在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中的这种行为
我创建了一个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);
};
我很难找到一个非jquery的答案。谢谢斯塔斯让我走上赛道。
Chrome:如果你不需要跨浏览器支持,你可以使用黑名单,而不是白名单。这个纯JS版本可以在Chrome中运行,但不能在IE中运行。不确定FF。
在Chrome(版本。36, 2014年年中),按键不是在输入或可满足的元素似乎是针对<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的答案是最好的。增加一个条件检查contentteditable使它为我工作*:
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: and Spartan/TechPreview]有一个“特性”,使与表相关的元素不可编辑。如果你点击其中一个,然后按退格键,它会导航回来。如果你没有editable <td>s,这不是一个问题。