如何防止Backspace键回退?


275

在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。

EDIT2:我不是要阻止历史导航,只是出于意外。

EDIT3:@brentonstrines评论(由于此问题如此受欢迎,因此移至此处):这是一个长期的“解决方法”,但是您可以在Chromium错误的背后给予支持以更改Webkit中的此行为


137
因为退格键已过载。您可能没有注意到它,但是您可能一直在使用它来擦除刚在文本字段中键入的字母。我的一些客户在导致该页面返回时遇到麻烦,因此这是有用的信息。除了你的小丑,没人知道退格应该退回一页。这是我所不知道的,对于浏览器来说,这是完全敌对的行为。我认为所有页面都应禁用该行为。
布列塔尼

80
人们为什么认为这很奇怪?使用退格键进行导航是一个非常愚蠢的快捷方式!用户可能希望从中删除文本的文本字段太多-想象有一个很长的SO答案,切换到另一个窗口来检查某些内容,然后返回并错误地单击编辑区域,按Backspace删除单词,然后突然,浏览器返回一个页面,您可能已经丢失了刚编写的所有内容。
彼得·布顿

57
为什么我要这样做?我不是在创建网站,而是在创建Web应用程序。有些输入字段是只读的,在这种情况下它们看起来是可编辑的,但是如果按退格键,您将离开页面。打算向后导航的退格印刷机与试图擦除某些东西的退格印刷机的比率可能远远小于1
/1000。– erikkallen

42
问题是如何做到这一点,而不是您是否认为这是一个好主意。在不了解项目细节的情况下,您的意见毫无意义。我的客户对我的一个项目特别要求这种行为,并且是真正的答案,而不是“为什么要这么做?” 会有所帮助。

7
这是一个长期的“解决方案”,但是您可以在Chromium错误的背后给予支持以更改Webkit中的此行为:code.google.com/p/chromium/issues/detail?
id=144832

Answers:


335

这段代码至少在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;
        }
    }
});

6
破坏密码字段。
Hemlock

7
正如Hemlock所说- d.type.toUpperCase() === 'PASSWORD'还要检查。否则看起来不错
stevendesu 2012年

17
由于您已经在使用jQueryif( $(d).is( ":input" ) )...
Paul Alexander

23
很遗憾,这必须是白名单,而不是能够将“后退”功能列入黑名单。您可能要d.isContentEditable在此处添加支票。
iono 2013年

3
我用当前接受的答案的干净版本创建了一个NPM项目:github.com/slorber/backspace-disabler(它也支持contenteditables,并且没有依赖项)
Sebastien Lorber

62

该代码在所有浏览器上均有效,并且在不在表单元素上或在禁用了formread | readOnly的情况下吞下了退格键。它也是有效的,当它在键入的每个键上执行时很重要。

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

1
请测试我的示例,您可能希望相应地更新代码。
Biff MaGriff

10
我更喜欢@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 )
Matthew Clark

@thetoolman,请参阅我对erikallen答案的评论。这也应说明contentEditable
2014年

10
@MaffooClock:您可以更加简洁.is(':checkbox,:radio,:submit')
cdmckay

1
@cdmckay:我简直不敢相信我没有那样写。感谢您为我们所有人清理这些问题:)
Matthew Clark

41

此处的其他答案已确定,如果没有将允许使用Backspace的元素列入白名单,则无法完成此操作。该解决方案不是理想的,因为白名单不像仅文本区域和文本/密码输入那样简单,而是反复发现其不完整并且需要更新。

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

问题在于,每当用户离开页面时(例如,单击链接或提交表单时),都不会弹出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事件上触发,但是在这种情况下,您可以使用其他技术来防止用户意外丢失其数据。


2
我只是添加了相同的解决方案,并在LOL页面的底部看到了这篇文章。我的区别之一是在返回“ Are you sure ...”语句之前设置lastUserInputWasBackspace = false,因此,如果您在已经看到弹出窗口之后碰巧单击了back按钮,则不会得到该弹出窗口(因此与非弹出窗口一致受退格键影响的行为)。
David Russell

