一个简单的html页面只包含两个控件,一个文本框和一个按钮。页面加载后,如果用户在文本框中单击并按“alt”+ p(按钮访问键),则该消息应显示为“我是从按键下来!!!”但如果用户单击文本框内的任何位置,则该消息应该显示为“只有在焦点位于文本框之外时才应该调用!!!”。完整代码如下所示:
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<script type="text/javascript">
function keyDown() {
if (event.altKey && event.keyCode == 80) {
event.returnValue = false;
event.cancelBubble = true;
event.keyCode = 0;
alert("I'm from key down!!!");
}
}
function clickMe() {
alert("I should be called only when the focus is outside the textbox!!!");
}
</script>
</head>
<body>
<div>
<input type="text" onkeydown ="keyDown();" />
<input type="button" value="Click me" accesskey="p" onclick="clickMe();" />
</div>
</body>
</html>
在IE10及以下版本中可以正常使用。但它在IE11和Chrome中不起作用,相反它会一个接一个地显示两条警告信息,例如“我来自关键!!!”和“只有当焦点在文本框之外时才应该调用!!!”这是不可取的。因此,keyDown()
事件处理程序已更改为支持IE10 +和Chrome
function keyDown() {
if (event.altKey && event.keyCode == 80) {
event.preventDefault ? event.preventDefault() : (event.returnValue = false);
event.stopPropagation ? event.stopPropagation() : (event.cancelBubble = true);
event.keyCode = 0;
alert("I'm from key down!!!");
}
}
但是在这种情况下event.stopPropagation()不起作用,任何想法为什么?
答案 0 :(得分:2)
accesskey
事件大多数浏览器将始终触发绑定到accesskey
属性的事件,即使其他绑定事件处理程序使用常见策略,例如return false
,stopPropagation
,stopImmediatePropagation
,{{1 }},preventDefault
等,在正常情况下可以有效地阻止事件冒泡和默认行为。
但是在你的情况下,你有一个处理程序检查你通过cancelBubble
绑定到另一个元素的相同组合键。因此,每当在文本字段具有焦点时输入关键组合时,两个处理程序都会被触发:首先在accesskey
处理程序中,然后无论是否尝试阻止该事件冒泡,keyDown
处理程序都是触发因为clickMe
激活了它。
一种解决方案是在您不想收听时暂时删除accesskey
属性(例如当您的文字输入有焦点时),然后在您不想要时恢复它们再忽略它们(例如当你的文字输入失去焦点时)。
请参阅this answer for a jQuery powered solution,您可以将其用作跳板,以创建符合您需求的简单JS解决方案。
示例:强>
accesskey
&#13;
答案 1 :(得分:1)
accesskey
属性似乎是个问题。 Chrome和IE使用 ALT + accesskey 来激活按键。 https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/accesskey。删除它,问题就消失了。
<强> jsFiddle example 强>
答案 2 :(得分:1)
这是另一种解决方法,只需禁用已启用的accesskey元素,然后重新启用它。
function keyDown() {
if (event.altKey && event.keyCode == 80) {
var accecskeyObj = $("input[accesskey=" + event.key + "][disabled != disabled]");
accecskeyObj.prop('disabled',true);
alert("I'm from key down!!!");
accecskeyObj.prop('disabled',false);
}
}
答案 3 :(得分:0)
您没有通过事件对象。
<input type="text" onkeydown="keyDown();" />
<input type="button" value="Click me" onclick="clickMe();" />
function keyDown() {
if (event.altKey && event.keyCode == 80) {
event.returnValue = false;
event.cancelBubble = true;
event.keyCode = 0;
alert("I'm from key down!!!");
}
}
function clickMe() {
alert("I should be called only when the focus is outside the textbox!!!");
}
但是,既然它已经定义为全球性的,它不应该成为问题。我检查并添加了任何类型的accesskey,chrome背靠背绕过两个警报框。
为了解决这个问题,我不认为您有任何其他选择,而不是删除访问密钥。删除后,它会在chrome和IE上显示相同的结果。
b = np.asarray(x)
for i in range(len(x.flat)):
b.flat[i] = operation(x.flat[i])
答案 4 :(得分:0)
这只是一种解决方法,不能成为一个合适的解决方案 - accesskey
属性是问题,所以要暂时删除此属性并再次添加它,如@gfullam所述。这可以通过使用jquery有效地完成,但不知道为什么stopPropagation()不起作用。
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
<script type="text/javascript">
function keyDown(evt) {
var e = evt || window.event;
if (e.altKey && e.keyCode == 80) {
//event.returnValue = false;
//event.cancelBubble = true;
//event.keyCode = 0;
var allAccessKeys = $('[accesskey]').each(function () {
$(this).data('allAccessKeys', $(this).attr
('accesskey')).removeAttr('accesskey');
});
alert("I'm from key down!!!");
setTimeout(function () {
allAccessKeys.each(function () {
$(this).attr('accesskey', $(this).data
('allAccessKeys'));
});
}, 0);
}
}
function clickMe() {
alert("I should be called only when the focus is outside the textbox!!!");
}
</script>
</head>
<body>
<div>
<input type="text" onkeydown="keyDown(event);" />
<input type="button" value="Click me" accesskey="p" onclick="clickMe();" />
</div>
</body>
</html>