【问题标题】:custom element, custom event handler attributes自定义元素,自定义事件处理程序属性
【发布时间】:2020-02-02 01:54:05
【问题描述】:

内置浏览器元素具有执行任意 javascript 的事件属性,如下所述

是否有任何方法可以创建具有类似行为的 自定义事件 处理程序属性的自定义元素,是否有这样做的标准模式?其中{some custom eventType}="{some code}" 在范围内使用正确的值执行,并且 this 绑定设置正确。

<some-custom-element oncustomevent="alert('worked')" />

【问题讨论】:

    标签: custom-element custom-events


    【解决方案1】:

    第一个问题是:您真的要允许从字符串执行代码吗?因为它需要eval()

    使用eval() 没有任何问题当您了解其含义时

    触发动态(字符串)代码:

    • 来自自定义元素属性onevent
    • 来自自定义元素设置器onevent
    • 来自自定义事件onevent 详细信息(请参阅connectedCallback

      function triggerEvent(name, code = "console.warn('No code parameter')") {
        console.log(name, this);
        if (this === window) console.warn('no element scope');
        try {
          if (typeof code === "string") eval(code);
          else console.warn("code is not a string")
        } catch (e) { console.error(e) }
      }
      customElements.define("my-element", class extends HTMLElement {
        static get observedAttributes() {
          return ['onevent'];
        }
        constructor() {
          super();
          this.onclick = () => triggerEvent.call(this, "element Click", "console.log('from element click')");
        }
        connectedCallback() {
          document.addEventListener("onevent", evt => {
            triggerEvent.call(this, "EventListener", evt.detail);
          })
        }
        attributeChangedCallback(name, oldValue, newValue) {
          if (name === "onevent") {
            triggerEvent.call(this, "attributeChangedCallback", newValue);
          }
        }
        set onevent(newValue) {
          triggerEvent.call(this, "setter", newValue);
        }
      });
    
      setTimeout(() => document.dispatchEvent(new CustomEvent("onevent", {
          detail: "console.log('from dispatchEvent detail')"
        })), 2000); //execute after elements listen
    <my-element onevent="console.log('from element attribute')">click my-element</my-element>
    <button onclick="document.querySelector('my-element').onevent='console.log(&quot;from button&quot;)'"
    >Call setter</button>

    JSFiddle 游乐场位于:https://jsfiddle.net/CustomElementsExamples/s9jm72nf/

    【讨论】:

    • 感谢您的回答。不过,我有三个后续问题。 1.事件当前是在属性更改时触发的,是否有标准模式在事件触发时执行它? 2. 这是一种标准的做事方式,还是社区中的大多数人不喜欢使用这样的自定义事件处理程序属性?注意:我没有意识到的一件事是 eval 总是在当前范围内执行。这影响了我对原始问题的理解
    • connectedCallback 中的侦听器侦听事件(冒泡到)document,这不是您所说的“事件触发”吗?我从未使用过也没有见过这种“模式”,所以我认为没有标准方式;这是你的代码,你可以做你想做的事。发布组件时添加大量文档和示例用法。
    • 我之前没听懂,请指点我。是的,这就是我所说的事件触发。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多