簡體   English   中英

如何將JavaScript添加到自定義元素?

[英]How to add JavaScript to Custom Elements?

我有以下代碼,該代碼創建了一個自定義元素,並封裝了Shadow DOM:

'use strict'
var proto = Object.create(HTMLElement.prototype);
proto.createdCallback = function() {

    var root = this.createShadowRoot();
    var divEl = document.createElement('div');
    divEl.setAttribute("id", "container");
    divEl.innerHTML =
        "<input id='input' type='text'>"
      + "<br>"
      + "Result: <span id='result'></span>"
      + "<br><button onclick='performTask()'>Run</button>";
    root.appendChild(divEl);

};
document.registerElement('custom-ele', {
    prototype: proto
});

這個想法是,當單擊“運行”時,將從輸入元素中獲取輸入並進行處理(在performTask()中),然后將輸出放入“ #result”中。 我的兩個問題是:

  1. 如何從Shadow DOM的輸入字段中獲取值?
  2. 如何將輸出放入#result?

之前的堆棧溢出后看起來會回答我的問題,但所有的建議鏈接不再有效所以我想知道如果任何人都可以在正確的方向指向我:)

PS我寧願不使用模板,因為並非所有瀏覽器都支持HTML導入,並且我希望所有自定義元素代碼都包含在一個文件中。

事實證明您可以向影子根本身添加功能,然后只需在影子根上調用this.parentNode.fn()即可直接引導子代訪問shadowRoot ...

proto.createdCallback = function() {

    let root = this.createShadowRoot();

    root.innerHTML = "<input id='input' type='text'>"
        + "<br>"
        + "Result: <span id='result'></span>"
        + "<br><button onclick='this.parentNode.process()'>Run</button>";

    this.shadowRoot.process = function() {
        let spanEle = this.querySelector('span');
        let inputEle = this.querySelector('input');
        spanEle.textContent = performAlgorithm(inputEle.value.split(','));
    };
};
document.registerElement('custom-ele', { prototype: proto });

(感謝MarcG給我的初步見解)

關閉

您可以在Shadow DOM root上使用方法querySelector來獲取內部元素:

'use strict'
var proto = Object.create( HTMLElement.prototype )
proto.createdCallback = function ()
{
    //HTML ROOT
    var root = this.createShadowRoot()
    root.innerHTML = "<input id='input' type='text'>"
        + "<br>"
        + "Result: <span id='result'></span>"
        + "<br><button>Run</button>"

    //UI
    var buttonEle = root.querySelector( "button" )
    var inputEle = root.querySelector( "input" )
    var spanEle = root.querySelector( "#result" )
    buttonEle.onclick = function ()
    {
        var input = inputEle.value
        // do some processing...
        spanEle.textContent = input
    } 
}
document.registerElement( 'custom-ele', { prototype: proto } )

注意:您可以在同一頁面中使用沒有HTML導入的template 請參見以下代碼段:

 <html> <body> <custom-ele></custom-ele> <template id="custelem"> <input id='input' type='text'> <br>Result: <span id='result'></span> <br> <button>Run</button> </template> <script> var proto = Object.create(HTMLElement.prototype) proto.createdCallback = function() { //HTML ROOT var root = this.createShadowRoot() root.innerHTML = custelem.innerHTML //UI var buttonEle = root.querySelector("button") var inputEle = root.querySelector("input") var spanEle = root.querySelector("#result") buttonEle.onclick = function() { var input = inputEle.value // do some processing... spanEle.textContent = input } } document.registerElement('custom-ele', { prototype: proto }) </script> </body> </html> 

不關門

如果您不想使用閉包,則可以在自定義元素上聲明一個名為handleEvent的方法,並添加一個將在其上重定向的事件監聽器:

proto.createdCallback = function ()
{
    //HTML ROOT
    var root = this.createShadowRoot()
    root.innerHTML = custelem.innerHTML

    //EVENT
    var buttonEle = root.querySelector( "button" )
    buttonEle.addEventListener( "click", this )
}

proto.handleEvent = function ( ev )
{
    var inputEle = this.shadowRoot.querySelector( "input" )
    var spanEle = this.shadowRoot.querySelector( "#result" )
    // do some processing...
    spanEle.textContent = inputEle.value
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM