我正在尝试在阴影dom内部创建一个click事件。
我如何做到这一点,以便影子dom内部的脚本会影响所选元素?
我希望它的行为几乎就像加载外部脚本一样。我不知道“文件”(script.textContent
)中可能包含什么,因此我希望文档成为#shadow-root。我希望它充当iframe,其中iframe拥有自己的文档。
例如,我说我正在使用codemirror,用户可以在其中输入自己的html,样式和脚本。我不知道用户可能输入什么,但是我希望它们一起工作。
class shadow_dom extends HTMLElement {
constructor() {
// Always call super first in constructor
super();
// write element functionality in here
var shadow = this.attachShadow({
mode: "open"
});
var html_content =
'<button class="button">Click Me</button><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js">\\/script>';
var css_content =
" .button {background: #23A7FF;color: #fff;border: 1px solid #23A7FF;border-radius: 4px; cursor: pointer; padding: 5px 10px;}";
var js_content =
'$(document).on("click", ".button", function() { $(this).css("background", "green"); console.log("clicked!"); });';
// $(shadow).on("click", ".button", function() ?
var style = document.createElement("style");
style.textContent = css_content;
var script = document.createElement("script");
script.type = "text/javascript";
script.textContent = js_content;
// POPULATE SHADOW DOM WITH CONTENT
shadow.innerHTML = html_content; // insert html
shadow.insertBefore(style, shadow.firstChild); // prepend style
shadow.appendChild(script); // append script
}
}
// Define the new element
customElements.define("shadow-dom", shadow_dom);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<shadow-dom></shadow-dom>
var js_content =
'$(document).on("click", ".button", function() {$(this).css("background", "green"); console.log("clicked!"); });';
正在将处理程序附加到DOM,而不是影子DOM。
connectedCallback()
在元素附加到DOM时(之后)被调用。 (read about it)。您可以使用this.shadowRoot
充当您的document
class shadow_dom extends HTMLElement {
constructor() {
// Always call super first in constructor
super();
// write element functionality in here
var shadow = this.attachShadow({
mode: "open"
});
var html_content =
'<button class="button">Click Me</button><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"><\/script>';
var css_content =
" .button {background: #23A7FF;color: #fff;border: 1px solid #23A7FF;border-radius: 4px; cursor: pointer; padding: 5px 10px;}";
var js_content =
'$(document).on("click", ".button", function() { $(this).css("background", "green"); console.log("clicked DOM .button!"); });';
var style = document.createElement("style");
style.textContent = css_content;
var script = document.createElement("script");
script.type = "text/javascript";
script.textContent = js_content;
// POPULATE SHADOW DOM WITH CONTENT
shadow.innerHTML = html_content; // insert html
shadow.insertBefore(style, shadow.firstChild); // prepend style
shadow.appendChild(script); // append script
}
connectedCallback(){
$(this.shadowRoot.querySelector('.button')).on("click", (e) => {
$(e.target).css("background", "green"); console.log("clicked SHADOW DOM button!");
});
}
}
// Define the new element
customElements.define("shadow-dom", shadow_dom);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<shadow-dom></shadow-dom>
<button class='button' id='test'>TEST</button>