2017-02-18 103 views
3

在没有任何框架的情况下使用Web Components,实现自定义事件的正确方法是什么?例如,假设我有一个有pop自定义事件自定义元素x-pop-out我希望所有的工作情况如下:Vanilla Web组件自定义事件属性和属性

<x-pop-out onpop="someGlobal.doSomething()"/>

var el = document.getElementsByTagName('x-pop-out')[0]; 
el.onpop =()=> someGlobal.doSomething(); 
//or 
el.addEventListener('pop',()=> someGlobal.doSomething()); 

最后一个我知道要怎么做,但做我需要自定义实现每个属性和getter/setter?另外,eval()是从属性执行字符串的适当方式吗?

回答

2

事件监听器解决方案(第三个)是最容易的,因为您不必定义任何特殊的事件来捕获事件。

事件处理程序解决方案需要制作一个eval()(来自属性的第一个)或明确调用该功能(第二个)。

如果您不能使用eval,则可以改为解析属性字符串。

customElements.define('x-pop-out', class extends HTMLElement { 
 
    connectedCallback() { 
 
     this.innerHTML = `<button id="Btn">pop</button>` 
 

 
     this.querySelector('button').onclick =() => { 
 
      this.dispatchEvent(new CustomEvent('pop')) 
 
      if (this.onpop) 
 
       this.onpop() 
 
      else 
 
       eval(this.getAttribute('onpop')) 
 
     }    
 
    } 
 
}) 
 

 
XPO.addEventListener('pop',() => console.info('pop'))
<x-pop-out id=XPO onpop="console.log('onpop attribute')"></x-pop-out> 
 
<hr> 
 
<button onclick="XPO.onpop =() => console.log('onpop override')">redefine onpop</button>

+0

的感谢!这似乎是正确的,我想知道是否有某种方式一次注册一个事件的所有3种模式,但我相信你是正确的没有。令人惊讶的是,认为每个具有自定义事件的Web组件都被期望“eval(字符串)”,但我没有看到其他方面的建议。 – hapticdata

+0

实际上,使用eval()并没有链接到自定义元素,而是在属性中嵌入JavaScript。它也用于标准元素。这就是为什么在应用受限内容策略时不允许内联JavaScript。 – Supersharp