1
@ user2407309我已删除有关Firefox无法与您的解决方案配合使用的评论(不是投诉)。我的调试器出现问题。很抱歉编辑/破坏您的代码。现在我意识到我超越了我的界限(编辑),原谅了我。真的很抱歉,对于您为该问题提供的出色解决方案,我没有丝毫抱怨。再次致歉。此代码运行良好。我相信这是最好的答案,对此我表示赞赏。
查尔斯·伯恩

1
该解决方案可以在我的本地计算机上运行,​​但是当我将其移到本地时,客户端(至少其中一些)失去了一半应用程序的功能。我想有些东西会拒绝它,但我不知道该怎么办。
史蒂夫(Steve)

1
@Steve,很少见,如果功能有问题,该信息属于此处。我只想知道是否真的有问题。
弗拉基米尔·科纳

1
不错的解决方案,但是不幸的是,如果用户不小心按了两次退格键,它仍然会向后导航。(至少在firefox上使用)
Remco de Zwart

26

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

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

1
这要简洁得多,据我所知也行得通。为什么最流行的答案是对所有输入类型进行检查,而且看起来更复杂?它更可靠吗?
2014年

1
最受欢迎的答案是第一个回答该问题的人,因此得票率很高。
Darwayne 2014年

4
当以只读字段为焦点时,删除仍然

16

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

示例
要测试制作2个文件。

starthere.htm-首先打开它,以便您可以回到

<a href="./test.htm">Navigate to here to test</a>

test.htm-当复选框或提交具有焦点(通过制表符实现)时,按退格键将向后导航。用我的代码替换即可修复。

<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>

您看到哪种浏览器在收音机|复选框|提交->后退功能上按了退格键?我还没有看到浏览器能做到这一点..
thetoolman

Internet Explorer 8和Chrome
Biff MaGriff

2
我在该线程中尝试了许多其他解决方案,但是该解决方案在我所有的情况下都运行良好,并且具有最干净,最容易理解的代码。谢谢。
伊兹沃德

您是否尝试过@Darwayne,我很想知道为什么这么短又更复杂,但是两者似乎对我来说都一样工作
Nearpoint 2014年

这对链接有效吗?我有一个带有图像按钮的ASP.Net应用程序,用于删除项目。到目前为止,这是唯一尚未完成的事情……
Steve

8

根据注释,如果他们按退格键删除但该字段未集中显示,您似乎想阻止人们丢失表单中的信息。

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


4
抱歉,这是不礼貌的评论。我的意思是,用户可能不希望因做自己不知道的事情做错而被指责。为什么不通过onkeydown静静地吃掉钥匙呢?目的不是要完全防止用户离开页面,而是要防止这种常见错误。另外,弹出对话框不是非常有效或有用。用户不阅读它们。您确定要离开页面吗?好的!不用等待,我不想离开页面..糟糕。
布列塔尼

3
OK,然后接受或离开它。我认为您正在尝试过度设计实际上不存在的问题,或者至少不重要。以我的经验,只有高级用户在不熟悉的对话框上单击“确定”,而没有正确阅读它们。;)
DisgruntledGoat09年

3
您和布列塔尼是同一个人吗?无论如何,您都将自己踢了一下-文章说“默认答案是取消”,因此当看到有关离开页面的对话框时,他们将按“取消”,因此不会离开页面。尽管应注意,Chrome在该对话框上的选项非常清楚,为“离开此页面”和“停留在此页面”。
DisgruntledGoat

1
不,他不是我,但我之前曾遇到过这种联系。我认为这些评论很有趣。“什么!?人们忽略模态对话框?我们必须找到一种使它们更加持久和令人讨厌的方法!”。确实解释了很多有关Microsoft软件的内容。
布列塔尼

3
@不满意:不,我不是Breton,文章的重点不是“默认选择是...”,而是“用户什么都不读”。
erikkallen's

7

停止浏览此代码即可!

$(document).on("keydown", function (event) {        
   if (event.keyCode === 8) {
      event.preventDefault();
    }
  });

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

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

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

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

在下面提到这一点!

防止BACKSPACE使用jQuery导航(类似于Google的主页)


7

大多数答案都在jquery中。您可以用纯Javascript完美地做到这一点,简单而无需库。文章是出发点对我来说是很好的,但由于keyIdentifier已过时,我希望这个代码是更安全的,所以我说|| e.keyCode == 8 if语句。另外,该代码在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>

