如何防止退格键导航回来?

eri*_*len 268 javascript firefox jquery internet-explorer cross-browser

在IE上,我可以使用(非常非标准但可以正常工作)jQuery来实现这一点

if ($.browser.msie)
    $(document).keydown(function(e) { if (e.keyCode == 8) window.event.keyCode = 0;});
Run Code Online (Sandbox Code Playgroud)

但有可能以一种适用于Firefox的方式,或以跨浏览器的方式获得奖金吗?

作为记录:

$(document).keydown(function(e) { if (e.keyCode == 8) e.stopPropagation(); });
Run Code Online (Sandbox Code Playgroud)

什么也没做.

$(document).keydown(function(e) { if (e.keyCode == 8) e.preventDefault(); });
Run Code Online (Sandbox Code Playgroud)

解决了问题,但是在页面上呈现退格键不可用,这比原始行为更糟糕.

编辑:我这样做的原因是我不是创建一个简单的网页,而是一个大型的应用程序.因为你在错误的地方按下退格键而失去10分钟的工作是令人难以置信的烦恼.通过防止退格键导航回来,防止错误与烦人用户的比例应该高于1000/1.

编辑2:我不是想阻止历史导航,只是意外事故.

EDIT3:@brentonstrines评论(因为这个问题非常受欢迎而搬到这里):这是一个长期的'修复',但你可以抛弃你的支持Chromium bug来改变webkit中的这种行为

eri*_*len 329

这个代码解决了这个问题,至少在IE和Firefox中(没有测试任何其他的,但如果问题甚至存在于其他浏览器中,我给它一个合理的工作机会).

