How can I prevent the backspace key from navigating back?

On IE I can do this with the (terribly non-standard, but working) jQuery

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

But is it possible to do in a way which works on Firefox, or in a cross-browser way for a bonus?

For the record:

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

does nothing.

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

solves the problem, but renders the backspace key unusable on the page, which is even worse than the original behaviour.

EDIT: The reason I do this is that I'm not creating a simple web page but a large application. It is incredibly annoying to lose 10 minutes of work just because you pressed backspace in the wrong place. The ratio of preventing mistakes vs. annoying users should be way above 1000/1 by preventing the backspace key from navigating back.

EDIT2: I'm not trying to prevent history navigation, just accidents.

EDIT3: @brentonstrines comment (moved here since the question is so popular): This is a long-term 'fix', but you could throw your support behind the Chromium bug to change this behavior in webkit


这段代码解决了这个问题,至少在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;
        }
    }
});

This code works on all browsers and swallows the backspace key when not on a form element, or if the form element is disabled|readOnly. It is also efficient, which is important when it is executing on every key typed in.

$(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();
            }
        }
    });
});

The other answers here have established that this cannot be done without whitelisting elements in which Backspace is allowed. This solution is not ideal because the whitelist is not as straightforward as merely textareas and text/password inputs, but is repeatedly found to be incomplete and needing to be updated.

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.

The problem is that an onbeforeunload modal must not pop up whenever the user navigates away from the page (such as when clicking a link or submitting a form), and we don't want to start whitelisting or blacklisting specific onbeforeunload conditions.

The ideal combination of tradeoffs for a generalized solution is as follows: keep track of whether backspace is pressed, and only pop up the onbeforeunload modal if it is. In other words:

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

This has been tested to work in IE7+, FireFox, Chrome, Safari, and Opera. Just drop this function into your global.js and call it from any page where you don't want users to accidentally lose their data.

链接地址: http://www.djcxy.com/p/41384.html

上一篇: HTML文本无法选择,但与旋转! 不可删除

下一篇: 我怎样才能防止退格键导航回来?