在IE上,我可以用jQuery(非常不标准,但工作)做到这一点

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

但是是否有可能在Firefox上运行,或者在跨浏览器上获得额外的好处呢?

郑重声明:

$(document).keydown(function(e) { if (e.keyCode == 8) e.stopPropagation(); });

什么也不做。

$(document).keydown(function(e) { if (e.keyCode == 8) e.preventDefault(); });

解决了问题,但使退格键在页面上无法使用,这比原来的行为更糟糕。

编辑: 我这样做的原因是我不是在创建一个简单的网页,而是一个大型的应用程序。仅仅因为你在错误的地方按了退格键而失去了10分钟的工作,这是非常令人恼火的。通过防止退格键返回,防止错误和讨厌用户的比例应该远远超过1000/1。

编辑2:我不是想阻止历史航行,只是想阻止事故。

EDIT3: @brentonstrines评论(因为这个问题太受欢迎了,所以移到这里):这是一个长期的“修复”,但你可以支持Chromium bug来改变webkit中的这种行为


当前回答

    document.onkeydown = function (e) {    
        e.stopPropagation();
        if ((e.keyCode==8  ||  e.keyCode==13) &&
            (e.target.tagName != "TEXTAREA") && 
            (e.target.tagName != "INPUT")) { 
            return false;
        }
    };

其他回答

这里的其他答案已经确定,如果没有允许退格的白名单元素,就不能做到这一点。这种解决方案并不理想,因为白名单不像仅仅是文本区域和文本/密码输入那样简单,而且经常被发现是不完整的,需要更新。

However, since the purpose of suppressing the backspace functionality is merely to prevent users from accidentally losing data, the beforeunload solution is a good one because the modal popup is surprising--modal popups are bad when they are triggered as part of a standard workflow, because the user gets used to dismissing them without reading them, and they are annoying. In this case, the modal popup would only appear as an alternative to a rare and surprising action, and is therefore acceptable.

问题是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

这已经在IE7+, FireFox, Chrome, Safari和Opera中进行了测试。只需将这个函数放到global.js中,并从任何您不希望用户意外丢失数据的页面调用它。

注意onbeforeunload模式只能被触发一次,所以如果用户再次按下退格键,该模式将不会再次触发。

注意,这不会触发hashchange事件,但是在这种情况下,您可以使用其他技术来防止用户意外丢失数据。

我有一些问题与接受的解决方案和Select2.js插件;我无法删除可编辑框中的字符,因为删除操作被阻止了。这就是我的解决方案:

//Prevent backwards navigation when trying to delete disabled text.
$(document).unbind('keydown').bind('keydown', function (event) {

    if (event.keyCode === 8) {

        var doPrevent = false,
            d = event.srcElement || event.target,
            tagName = d.tagName.toUpperCase(),
            type = (d.type ? d.type.toUpperCase() : ""),
            isEditable = d.contentEditable,
            isReadOnly = d.readOnly,
            isDisabled = d.disabled;

        if (( tagName === 'INPUT' && (type === 'TEXT' || type === 'PASSWORD'))
            || tagName === 'PASSWORD'
            || tagName === 'TEXTAREA') {
            doPrevent =  isReadOnly || isDisabled;
        }
        else if(tagName === 'SPAN'){
            doPrevent = !isEditable;
        }
        else {
            doPrevent = true;
        }
    }

    if (doPrevent) {
        event.preventDefault();
    }
});

Select2创建了一个Span,其属性为“contentEditable”,对于其中的可编辑组合框,该属性被设置为true。我添加了一些代码来说明span tagName和不同的属性。这解决了我所有的问题。

编辑:如果你没有使用jquery的Select2组合框插件,那么这个解决方案可能不需要你,接受的解决方案可能更好。

以下是我对得票最多的答案的改写。我试着检查element.value!==undefined(因为有些元素可能没有HTML属性,但可能在原型链的某个地方有javascript值属性),然而这并不是很好,并且有很多边缘情况。似乎没有一个很好的方法来证明这一点,所以白名单似乎是最好的选择。

这将在事件气泡阶段的末尾注册元素,因此如果您想以任何自定义方式处理Backspace,您可以在其他处理程序中这样做。

这也检查instanceof HTMLTextAreElement,因为理论上可以有一个继承自它的web组件。

这不会检查contentEditable(与其他答案结合)。

https://jsfiddle.net/af2cfjc5/15/

var _INPUTTYPE_WHITELIST = ['text', 'password', 'search', 'email', 'number', 'date'];

function backspaceWouldBeOkay(elem) {
    // returns true if backspace is captured by the element
    var isFrozen = elem.readOnly || elem.disabled;
    if (isFrozen) // a frozen field has no default which would shadow the shitty one
        return false;
    else {
        var tagName = elem.tagName.toLowerCase();
        if (elem instanceof HTMLTextAreaElement) // allow textareas
            return true;
        if (tagName=='input') { // allow only whitelisted input types
            var inputType = elem.type.toLowerCase();
            if (_INPUTTYPE_WHITELIST.includes(inputType))
                return true;
        }   
        return false; // everything else is bad
    }
}

document.body.addEventListener('keydown', ev => {
    if (ev.keyCode==8 && !backspaceWouldBeOkay(ev.target)) {
        //console.log('preventing backspace navigation');
        ev.preventDefault();
    }
}, true); // end of event bubble phase

结合“toolman”&&“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();
    });
}); 

纯javascript版本,适用于所有浏览器:

document.onkeydown = function(e) {stopDefaultBackspaceBehaviour(e);}
document.onkeypress = function(e) {stopDefaultBackspaceBehaviour(e);}

function stopDefaultBackspaceBehaviour(event) {
  var event = event || window.event;
  if (event.keyCode == 8) {
    var elements = "HTML, BODY, TABLE, TBODY, TR, TD, DIV";
    var d = event.srcElement || event.target;
    var regex = new RegExp(d.tagName.toUpperCase());
    if (regex.test(elements)) {
      event.preventDefault ? event.preventDefault() : event.returnValue = false;
    }
  }
}

当然,你可以使用“INPUT, TEXTAREA”和使用“if (!regex.test(elements))”然后。第一个对我来说很好。