Shadow DOM 外部的事件侦听器不会绑定到 Shadow DOM 内部的元素
Event listener outside of Shadow DOM won't bind to elements inside of Shadow DOM
我的站点上安装了 Angular 网络组件。它使用 Shadow DOM 所以它非常快(在我的情况下必须如此)。
在我的站点上,我还有一个快捷方式 h,它会打开一个显示一些有用信息的弹出窗口。 h 键绑定必须保持原样。可以在此处查看其实现方式的示例代码:https://jsfiddle.net/js1edv37/
这是一个简单的事件侦听器,侦听 document
:
$(document).on("keyup", function(e) {
}
但是,当我的 Web 组件聚焦 textarea
或 input
元素时,也会触发此事件。发生这种情况是因为它使用 Shadow DOM,外部脚本无法访问。
您可以通过在input
和textarea
元素的内部和外部按键盘上的h来测试它。
有没有办法让我的脚本在 Shadow DOM 网络组件之外,仍然监听 keyup
事件,但让它监听 all页面上的元素?就连影子里面的那些DOM.
如果您保存对影子根的引用,您始终可以在搜索时访问它的子节点
$(document).on("keyup", function(e) {
let focusedInputs = $("input:focus, textarea:focus").length + $(shadow).children("input:focus, textarea:focus").length;
if (focusedInputs > 0) {
return true;
}
if (e.keyCode === 72) {
trigger();
}
});
function trigger() {
alert("If this was triggered, everything is perfectly fine");
}
let div = document.querySelector("div");
let shadow = div.createShadowRoot();
shadow.innerHTML = "<textarea>This shouldn't fail</textarea>";
textarea {
width: 500px;
height: 100px;
}
input {
width: 250px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea>Some stuff here</textarea>
<br />
<input type="text" value="Some more text here" />
<br />
<br />
<h1>Shadow DOM element WON'T fail now :)</h1>
<div></div>
在 Web 组件中,通过对 shadowRoot
的 querySelector()
调用获取输入元素 属性:
let textareainshadow = div.shadowRoot.querySelector( 'textarea' )
然后侦听 keyup
事件并借助 stopImmediatePropagation()
方法停止其传播。
textareainshadow.addEventListener( 'keyup' , ev => {
console.log( 'caught', ev.type )
ev.stopImmediatePropagation()
})
我的站点上安装了 Angular 网络组件。它使用 Shadow DOM 所以它非常快(在我的情况下必须如此)。
在我的站点上,我还有一个快捷方式 h,它会打开一个显示一些有用信息的弹出窗口。 h 键绑定必须保持原样。可以在此处查看其实现方式的示例代码:https://jsfiddle.net/js1edv37/
这是一个简单的事件侦听器,侦听 document
:
$(document).on("keyup", function(e) {
}
但是,当我的 Web 组件聚焦 textarea
或 input
元素时,也会触发此事件。发生这种情况是因为它使用 Shadow DOM,外部脚本无法访问。
您可以通过在input
和textarea
元素的内部和外部按键盘上的h来测试它。
有没有办法让我的脚本在 Shadow DOM 网络组件之外,仍然监听 keyup
事件,但让它监听 all页面上的元素?就连影子里面的那些DOM.
如果您保存对影子根的引用,您始终可以在搜索时访问它的子节点
$(document).on("keyup", function(e) {
let focusedInputs = $("input:focus, textarea:focus").length + $(shadow).children("input:focus, textarea:focus").length;
if (focusedInputs > 0) {
return true;
}
if (e.keyCode === 72) {
trigger();
}
});
function trigger() {
alert("If this was triggered, everything is perfectly fine");
}
let div = document.querySelector("div");
let shadow = div.createShadowRoot();
shadow.innerHTML = "<textarea>This shouldn't fail</textarea>";
textarea {
width: 500px;
height: 100px;
}
input {
width: 250px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea>Some stuff here</textarea>
<br />
<input type="text" value="Some more text here" />
<br />
<br />
<h1>Shadow DOM element WON'T fail now :)</h1>
<div></div>
在 Web 组件中,通过对 shadowRoot
的 querySelector()
调用获取输入元素 属性:
let textareainshadow = div.shadowRoot.querySelector( 'textarea' )
然后侦听 keyup
事件并借助 stopImmediatePropagation()
方法停止其传播。
textareainshadow.addEventListener( 'keyup' , ev => {
console.log( 'caught', ev.type )
ev.stopImmediatePropagation()
})