在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);
};
纯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))”然后。第一个对我来说很好。
对于任何感兴趣的人,我把一个jQuery插件放在一起,它包含了toolman的(加上@MaffooClock/@cdmckay的评论)和@Vladimir Kornea的想法。
用法:
//# Disable backspace on .disabled/.readOnly fields for the whole document
$(document).disableBackspaceNavigation();
//# Disable backspace on .disabled/.readOnly fields under FORMs
$('FORM').disableBackspaceNavigation();
//# Disable backspace on .disabled/.readOnly fields under #myForm
$('#myForm').disableBackspaceNavigation();
//# Disable backspace on .disabled/.readOnly fields for the whole document with confirmation
$(document).disableBackspaceNavigation(true);
//# Disable backspace on .disabled/.readOnly fields for the whole document with all options
$(document).disableBackspaceNavigation({
confirm: true,
confirmString: "Are you sure you want to navigate away from this page?",
excludeSelector: "input, select, textarea, [contenteditable='true']",
includeSelector: ":checkbox, :radio, :submit"
});
插件:
//# Disables backspace initiated navigation, optionally with a confirm dialog
//# From: https://stackoverflow.com/questions/1495219/how-can-i-prevent-the-backspace-key-from-navigating-back
$.fn.disableBackspaceNavigation = function (vOptions) {
var bBackspaceWasPressed = false,
o = $.extend({
confirm: (vOptions === true), //# If the caller passed in `true` rather than an Object, default .confirm accordingly,
confirmString: "Are you sure you want to leave this page?",
excludeSelector: "input, select, textarea, [contenteditable='true']",
includeSelector: ":checkbox, :radio, :submit"
}, vOptions)
;
//# If we are supposed to use the bConfirmDialog, hook the beforeunload event
if (o.confirm) {
$(window).on('beforeunload', function () {
if (bBackspaceWasPressed) {
bBackspaceWasPressed = false;
return o.confirmString;
}
});
}
//# Traverse the passed elements, then return them to the caller (enables chainability)
return this.each(function () {
//# Disable backspace on disabled/readonly fields
$(this).bind("keydown keypress", function (e) {
var $target = $(e.target /*|| e.srcElement*/);
//# If the backspace was pressed
if (e.which === 8 /*|| e.keyCode === 8*/) {
bBackspaceWasPressed = true;
//# If we are not using the bConfirmDialog and this is not a typeable input (or a non-typeable input, or is .disabled or is .readOnly), .preventDefault
if (!o.confirm && (
!$target.is(o.excludeSelector) ||
$target.is(o.includeSelector) ||
e.target.disabled ||
e.target.readOnly
)) {
e.preventDefault();
}
}
});
});
}; //# $.fn.disableBackspaceNavigation