Javascript 如何防止backspace键向后导航?
在IE上,我可以使用(非常不标准,但工作正常)jQuery来实现这一点 但是,有没有可能在Firefox上运行,或者通过跨浏览器的方式获得额外的好处呢 记录在案:Javascript 如何防止backspace键向后导航?,javascript,jquery,internet-explorer,firefox,cross-browser,Javascript,Jquery,Internet Explorer,Firefox,Cross Browser,在IE上,我可以使用(非常不标准,但工作正常)jQuery来实现这一点 但是,有没有可能在Firefox上运行,或者通过跨浏览器的方式获得额外的好处呢 记录在案: $(document).keydown(function(e) { if (e.keyCode == 8) e.stopPropagation(); }); 什么也不做 $(document).keydown(function(e) { if (e.keyCode == 8) e.preventDefault(); }); 解决了
$(document).keydown(function(e) { if (e.keyCode == 8) e.stopPropagation(); });
什么也不做
$(document).keydown(function(e) { if (e.keyCode == 8) e.preventDefault(); });
解决了该问题,但使退格键在页面上不可用,这比原始行为更糟糕
编辑:
我这样做的原因是,我不是在创建一个简单的网页,而是在创建一个大型应用程序。仅仅因为你在错误的地方按了backspace,就失去了10分钟的工作,这真是令人讨厌。通过防止backspace键向后导航,防止错误与骚扰用户的比率应远高于1000/1
编辑2:我不是试图阻止历史导航,只是意外
EDIT3:@brentonstrines评论(由于这个问题很受欢迎,所以移到这里):这是一个长期的“修复”,但你可以把你的支持抛到后面不确定为什么没有人回答这个问题-这似乎是一个完全合理的技术问题,可以问它是否可能
不,我不认为有一个跨浏览器的方式来禁用退格按钮。不过,我知道这几天FF中默认情况下没有启用该功能。根据评论,如果用户按backspace删除表单中的信息,但该字段未聚焦,则您希望阻止他们在表单中丢失信息
在这种情况下,您需要查看onunload事件处理程序。堆栈溢出使用它-如果您在开始编写答案时试图离开页面,它会弹出一条警告。这段代码解决了问题,至少在IE和Firefox中是这样(没有测试过任何其他浏览器,但如果问题在其他浏览器中也存在,我给它一个合理的工作机会)
此代码解决了所有浏览器中的问题:
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();
}
}
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;
}
}
}
使用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>
//根据页面内的需要设置此变量
var BACKSPACE\u NAV\u DISABLED=真;
函数fnPreventBackspace(event){if(BACKSPACE_NAV_DISABLED&&event.keyCode==8){return false;}
函数fnPreventBackspacePropagation(事件){if(BACKSPACE_NAV_DISABLED&&event.keyCode==8){event.stopPropagation();}返回true;}
$(文档).ready(函数(){
如果(已禁用退格导航){
//IE使用keydown,Mozilla使用keypress
//如scr中所述:http://www.codeproject.com/KB/scripting/PreventDropdownBackSpace.aspx
$(文档).keypress(退格);
$(文档).keydown(退格);
//允许退格是由以下控件组成的
var jCtrl=null;
jCtrl=$('input[type=“text”]”);
jCtrl.keypress(fn);
jCtrl.keydown(fn);
jCtrl=$('input[type=“password”]”);
jCtrl.keypress(fn);
jCtrl.keydown(fn);
jCtrl=$('textarea');
jCtrl.keypress(fn);
jCtrl.keydown(fn);
//禁用readonly和disabled的退格
jCtrl=$('input[type=“text”][readonly=“readonly”]”)
jCtrl.keypress(退格);
jCtrl.keydown(退格);
jCtrl=$('input[type=“text”][disabled=“disabled”]”)
jCtrl.keypress(退格);
jCtrl.keydown(退格);
}
});
修改erikkallen的答案以解决不同的输入类型
//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();
});
我发现一个有进取心的用户可能会在复选框或单选按钮上按backspace,徒劳地试图清除复选框或单选按钮,相反,他们会向后导航并丢失所有数据
这一变化应该解决这一问题
新编辑以处理内容可编辑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-当复选框或提交具有焦点(通过制表符实现)时,当按下backspace时,此选项将向后导航。替换为我要修复的代码
<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>
$(文档).keydown(函数(e){
var-doPrevent;
如果(e.keyCode==8){
var d=e.src元素| | e.target;
如果(d.tagName.toUpperCase()='INPUT'| | d.tagName.toUpperCase()=='TEXTAREA'){
doPrevent=d.readOnly | | d.disabled;
}
其他的
doPrevent=true;
}
其他的
doPrevent=false;
if(doPrevent)
e、 预防默认值();
});
event.stopPropagation()
和event.preventDefault()
在IE中什么都不做。我不得不发送returnevent.keyCode==11
(我刚刚选了一些东西),而不是说“如果不是=8,运行事件”
,让它工作event.returnValue=false
也可以使用。此代码在所有浏览器上都可以使用,并且当不在表单元素上时,或者如果表单元素被禁用| 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();
}
}
});
});
结合“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();
});
});
按backspace时防止导航的最简单方法
$(document).keydown(function () {
if (event.keyCode == 8) {
if (event.target.nodeName == 'BODY') {
event.preventDefault();
}
}
});
此解决方案与已发布的其他解决方案类似,但它使用一个简单的白名单,使其易于自定义,只需在.is()函数中设置选择器,即可在指定元素中使用退格 我在此表单中使用它来防止页面上的退格返回:
$(document).on("keydown", function (e) {
if (e.which === 8 && !$(e.target).is("input:not([readonly]), textarea")) {
e.preventDefault();
}
});
我对接受的解决方案和Select2.js插件有一些问题;我无法删除中的字符
$(document).on("keydown", function (e) {
if (e.which === 8 && !$(e.target).is("input:not([readonly]), textarea")) {
e.preventDefault();
}
});
//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();
}
});
require(["dojo/on", "dojo/keys", "dojo/domReady!"],
function(on, keys) {
on(document.body,"keydown",function(evt){if(evt.keyCode == keys.BACKSPACE)evt.preventDefault()});
});
document.onkeypress = Backspace;
function Backspace(event) {
if (event.keyCode == 8) {
if (document.activeElement.tagName == "INPUT") {
return true;
} else {
return false;
}
}
}
$(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')
$(document).on('keydown',function(e){
var $target = $(e.target||e.srcElement);
if(e.keyCode == 8 && !$target.is('input,[contenteditable="true"],textarea'))
{
e.preventDefault();
}
})
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;
}
}
}
var stresstest = function(e, method, index){...
$(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();
}
});
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
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();
}
}
}
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;
}
}
}
}
$(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;
}
});
$(document).on("keydown", function (e) {
if (e.which === 8 && !$(e.target).is("input, textarea")) {
e.preventDefault();
}
});
<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>
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";
}
}
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);
};
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
$(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();
}
});
<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>