Javascript Vanilla Web组件自定义事件属性和属性

Javascript Vanilla Web组件自定义事件属性和属性,javascript,event-handling,web-component,custom-element,Javascript,Event Handling,Web Component,Custom Element,使用没有任何框架的Web组件,实现自定义事件的正确方法是什么?例如,假设我有一个自定义元素x-pop-out,它有一个自定义事件pop,我希望以下所有操作都能正常工作: 最后一个问题是如何做,但是我是否需要自定义实现属性和每个属性的getter/setter?另外,eval()是从属性执行字符串的适当方法吗?事件侦听器解决方案(第三个)是最简单的,因为不必定义任何特殊的内容来捕获事件 事件处理程序解决方案需要生成一个eval()(第一个,from属性)或明确地调用函数(第二个) 如果不能使用e

使用没有任何框架的Web组件,实现自定义事件的正确方法是什么?例如,假设我有一个自定义元素
x-pop-out
,它有一个自定义事件
pop
,我希望以下所有操作都能正常工作:

最后一个问题是如何做,但是我是否需要自定义实现属性和每个属性的getter/setter?另外,
eval()
是从属性执行字符串的适当方法吗?

事件侦听器解决方案(第三个)是最简单的,因为不必定义任何特殊的内容来捕获事件

事件处理程序解决方案需要生成一个
eval()
(第一个,from属性)或明确地调用函数(第二个)

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

customElements.define('x-pop-out',类扩展HtmleElement{
connectedCallback(){
this.innerHTML=`pop`
此.querySelector('button')。onclick=()=>{
this.dispatchEvent(新的CustomEvent('pop'))
如果(this.onpop)
this.onpop()
其他的
eval(this.getAttribute('onpop'))
}            
}
} )
XPO.addEventListener('pop',()=>console.info('pop'))


基于SuperSharp重新定义onpop
。他的建议只适用于控制台日志,实际上不适用于事件。我使用的解决方案是覆盖dispatchEvent并使其也创建自定义HTML事件属性

遵循使用“on”+event.type的标准。我们使用with在新函数中屏蔽该属性,并检查该属性是否为函数,如果需要,则在事件中传递

dispatchEvent(event) {
  super.dispatchEvent(event);
  const eventFire = this['on' + event.type];
  if ( eventFire ) {
    eventFire(event);
  } else {
  const func = new Function('e',
    'with(document) {'
       + 'with(this) {'
         + 'let attr = ' + this.getAttribute('on' + event.type) +';'
         + 'if(typeof attr === \'function\') { attr(e)};
       + }'
     + '}'
   );
   func.call(this, event);
   } 
}
例如:

类用户卡扩展HtmleElement{
构造函数(){
//如果定义构造函数,请始终首先调用super(),因为CE规范要求它。
超级()//
}
调度事件(事件){
超级调度事件(事件);
const eventFire=this['on'+event.type];
if(eventFire){
事件火灾(事件);
}否则{
const func=新函数('e',
'与(文件){'+
“用(这个){”+
'let attr='+this.getAttribute('on'+event.type)+';'+
'if(typeof attr==\'function\'){attr(e)};'+
'}' +
'}');
函数调用(此,事件);
}
}
connectedCallback(){
this.innerHTML=`用户名
密码
登录`;
this.test=this.querySelector(#login”);
this.test.addEventListener(“单击”,(事件)=>{
这就是dispatchEvent(
新CustomEvent('pop'{
详情:{
用户名:'hardcodeduser',
密码:“hardcodedpass”
}
})
);
})
}
}
自定义元素。定义('user-card',UserCard);
函数onPop2(事件){
调试器;
log('from function');
}



谢谢!这似乎是正确的,我想知道是否有某种方法可以同时在所有3种模式中注册某个事件,但我相信你是正确的。令人惊讶的是,每个带有自定义事件的web组件都应该
eval(string)
,但我看不出有其他建议。实际上eval()的使用并没有链接到自定义元素,而是链接到属性中的内联javascript。它也用于标准元素。这就是为什么在应用受限内容策略时不允许使用内联javascript。不工作。attr类型始终为Object,现在为function@ahmadalibaloch你能告诉我错误吗。只运行了代码片段,工作正常
dispatchEvent(event) {
  super.dispatchEvent(event);
  const eventFire = this['on' + event.type];
  if ( eventFire ) {
    eventFire(event);
  } else {
  const func = new Function('e',
    'with(document) {'
       + 'with(this) {'
         + 'let attr = ' + this.getAttribute('on' + event.type) +';'
         + 'if(typeof attr === \'function\') { attr(e)};
       + }'
     + '}'
   );
   func.call(this, event);
   } 
}