自定义元素未获取onclick 编辑:编辑2:编辑3:

问题描述

我正在定义一个自定义元素

customElements.define("my-button",class extends HTMLButtonElement {
  onclick() {
    console.log("bar");
  }
},{ extends: "button" })

https://jsfiddle.net/tuxkjp3q/

但是当我单击它时,什么也没有发生。

这是为什么?如何在不覆盖构造函数的情况下将事件处理程序附加到类的每个实例上?

编辑:

当我检查DOM对象时,有一个onclick处理程序,但是没有起作用。这很混乱

enter image description here

编辑2:

进一步的发现,从原型中省略时,定义了处理程序。

customElements.define("my-button",class extends HTMLButtonElement {
  constructor() {
    super();
    this.onclick = () => console.log("bar");
  }
},{ extends: "button" })

但是当原型包含onclick时,相同的处理程序将不再起作用

customElements.define("my-button",class extends HTMLButtonElement {
  onclick() {
    console.log("bar");
  }

  constructor() {
    super();
    this.onclick = () => console.log("bar");
  }
},{ extends: "button" })

如果能对此现象做出解释,我将非常高兴。

编辑3:

如果有人遇到相同的问题,我想出一个解决方法。可能值得注意的是,只有实例化类的直接原型中定义的处理程序才会被附加,这对性能有好处,但逻辑上可能有缺陷。无论如何,它可以根据您的要求进行调整。

// Only in the base class
constructor() {
  super();

  for (let prop of Object.getownPropertyNames(this.constructor.prototype)) {
    if (prop.indexOf("on") === 0) {
      this.addEventListener(prop.substring(2).toLowerCase(),this.constructor.prototype[prop]);
    }
  }
}

我仍然非常有兴趣了解原因。

解决方法

问题是您需要定义click的侦听器...而不是onClick函数

class CustomButton extends HTMLButtonElement  {
  constructor() {
    super();

    this.addEventListener('click',() => {
      console.log('clicked');
    });
  }
}

customElements.define('custom-button',CustomButton,{ extends: "button" });

html

<button is="custom-button">
  Hi
</button>
,

您真正要做的就是为您的自定义元素创建一个onclick属性,并为其分配一个功能。仅仅因为它被命名为onclick并不意味着该系统知道它是click事件,因为您正在制作自己的元素。 You will need to create a custom event for your custom element.

,

在附加所有以 on

开头的处理程序时,您会很钝

猜猜可能有多少:

document.body.append(
  ...Object.getOwnPropertyNames(window).filter(prop => prop.indexOf("on") === 0)
  .map((prop,idx,arr) => {
    let div = document.createElement("div");
    div.innerHTML = `${arr.length-idx} &nbsp; ${prop}`;
    return div;
  }));

您不必使用addEventListener;

在组件 中使用( old this.onclick=处理程序,
因为该组件的用户可以轻松覆盖它。
使用addEventListener组件的 author 必须提供一种removeListener方法;否则用户将无法删除侦听器。

有关不同JavaScript事件模型的信息:

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...