Shadow DOM之外的事件侦听器不会绑定到Shadow DOM内部的元素

问题描述 投票:3回答:2

我的网站上安装了Angular Web组件。它使用Shadow DOM,所以它超级快(它必须在我的情况下)。

在我的网站上,我还有一个h的快捷方式,打开一个弹出窗口,显示一些有用的信息。这个h键绑定必须保持不变。它的实现方式的示例代码可以在这里看到:https://jsfiddle.net/js1edv37/

这是一个监听document的简单事件监听器:

$(document).on("keyup", function(e) {

}

但是,当我的Web组件集中了textareainput元素时,这也会被触发。发生这种情况是因为它使用了Shadow DOM,外部的脚本无法访问。

您可以通过在inputtextarea元素内外键盘上按h来测试它。

有没有办法让我的脚本来自Shadow DOM Web组件之外,仍然可以监听keyup事件,但是让它监听页面上的所有元素?甚至是Shadow DOM里面的那些。

javascript jquery shadow-dom
2个回答
3
投票

在Web Component中,使用querySelector()属性上的shadowRoot调用获取input元素:

let textareainshadow = div.shadowRoot.querySelector( 'textarea' )

然后听keyup事件并在stopImmediatePropagation()方法的帮助下停止它的传播。

textareainshadow.addEventListener( 'keyup' , ev => {
    console.log( 'caught', ev.type )
    ev.stopImmediatePropagation()
}) 

https://jsfiddle.net/7mkrxh25/1/


2
投票

如果将引用保存到影子根,则可以随时访问它的子项作为搜索它们

$(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>

Fiddle

© www.soinside.com 2019 - 2024. All rights reserved.