gpt4 book ai didi

Javascript event.stopPropagation() 不适用于 `accesskey` 属性

转载 作者:行者123 更新时间:2023-11-29 18:02:20 24 4
gpt4 key购买 nike

一个简单的 html 页面只包含两个控件,一个文本框和一个按钮。页面加载后,如果用户在文本框内单击并按“alt”+ p(按钮访问键),消息应显示为“I'm from key down!!”但是如果用户点击文本框内部以外的任何地方,则消息应显示为“仅当焦点位于文本框之外时才应调用我!!!”。完整代码如下:

<!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() 不起作用,知道为什么吗?

最佳答案

accesskey 事件总是被触发

(除非您暂时禁用它)

大多数浏览器总是会触发绑定(bind)到 accesskey 属性的事件,即使其他绑定(bind)的事件处理程序使用常见策略,例如 return falsestopPropagationstopImmediatePropagationpreventDefaultcancelBubble 等,它们在正常情况下可有效阻止事件冒泡和默认行为。

但在您的情况下,您有一个处理程序检查与您通过 accesskey 绑定(bind)到另一个元素的相同的组合键。因此,每次在文本字段具有焦点时输入组合键,都会触发两个处理程序:首先在 keyDown 处理程序中,然后无论是否尝试阻止该事件冒泡,clickMe 处理程序被触发,因为它是由 accesskey 激活的。

一种解决方案是在您不想收听它们时(例如当您的文本输入具有焦点时)暂时删除 accesskey 属性,然后在您不想忽略时恢复它们它们不再存在(例如当您的文本输入失去焦点时)。

参见 this answer for a jQuery powered solution您可以将其用作创建满足您需求的纯 JS 解决方案的跳板。

示例:

<script type="text/javascript">

/* Function to cache accesskey attributes */
function cacheAccessKeys() {

/* Get all elements with accesskeys
// This could be modified to select a smaller subset of elements */
var akEls = document.querySelectorAll('[accesskey]');

/* Iterate over each element in the set of matched elements */
Array.prototype.forEach.call(akEls, function (el, i) {

/* Set the value of data-accesskey to the value of accesskey */
el.setAttribute('data-accesskey', el.getAttribute('accesskey'));

/* Remove the accesskey attribute
// to temporarily disable accesskey binding */
el.removeAttribute('accesskey');
});
}

/* Function to restore accesskey attributes */
function restoreAccessKeys() {

/* Get all elements with accesskeys
// This could be modified to select a smaller subset of elements */
var akEls = document.querySelectorAll('[data-accesskey]');

/* Iterate over each element in the set of matched elements */
Array.prototype.forEach.call(akEls, function (el, i) {

/* Set the value of accesskey to the value of data-accesskey
// to restore accesskey binding */
el.setAttribute('accesskey', el.getAttribute('data-accesskey'));

/* Clean-up (perhaps unnecessary)
// In case the accesskey attributes are set dynamically elsewhere,
// this prevents mismatched caching. */
el.removeAttribute('data-accesskey');
});
}

function keyDown(e) {
if (e.altKey && e.keyCode === 80) {
console.log("I'm from key down!!!");
}
}

function clickMe() {
console.log("I should be called only when the focus is outside the textbox!!!");
}
</script>

<div>


<!-- On focus: Cache/remove accesskey attributes -->
<!-- On keydown: Now the key combo in here won't trigger other handlers. -->
<!-- On blur: Restore accesskey attributes -->
<input type="text"
onfocus="cacheAccessKeys();"
onkeydown="keyDown(event);"
onblur="restoreAccessKeys();"
/>

<!-- On click: Activated by Alt + p access key combo
//-- only when text field does NOT have focus. -->
<input type="button"
accesskey="p"
value="Click me"
onclick="clickMe();"
/>
</div>

关于Javascript event.stopPropagation() 不适用于 `accesskey` 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34006721/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com