从内联元素访问Web组件中的类函数

时间:2018-12-28 19:43:47

标签: javascript web-component

我想从Web组件内的Element中执行已定义的类函数:

customElements.define('first-component', class FirstComponent extends HTMLElement {
    constructor() {
        super();
     }

     log() {
        console.log('Well Done!')
     }

     connectedCallback() {
        this.innerHTML = '<button onclick="log()">Do it</button>'
     }
});

当前状态:参考错误:未定义日志

4 个答案:

答案 0 :(得分:2)

使用parentElement

要调用自定义元素的log()方法,您必须有一个引用。

在您的示例中,custom元素是<button>元素的父元素,因此您应该调用按钮的parentElement属性,如@Smankusors所述:

<button onclick="this.parentElement.log()>Do it</button>

使用getRootNode()

或者,在更复杂的DOM树中,如果使用了影子DOM,则可以将getRootNode()host结合使用以获取自定义元素引用。

customElements.define('first-component', class FirstComponent extends HTMLElement {
     log() {
        console.log('Well Done!')
     }

     connectedCallback() {
        this.attachShadow({mode: 'open'})
            .innerHTML = '<button onclick="this.getRootNode().host.log()">Do it</button>'
     }
})
<first-component></first-component>


具有唯一标识符

您还可以通过其id属性(如果有)来调用自定义元素:

customElements.define('first-component', class FirstComponent extends HTMLElement {
     log() {
        console.log('Well Done!')
     }

     connectedCallback() {
        if (!this.id)
            this.id = "_id"
        this.innerHTML = `<button onclick="${this.id}.log()">Do it</button>`
     }
})
<first-component></first-component>


使用handleEvent()

出于安全原因,您可以避免使用内联脚本并实现handleEvent()方法,然后根据某些条件在其中调用特定的方法:

customElements.define('first-component', class FirstComponent extends HTMLElement {
    log() {
        console.log('Well Done!')
    }
     
    handleEvent(ev) {
        if (ev.target.innerText == 'Do it')
            this.log()
    }

    connectedCallback() {
        this.innerHTML = '<button>Do it</button>'
        this.addEventListener('click', this)
    }
})
<first-component></first-component>

答案 1 :(得分:1)

该值不应为log(),而应为this.log(),因为该log函数作用域仅是该元素,而不是window作用域,因此您的代码应为< / p>

customElements.define('first-component', class FirstComponent extends HTMLElement {
    constructor() {
        super();
     }

     log() {
        console.log('Well Done!')
     }

     connectedCallback()
        this.innerHTML = '<button onclick="this.parentElement.log()">Do it</button>'
     }
});

-编辑- 抱歉,我的错误,我刚刚看到您在自定义元素中添加了按钮,好吧……如果您仍然希望内联,则应该为this.parentElement.log()

答案 2 :(得分:0)

由于DOM及其元素对它所处的范围没有任何了解,因此仅设置innerHTML的值将不起作用,因为logwindow上不存在。 DOM范围。因此,最佳做法是创建元素并将其附加到自定义元素的Shadow Dom,同时将eventListener添加到按钮。

customElements.define('first-component', class FirstComponent extends HTMLElement {
    constructor() {
        super();
     }

     log() {
        console.log('Well Done!')
     }

     connectedCallback() { // This parentheses was also missing
         var shadow = this.attachShadow({mode: 'open'});
         const button = document.createElement("button");
         button.textContent = 'Do it!';
         button.addEventListener('click', () => this.log());
         shadow.appendChild(button);
     }
});
<first-component id="component"></first-component>

答案 3 :(得分:0)

出于多种原因,您应该-停止使用内联事件监听器。相反,请使用addEventListener-在这种情况下,请使用connectedCallback

customElements.define('first-element', class FirstElement extends HTMLElement {
    constructor() {
        super();
     }

     log() {
        console.log('Well Done!')
     }

     connectedCallback() {
        const btn = document.createElement('button');
        btn.textContent = 'Do it!';
        btn.type = 'button'; // otherwise it's type=submit
        btn.addEventListener('click', this.log);
        this.appendChild(btn);
     }
});
<first-element></first-element>