该代码非常有效,因为,

  1. 它使用纯javascript(无需库)。
  2. 它不仅检查按下的键,还确认该操作是否确实是浏览器的“后退”操作。
  3. 结合以上内容,用户可以在网页上的输入文本框中键入和删除文本,而不会出现任何问题,同时仍可以防止后退按钮动作。
  4. 它短,干净,快速,直截了当。

您可以添加console.log(e); 为了您的测试目的,在Chrome中按F12键,转到“控制台”选项卡,并在页面上单击“退格键”,然后在其中查看以查看返回的值,然后可以将所有这些参数作为目标以进一步增强代码以上满足您的需求。


6

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

添加IMAGE可能也很有用。
mrswadge 2014年

我选择了这个。
科伦丁

5

不知道为什么没人会回答这个问题-似乎是一个完全合理的技术问题,询问是否可能。

不,我认为没有跨浏览器的方式可以禁用Backspace按钮。我知道这些天默认情况下未在FF中启用它。


3
负1表示未回答实际问题和浪费时间
Andrew

3

此解决方案与已发布的其他解决方案相似,但是它使用了简单的白名单,使其易于自定义以仅通过在.is()函数中设置选择器就可以在指定元素中允许退格。

我以这种形式使用它来防止页面上的退格键向后导航:

$(document).on("keydown", function (e) {
    if (e.which === 8 && !$(e.target).is("input:not([readonly]), textarea")) {
        e.preventDefault();
    }
});

2
当用户使用contenteditable时,将使其禁用。因此,您可能想在白名单中添加contenteditable = true
Miguel

3

为了稍微详细说明@erikkallen的出色答案,以下函数允许所有基于键盘的输入类型,包括HTML5中引入的类型:

$(document).unbind('keydown').bind('keydown', function (event) {
    var doPrevent = false;
    var INPUTTYPES = [
        "text", "password", "file", "date", "datetime", "datetime-local",
        "month", "week", "time", "email", "number", "range", "search", "tel",
        "url"];
    var TEXTRE = new RegExp("^" + INPUTTYPES.join("|") + "$", "i");
    if (event.keyCode === 8) {
        var d = event.srcElement || event.target;
        if ((d.tagName.toUpperCase() === 'INPUT' && d.type.match(TEXTRE)) ||
             d.tagName.toUpperCase() === 'TEXTAREA') {
            doPrevent = d.readOnly || d.disabled;
        } else {
            doPrevent = true;
        }
    }
    if (doPrevent) {
        event.preventDefault();
    }
});

谢谢,我正在用这个答案!到目前为止,您是否发现此解决方案有任何问题?
2014年

1
我建议将INPUTTYPES,TEXTRE声明移出函数,以免在每次按键事件时都重新计算它们。
thetoolman

3

JavaScript-jQuery方式:

$(document).on("keydown", function (e) {
    if (e.which === 8 && !$(e.target).is("input, textarea")) {
        e.preventDefault();
    }
});

Javascript-本机方式,对我有用:

<script type="text/javascript">

//on backspace down + optional callback
function onBackspace(e, callback){
    var key;
    if(typeof e.keyIdentifier !== "undefined"){
        key = e.keyIdentifier;

    }else if(typeof e.keyCode !== "undefined"){
        key = e.keyCode;
    }
    if (key === 'U+0008' || 
        key === 'Backspace' || 
        key === 8) {
                    if(typeof callback === "function"){
                callback();
            }
            return true;
        }
    return false;
}

//event listener
window.addEventListener('keydown', function (e) {

    switch(e.target.tagName.toLowerCase()){
        case "input":
        case "textarea":
        break;
        case "body":
            onBackspace(e,function(){
                e.preventDefault();
            });

        break;
    }
}, true);
</script>

@MichaelPotter很久以前,我的用例还可以。请随时通过改进/更改我的答案做出贡献。谢谢!
Vladimir Djuricic

3

我很难找到一个非JQUERY的答案。感谢Stas让我走上正轨。

Chrome: 如果您不需要跨浏览器支持,则可以仅使用黑名单,而无需将其列入白名单。此纯JS版本适用于Chrome,但不适用于IE。不确定FF。

在Chrome浏览器(2014年中期,版本36)中,似乎没有针对输入或可编辑内容的按键<BODY>。这样就可以使用黑名单,我更喜欢将其列入白名单。IE使用最终点击目标-因此它可能是div或其他任何东西。这使得它在IE中毫无用处。

window.onkeydown = function(event) {
    if (event.keyCode == 8) {
    //alert(event.target.tagName); //if you want to see how chrome handles keypresses not on an editable element
        if (event.target.tagName == 'BODY') {
            //alert("Prevented Navigation");
            event.preventDefault();
        }
    }
}  

跨浏览器: 对于纯JavaScript,我发现Stas的答案是最好的。再添加一个针对contenteditable的条件检查,使其对我有效*:

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 (d.contentEditable != 'true') { //it's not REALLY true, checking the boolean value (!== true) always passes, so we can use != 'true' rather than !== true/
            if (regex.test(elements)) {
                event.preventDefault ? event.preventDefault() : event.returnValue = false;
            }
        }
    }
}

*请注意,IE [edit:和Spartan / TechPreview]具有使表相关元素不可编辑的“功能” 。如果您单击其中之一,然后按Backspace键,它将向后导航。如果您没有可编辑<td>的,这不是问题。


2

我在接受的解决方案和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。我添加了代码来说明跨度tagName和其他属性。这解决了我所有的问题。

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


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

2
您不应该使用return false。建议使用e.preventDefault。另外,您将停止传播每个键的事件,而不仅仅是停止键。最后,输入keyCode 13,问题是关于防止使用Backspace进行向后导航,但这将阻止enter提交表单或执行其他操作。

1

这段代码解决了所有浏览器中的问题:

onKeydown:function(e)
{
    if (e.keyCode == 8) 
    {
      var d = e.srcElement || e.target;
      if (!((d.tagName.toUpperCase() == 'BODY') || (d.tagName.toUpperCase() == 'HTML'))) 
      {
         doPrevent = false;
      }
       else
      {
         doPrevent = true;
      }
    }
    else
    {
       doPrevent = false;
    }
      if (doPrevent)
      {
         e.preventDefault();
       }

  }

1
我发现由于d.tagname为DIV或,此代码无法正常工作TD
Biff MaGriff

来自Haseeb Akhtar的代码可在Chrome和Firefox中完美运行,但令人惊讶!!不在IE6-9中有什么建议吗?
马丁·安德森

1

防止在按下退格键时导航的最简单方法

$(document).keydown(function () {
    if (event.keyCode == 8) {
        if (event.target.nodeName == 'BODY') {
            event.preventDefault();
        }
    }
});

防止在按下后空格时导航,同时允许在所有输入控件中使用后退键
Mohammed Irfan Mayan

并且不要错过第一行。.$(document).keydown(function(){
Mohammed Irfan Mayan

3
这将禁用文本区域和输入内部的
后退按钮

1

使用Dojo工具包1.7,这可以在IE 8中使用:

require(["dojo/on", "dojo/keys", "dojo/domReady!"],
function(on, keys) {
    on(document.body,"keydown",function(evt){if(evt.keyCode == keys.BACKSPACE)evt.preventDefault()});
});

1

您是否尝试了仅将以下属性添加到只读文本字段的非常简单的解决方案:

onkeydown =“ return false;”

当在只读文本字段中按Backspace键时,这将使浏览器不再返回历史记录。也许我想念您的真实意图,但看来这将是解决您问题的最简单方法。


1

更整洁的解决方案-

$(document).on('keydown', function (e) {
    var key = e == null ? event.keyCode : e.keyCode;
    if(key == 8 && $(document.activeElement.is(':not(:input)')))   //select, textarea
      e.preventDefault();
});

或者,您只能检查是否

$(document.activeElement).is('body')

1

纯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))”。第一个对我来说很好。


1

性能?

我担心性能,并摆弄了一个小提琴:http : //jsfiddle.net/felvhage/k2rT6/9/embedded/result/

