用于 Web 组件/自定义事件 (JS) 的基于 HTML 的事件侦听器

2024-03-21

TL;DR; 是否可以在 HTML(而不是 JS)中为自定义事件定义事件侦听器?

以此为基础codepen https://codepen.io/tony19/pen/EWerge?editors=1011,我正在尝试执行以下操作:

<my-checkreport
  onclick="myFunction()"
  oncheck="myFunction1)"
  check="myFunction()"
></my-checkreport>

where myFunction做一些console.log我可以在浏览器控制台中看到的东西。本国的onlick当然有效,但两者都没有oncheck nor check工作,对于下面定义的自定义事件(来源取自上面链接codepen https://codepen.io/tony19/pen/EWerge?editors=1011):

customElements.define('my-checkbox', class extends HTMLElement {
  constructor() {
    super();
    const shadowRoot = this.attachShadow({mode: 'open'});
    this.checkEvent = new CustomEvent("check", {
      bubbles: true,
      cancelable: false,
    });
    shadowRoot.innerHTML = `
      <label>
        <input type="checkbox" id="my-checkbox"></input>
        Dummy Enabled
      </label>`;
    shadowRoot.querySelector('#my-checkbox').addEventListener('click', (e) => {
      console.log('checked', e.target.checked);
      this.dispatchEvent(this.checkEvent);
    });
  }
});

是否可以为 HTML 中的自定义事件附加事件侦听器?


这是我能最接近地模拟事件处理程序的 DOM 声明的方法。据我所知,这段代码完成了 DOM 为内置事件处理程序所做的一切。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>On-Event Test</title>
    <script>
    function onCheckHandler(event) {
      console.log('onCheckHandler: %O', event);
      event.stopPropagation();
      event.stopImmediatePropagation();
      //event.preventDefault();
    }

    function eventListener(event) {
      console.log('eventListener: %O', event);
    }
    (function() {
      var template = `<div>Click to Check</div>`;
      class MyEl extends HTMLElement {
        constructor() {
          super();

          var rootEl = this.attachShadow({mode: 'open'});
          rootEl.innerHTML = template;
          rootEl.firstChild.addEventListener('click', () => {
            var checkEvent = new CustomEvent("check", {bubbles:true,cancelable:true});
            if (this.dispatchEvent(checkEvent)) {
              // Do default operation here
              console.log('Performing default operation');
            }
          });
          this._onCheckFn = null;
        }

        static get observedAttributes() {
          return ['oncheck'];
        }

        attributeChangedCallback(attrName, oldVal, newVal) {
          if (attrName === 'oncheck' && oldVal !== newVal) {
            if (newVal === null) {
              this.oncheck = null;
            }
            else {
              this.oncheck = Function(`return function oncheck(event) {\n\t${newVal};\n};`)();
            }
          }
        }

        get oncheck() {
          return this._onCheckFn;
        }
        set oncheck(handler) {
          if (this._onCheckFn) {
            this.removeEventListener('check', this._onCheckFn);
            this._onCheckFn = null;
          }

          if (typeof handler === 'function') {
            this._onCheckFn = handler;
            this.addEventListener('check', this._onCheckFn);
          }
        }
      }

      // Define our web component
      customElements.define('my-el', MyEl);
    })();
    </script>
  </head>
  <body>
    <my-el oncheck="onCheckHandler(event)"></my-el>
  </body>
</html>

要使其正常工作,您需要执行两个步骤:

步骤1:

组件代码必须支持属性更改。

当属性设置为字符串(要调用的函数)时,代码将创建一个临时函数,尝试调用作为属性值提供的函数。然后该函数被传递到第二步。

当该属性设置为其他任何值或删除该属性时,代码会将 null 传递到第二步。

第二步:

组件代码必须支持oncheck财产。

每当更改此属性时,都需要通过调用删除任何先前为此属性定义的事件处理程序removeEventListener.

如果属性的新值是一个函数,则调用addEventListener将该函数作为处理程序。

弄清楚这一点很有趣。一开始我以为是基于DOM的oncheck处理程序永远是第一位的。但通过测试onclick and addEventHandler('click')我发现事件处理程序是按照收到的顺序添加的。如果onclick在 DOM 中提供,而不是首先添加事件侦听器。如果你随后打电话removeAttribute('onclick')进而setAttribute('onclick', 'handler(event)')然后该事件处理程序被移动到列表的末尾。

所以这段代码完全复制了我与click event.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用于 Web 组件/自定义事件 (JS) 的基于 HTML 的事件侦听器 的相关文章