在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中的这种行为
我有一些问题与接受的解决方案和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。我添加了一些代码来说明span tagName和不同的属性。这解决了我所有的问题。
编辑:如果你没有使用jquery的Select2组合框插件,那么这个解决方案可能不需要你,接受的解决方案可能更好。
我有一些问题与接受的解决方案和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。我添加了一些代码来说明span tagName和不同的属性。这解决了我所有的问题。
编辑:如果你没有使用jquery的Select2组合框插件,那么这个解决方案可能不需要你,接受的解决方案可能更好。
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>
这段代码解决了这个问题,至少在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;
}
}
});
对于任何感兴趣的人,我把一个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