var stresstest = function(e, method, index){...

我已经分析了在该线程中找到的最有前途的方法。事实证明,它们都非常快,并且很可能不会在键入时引起“迟钝”问题。我查看的最慢的方法是在IE8中进行10.000次调用时大约需要125毫秒。每次行程0.0125ms。

我发现Codenepal和Robin Maben发布的方法最快〜0.001ms(IE8),但是要注意不同的语义。

对于将这种功能引入其代码的人来说,这也许是一种解脱。


1

修改后的erikkallen答案:

$(document).unbind('keydown').bind('keydown', function (event) {

    var doPrevent = false, elem;

    if (event.keyCode === 8) {
        elem = event.srcElement || event.target;
        if( $(elem).is(':input') ) {
            doPrevent = elem.readOnly || elem.disabled;
        } else {
            doPrevent = true;
        }
    }

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

1
完美的答案。我从其他人那里获得的解决方案在Firefox中不起作用,但是这个解决方案可以完美地在所有三个(Firefox,IE和crome)中正常工作。感谢Prozi。
Nikhil Dinesh 2014年

1

经过测试,该解决方案效果很好。

我确实添加了一些代码来处理一些未用输入标记的输入字段,并集成到为我的工作生成输入表单的Oracle PL / SQL应用程序中。

我的“两分钱”:

 if (typeof window.event != ''undefined'')
    document.onkeydown = function() {
    //////////// IE //////////////
    var src = event.srcElement;
    var tag = src.tagName.toUpperCase();
    if (event.srcElement.tagName.toUpperCase() != "INPUT"
        && event.srcElement.tagName.toUpperCase() != "TEXTAREA"
        || src.readOnly || src.disabled 
        )
        return (event.keyCode != 8);
    if(src.type) {
       var type = ("" + src.type).toUpperCase();
       return type != "CHECKBOX" && type != "RADIO" && type != "BUTTON";
       }
   }
else
   document.onkeypress = function(e) {
   //////////// FireFox 
   var src = e.target;
   var tag = src.tagName.toUpperCase();
   if ( src.nodeName.toUpperCase() != "INPUT" && tag != "TEXTAREA"
      || src.readOnly || src.disabled )
      return (e.keyCode != 8);
    if(src.type) {
      var type = ("" + src.type).toUpperCase();
      return type != "CHECKBOX" && type != "RADIO" && type != "BUTTON";
      }                              
   }

1

我创建了一个NPM项目,其中包含当前接受的(erikkallen)的干净版本

https://github.com/slorber/backspace-disabler

它使用基本相同的原理,但:

  • 无依赖性
  • 支持内容可编辑
  • 更具可读性/可维护性的代码库
  • 将得到支持,因为它将用于我公司的生产中
  • 麻省理工学院执照

var Backspace = 8;

// See http://stackoverflow.com/questions/12949590/how-to-detach-event-in-ie-6-7-8-9-using-javascript
function addHandler(element, type, handler) {
    if (element.addEventListener) {
        element.addEventListener(type, handler, false);
    } else if (element.attachEvent) {
        element.attachEvent("on" + type, handler);
    } else {
        element["on" + type] = handler;
    }
}
function removeHandler(element, type, handler) {
    if (element.removeEventListener) {
        element.removeEventListener(type, handler, false);
    } else if (element.detachEvent) {
        element.detachEvent("on" + type, handler);
    } else {
        element["on" + type] = null;
    }
}




// Test wether or not the given node is an active contenteditable,
// or is inside an active contenteditable
function isInActiveContentEditable(node) {
    while (node) {
        if ( node.getAttribute && node.getAttribute("contenteditable") === "true" ) {
            return true;
        }
        node = node.parentNode;
    }
    return false;
}



var ValidInputTypes = ['TEXT','PASSWORD','FILE','EMAIL','SEARCH','DATE'];

function isActiveFormItem(node) {
    var tagName = node.tagName.toUpperCase();
    var isInput = ( tagName === "INPUT" && ValidInputTypes.indexOf(node.type.toUpperCase()) >= 0 );
    var isTextarea = ( tagName === "TEXTAREA" );
    if ( isInput || isTextarea ) {
        var isDisabled = node.readOnly || node.disabled;
        return !isDisabled;
    }
    else if ( isInActiveContentEditable(node) ) {
        return true;
    }
    else {
        return false;
    }
}


// See http://stackoverflow.com/questions/1495219/how-can-i-prevent-the-backspace-key-from-navigating-back
function disabler(event) {
    if (event.keyCode === Backspace) {
        var node = event.srcElement || event.target;
        // We don't want to disable the ability to delete content in form inputs and contenteditables
        if ( isActiveFormItem(node) ) {
            // Do nothing
        }
        // But in any other cases we prevent the default behavior that triggers a browser backward navigation
        else {
            event.preventDefault();
        }
    }
}


/**
 * By default the browser issues a back nav when the focus is not on a form input / textarea
 * But users often press back without focus, and they loose all their form data :(
 *
 * Use this if you want the backspace to never trigger a browser back
 */
exports.disable = function(el) {
    addHandler(el || document,"keydown",disabler);
};

/**
 * Reenable the browser backs
 */
exports.enable = function(el) {
    removeHandler(el || document,"keydown",disabler);
};

1

这是我对票数最高的答案的重写。我尝试检查element.value!== undefined(因为某些元素可能没有html属性,但可能在原型链上的某处具有javascript value属性),但是效果不佳,并且存在很多边缘情况。似乎并没有一种很好的方法来证明这一点,因此白名单似乎是最好的选择。

这将在事件冒泡阶段结束时注册该元素,因此,如果要以任何自定义方式处理Backspace,则可以在其他处理程序中进行处理。

这也检查HTMLTextAreElement的instance,因为理论上可以有一个继承自该元素的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

0

Sitepoint:停用Java脚本

event.stopPropagation()event.preventDefault()什么也不做的IE浏览器。但是,我不得不发送退货event.keyCode == 11(我刚刚选择了一些东西),而不是只是说"if not = 8, run the event"要使它工作。 event.returnValue = false也可以。


0

使用jQuery的另一种方法

    <script type="text/javascript">

    //set this variable according to the need within the page
    var BACKSPACE_NAV_DISABLED = true;

    function fnPreventBackspace(event){if (BACKSPACE_NAV_DISABLED && event.keyCode == 8) {return false;}}
    function fnPreventBackspacePropagation(event){if(BACKSPACE_NAV_DISABLED && event.keyCode == 8){event.stopPropagation();}return true;}

    $(document).ready(function(){ 
        if(BACKSPACE_NAV_DISABLED){
            //for IE use keydown, for Mozilla keypress  
            //as described in scr: http://www.codeproject.com/KB/scripting/PreventDropdownBackSpace.aspx
            $(document).keypress(fnPreventBackspace);
            $(document).keydown(fnPreventBackspace);

            //Allow Backspace is the following controls 
            var jCtrl = null;
            jCtrl = $('input[type="text"]');
            jCtrl.keypress(fnPreventBackspacePropagation);
            jCtrl.keydown(fnPreventBackspacePropagation);

            jCtrl = $('input[type="password"]');
            jCtrl.keypress(fnPreventBackspacePropagation);
            jCtrl.keydown(fnPreventBackspacePropagation);

            jCtrl = $('textarea');
            jCtrl.keypress(fnPreventBackspacePropagation);
            jCtrl.keydown(fnPreventBackspacePropagation);

            //disable backspace for readonly and disabled
            jCtrl = $('input[type="text"][readonly="readonly"]')
            jCtrl.keypress(fnPreventBackspace);
            jCtrl.keydown(fnPreventBackspace);

            jCtrl = $('input[type="text"][disabled="disabled"]')
            jCtrl.keypress(fnPreventBackspace);
            jCtrl.keydown(fnPreventBackspace);
        }
    }); 

    </script>

请注意,如果已动态添加控件(文本框),则此方法不起作用。
CodeNepal

0

我已经在代码中使用了一段时间了。我为学生编写在线测试,当学生在测试过程中按退格键时遇到了问题,它将带他们回到登录屏幕。令人沮丧!它可以在FF上正常工作。

document.onkeypress = Backspace;
function Backspace(event) {
    if (event.keyCode == 8) {
        if (document.activeElement.tagName == "INPUT") {
            return true;
        } else {
            return false;
        }
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.