// Prevent the backspace key from navigating back.
$(document).unbind('keydown').bind('keydown', function (event) {
    if (event.keyCode === 8) {
        var doPrevent = true;
        var types = ["text", "password", "file", "search", "email", "number", "date", "color", "datetime", "datetime-local", "month", "range", "search", "tel", "time", "url", "week"];
        var d = $(event.srcElement || event.target);
        var disabled = d.prop("readonly") || d.prop("disabled");
        if (!disabled) {
            if (d[0].isContentEditable) {
                doPrevent = false;
            } else if (d.is("input")) {
                var type = d.attr("type");
                if (type) {
                    type = type.toLowerCase();
                }
                if (types.indexOf(type) > -1) {
                    doPrevent = false;
                }
            } else if (d.is("textarea")) {
                doPrevent = false;
            }
        }
        if (doPrevent) {
            event.preventDefault();
            return false;
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

  • 它很糟糕,这必须是白名单,而不是能够将"后退"功能列入黑名单.您可能需要在此处添加对"d.isContentEditable"的检查. (23认同)
  • 因为你已经在使用jQuery`if($(d).is(":input"))...` (17认同)
  • 正如Hemlock所说 - 检查`d.type.toUpperCase()==='PASSWORD'.否则看起来不错 (7认同)
  • 中断密码字段. (6认同)
  • 我创建了一个NPM项目,其中包含当前接受的答案的简洁版本:https://github.com/slorber/backspace-disabler(它也支持contenteditables并且没有依赖性) (3认同)

the*_*man 61

此代码适用于所有浏览器,并且当不在表单元素上时,或者如果表单元素被禁用,则会吞下退格键.它也很有效,当它在每个键入的键上执行时很重要.

$(function(){
    /*
     * this swallows backspace keys on any non-input element.
     * stops backspace -> back
     */
    var rx = /INPUT|SELECT|TEXTAREA/i;

    $(document).bind("keydown keypress", function(e){
        if( e.which == 8 ){ // 8 == backspace
            if(!rx.test(e.target.tagName) || e.target.disabled || e.target.readOnly ){
                e.preventDefault();
            }
        }
    });
});
Run Code Online (Sandbox Code Playgroud)

  • 我更喜欢@ erikkallen的解决方案,因为它更清洁.但是,我想要忽略提交按钮,单选按钮和复选框,所以我将if()更改为:if(!rx.test(e.target.tagName)|| $(e.target) .is(':checkbox')|| $(e.target).is(':radio')|| $(e.target).is(':submit')|| e.target.disabled || e .target.readOnly)` (10认同)
  • @MaffooClock:你可以更简洁地使用`.is(':checkbox,:radio,:submit')` (10认同)

Vla*_*nea 41

这里的其他答案已经确定,如果没有允许Backspace的白名单元素,就无法做到这一点.此解决方案并不理想,因为白名单不仅仅是textareas和文本/密码输入,而是反复发现不完整且需要更新.

但是,由于抑制退格功能的目的仅仅是为了防止用户意外丢失数据,因此前载加载解决方案是一个很好的解决方案,因为模式弹出窗口令人惊讶 - 当模式弹出窗口作为标准工作流程的一部分被触发时,它们很糟糕,因为用户习惯于在不阅读它们的情况下解雇它们,而且它们很烦人.在这种情况下,模态弹出窗口只会作为罕见且令人惊讶的动作的替代,因此是可以接受的.

问题是每当用户离开页面时(例如单击链接或提交表单时)都不会弹出onbeforeunload模式,并且我们不想开始将特定的onbeforeunload条件列入白名单或列入黑名单.

广义解决方案的权衡的理想组合如下:跟踪是否按下退格键,并且只有弹出onbeforeunload模式(如果是).换一种说法:

function confirmBackspaceNavigations () {
    // http://stackoverflow.com/a/22949859/2407309
    var backspaceIsPressed = false
    $(document).keydown(function(event){
        if (event.which == 8) {
            backspaceIsPressed = true
        }
    })
    $(document).keyup(function(event){
        if (event.which == 8) {
            backspaceIsPressed = false
        }
    })
    $(window).on('beforeunload', function(){
        if (backspaceIsPressed) {
            backspaceIsPressed = false
            return "Are you sure you want to leave this page?"
        }
    })
} // confirmBackspaceNavigations
Run Code Online (Sandbox Code Playgroud)

这已经过测试,适用于IE7 +,FireFox,Chrome,Safari和Opera.只需将此函数放入global.js中,然后从不希望用户意外丢失数据的任何页面调用它.

请注意,这不会触发hashchange事件,但在该上下文中,您可以使用其他技术来防止用户意外丢失其数据.

  • 我刚刚添加了相同的解决方案,并在页面底部看到了这个帖子.我有一个区别是在返回"你确定..."语句之前设置lastUserInputWasBackspace = false,所以如果你在看到弹出窗口后碰巧点击后退按钮就不会得到弹出窗口(所以它与非一致受退格影响的行为). (2认同)
  • @user2407309 我已经删除了有关 Firefox 无法使用您的解决方案的评论(不是投诉)。我的调试器有问题。对于编辑/破坏您的代码,我深表歉意。我现在意识到我超越了我的界限(编辑)请原谅我。我真的很抱歉,我对你对这个问题的出色解决方案没有任何抱怨。再次抱歉。这段代码运行良好。我相信这是最好的答案,我为此赞扬你。 (2认同)
  • 不错的解决方案,但不幸的是,如果用户不小心按了两次退格键,它仍然会导航回去。(至少在 Firefox 上) (2认同)

Dar*_*yne 24

更优雅/简洁的解决方案:

$(document).on('keydown',function(e){
  var $target = $(e.target||e.srcElement);
  if(e.keyCode == 8 && !$target.is('input,[contenteditable="true"],textarea'))
  {
    e.preventDefault();
  }
})
Run Code Online (Sandbox Code Playgroud)

  • 当readonly字段被聚焦时,delete仍然会以chrome格式导航回来 (4认同)

Bif*_*iff 15

修改erikkallen的答案以解决不同的输入类型

我发现一个有进取心的用户可能会在复选框或单选按钮上按退格键,徒劳地尝试清除它,而是会向后导航并丢失所有数据.

此更改应解决该问题.

新编辑以处理内容可编辑的div

    //Prevents backspace except in the case of textareas and text inputs to prevent user navigation.
    $(document).keydown(function (e) {
        var preventKeyPress;
        if (e.keyCode == 8) {
            var d = e.srcElement || e.target;
            switch (d.tagName.toUpperCase()) {
                case 'TEXTAREA':
                    preventKeyPress = d.readOnly || d.disabled;
                    break;
                case 'INPUT':
                    preventKeyPress = d.readOnly || d.disabled ||
                        (d.attributes["type"] && $.inArray(d.attributes["type"].value.toLowerCase(), ["radio", "checkbox", "submit", "button"]) >= 0);
                    break;
                case 'DIV':
                    preventKeyPress = d.readOnly || d.disabled || !(d.attributes["contentEditable"] && d.attributes["contentEditable"].value == "true");
                    break;
                default:
                    preventKeyPress = true;
                    break;
            }
        }
        else
            preventKeyPress = false;

        if (preventKeyPress)
            e.preventDefault();
    });
Run Code Online (Sandbox Code Playgroud)

示例
测试make 2文件.

starthere.htm - 首先打开它,这样你就有了回归的地方

<a href="./test.htm">Navigate to here to test</a>
Run Code Online (Sandbox Code Playgroud)

test.htm - 当复选框或提交具有焦点(通过Tab键实现)时,按下退格键时将向后导航.替换为我的代码来修复.

<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">

    $(document).keydown(function(e) {
        var doPrevent;
        if (e.keyCode == 8) {
            var d = e.srcElement || e.target;
            if (d.tagName.toUpperCase() == 'INPUT' || d.tagName.toUpperCase() == 'TEXTAREA') {
                doPrevent = d.readOnly || d.disabled;
            }
            else
                doPrevent = true;
        }
        else
            doPrevent = false;

        if (doPrevent)
            e.preventDefault();
    });
</script>
</head>
<body>
<input type="text" />
<input type="radio" />
<input type="checkbox" />
<input type="submit" />
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

  • 我在这个帖子中尝试了许多其他解决方案,但是这个解决方案在我的所有情况下运行良好,并且具有最干净,最容易理解的代码.谢谢. (2认同)

Dis*_*oat 8

根据评论显示,您希望阻止人们丢失表单中的信息,如果他们按退格键删除但该字段没有聚焦.

在这种情况下,您要查看onunload事件处理程序.Stack Overflow使用它 - 如果您在开始编写答案时尝试离开页面,它会弹出警告.

  • 抱歉,这是一个粗鲁的评论.我的意思是,用户可能不希望因为做一些他们甚至不知道错误的事情而受到谴责.为什么不只是默默地吃着onkeydown的钥匙?目标不是完全阻止用户离开页面,而是防止这种常见错误.此外,弹出对话不是非常有效或有用.用户不读它们.你确定要离开页面吗?好的!没有等待,我不想离开页面..哎太晚了. (4认同)
  • 好的,然后接受或离开它.我认为你试图过度设计一个不存在的问题,或者至少不重要的问题.根据我的经验,只有高级用户才能在不熟悉的对话框上单击"确定",而无需正确阅读.;) (3认同)
  • 你和布列塔尼是同一个人吗?无论如何你有点自己在那里射击 - 文章说"默认答案是取消"所以当看到关于离开页面的对话时,他们将按"取消",因此**不**离开页面.虽然应该注意Chrome浏览器在该对话框中的选项是"离开此页面"和"留在此页面上",这些选项非常清楚. (3认同)
  • @Disgruntled:不,我不是布列塔尼,文章的重点不是"默认选择是......"而是"用户不读任何东西". (3认同)

小智 7

停止导航此代码有效!

$(document).on("keydown", function (event) {        
   if (event.keyCode === 8) {
      event.preventDefault();
    }
  });
Run Code Online (Sandbox Code Playgroud)

但是为了不限制文本字段而是限制其他字段

$(document).on("keydown", function (event) {
  if (event.which === 8 && !$(event.target).is("input, textarea")) {
   event.preventDefault();
  }
});
Run Code Online (Sandbox Code Playgroud)

为了防止特定领域的使用,只需使用

$('#myOtherField').on("keydown", function (event) {
  if (event.keyCode === 8 || event.which === 8) { 
   event.preventDefault(); 
  } 
});
Run Code Online (Sandbox Code Playgroud)

参考下面这个!

阻止BACKSPACE使用jQuery导航(如Google的主页)


Tar*_*rik 7

大多数答案都在jquery中.您可以在纯Javascript中完美地完成此操作,简单且无需库.这篇文章对我来说是一个很好的起点,但由于不推荐使用keyIdentifier,我希望这段代码更安全,所以我在if语句中添加了|| e.keyCode == 8.此外,代码在Firefox上运行不正常,所以我添加了return false; 现在它的效果非常好.这里是:

<script type="text/javascript">
window.addEventListener('keydown',function(e){if(e.keyIdentifier=='U+0008'||e.keyIdentifier=='Backspace'||e.keyCode==8){if(e.target==document.body){e.preventDefault();return false;}}},true);
</script>
Run Code Online (Sandbox Code Playgroud)

这段代码效果很好,因为,

  1. 它是纯粹的javascript(不需要库).
  2. 它不仅检查按下的键,还确认该动作是否真的是一个浏览器"后退"动作.
  3. 与上述一起,用户可以在网页上的输入文本框中键入和删除文本而没有任何问题,同时仍然阻止后退按钮操作.
  4. 它简短,干净,快速,直接.

你可以添加console.log(e); 为了您的测试目的,并在Chrome中点击F12,转到"控制台"选项卡并点击页面上的"退格"并查看其中的内容以查看返回的值,然后您可以定位所有这些参数以进一步增强代码以上是为了满足您的需求.


bra*_*ter 5

不知道为什么没人会回答这个问题 - 这似乎是一个非常合理的技术问题,可以问这是否可行.

不,我认为没有跨浏览器方式来禁用退格按钮.我知道这些天默认情况下它没有默认启用.

  • 负1表示未回答实际问题并浪费时间 (3认同)

小智 5

结合"thetoolman"&&"Biff MaGriff"给出的解决方案

以下代码似乎在IE 8/Mozilla/Chrome中正常工作

$(function () {
    var rx = /INPUT|TEXTAREA/i;
    var rxT = /RADIO|CHECKBOX|SUBMIT/i;

    $(document).bind("keydown keypress", function (e) {
        var preventKeyPress;
        if (e.keyCode == 8) {
            var d = e.srcElement || e.target;
            if (rx.test(e.target.tagName)) {
                var preventPressBasedOnType = false;
                if (d.attributes["type"]) {
                    preventPressBasedOnType = rxT.test(d.attributes["type"].value);
                }
                preventKeyPress = d.readOnly || d.disabled || preventPressBasedOnType;
            } else {preventKeyPress = true;}
        } else { preventKeyPress = false; }

        if (preventKeyPress) e.preventDefault();
    });
}); 
Run Code Online (Sandbox Code Playgroud)