Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 自定义元素未拾取onclick_Javascript_Html_Ecmascript 6_Native Web Component - Fatal编程技术网

Javascript 自定义元素未拾取onclick

Javascript 自定义元素未拾取onclick,javascript,html,ecmascript-6,native-web-component,Javascript,Html,Ecmascript 6,Native Web Component,我正在定义一个自定义元素 customElements.define("my-button", class extends HTMLButtonElement { onclick() { console.log("bar"); } }, { extends: "button" }) 但当我点击它时,什么也没发生 为什么会这样?我如何在不重写构造函数的情况下将事件处理程序附加到类的每个实例 编辑: 当我检查DOM对象时

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

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

但当我点击它时,什么也没发生

为什么会这样?我如何在不重写构造函数的情况下将事件处理程序附加到类的每个实例

编辑: 当我检查DOM对象时,有一个onclick处理程序,但它不起作用。这令人困惑

编辑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]);
    }
  }
}

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

问题是您需要定义单击的侦听器。。。不是onClick函数

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

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

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


你好

您真正要做的就是为自定义元素创建一个
onclick
属性,并为其分配一个函数。仅仅因为它被命名为
onclick
,并不意味着系统知道这是一个
click
事件,因为您正在创建自己的元素

在附加所有以on开头的处理程序时,您的操作非常简单

猜猜可能有多少人:

document.body.append(
…Object.getOwnPropertyNames(window.filter)(prop=>prop.indexOf(“on”)==0)
.map((道具、idx、arr)=>{
设div=document.createElement(“div”);
div.innerHTML=`${arr.length-idx}${prop}`;
返回div;

}));我特别指出,我正在寻找一种不重写构造函数的解决方案。通过定义函数
onclick
我应该定义本质上是
onclick
事件属性。如果我在
my button
中将它声明为一个HTML标记,而不是通过JavaScript,那么它可以正常工作。谢谢您的时间!如编辑2中所示,如果将其添加为属性,则系统知道它是一个事件处理程序。为什么不重写构造函数?@Supersharp这是一个设计决策,或者简单地说,这很难看。还有一个问题,比如说我使用了
addEventListener
,但是我的监听器实际上绑定到了类的原型,并且在*
名称上使用了
,然后有一天标准会改变并实现这个问题中预期的行为,然后,您将两次调用同一个处理程序,这很可能会导致应用程序崩溃。仅供参考:自定义内置(扩展除HtmleElement以外的任何内容)在Safari中都无法工作;苹果拒绝执行这部分标准。注编辑#3仍然允许
此。单击
定义。它不能像您期望的那样(今天)工作的原因是内联处理程序可以追溯到25年前
这个.onclick
是一种古老的方法(完全有效,而且大多数时候(我)更喜欢这种方法);与
addEventListener
处理程序不同的表示法(根据2010年后编写的教科书,首选方法)ES6
class
引入时,他们(我想)不想使用(旧)表示法。注2:#3会让你陷入内存问题。。您正在到处添加侦听器,但没有删除它们。垃圾收集可能会捕获大部分/部分内容,但通常情况下,如果你添加了一个侦听器,你也要负责删除该侦听器(在
disconnectedCallback
中)@Danny'365CSI'Engelman在我听来像是safari将成为新的ie,如果苹果不齐心协力的话。你能提供注释2的任何来源吗?我相信监听器和元素一起被收集起来。正如评论中所讨论的,这是对我的示例的不当使用。试着在
window.constructor.prototype
上运行它,看看有多少。
<button is="custom-button">
  Hi
</button>