X-Tag 事件委派:访问根元素

x-tag event delegation: accessing the root element

本文关键字:元素 访问 事件 委派 X-Tag      更新时间:2023-09-26

>我需要将'tap'事件委托给自定义元素中的关闭按钮,然后调用根元素上的close()方法。 下面是一个示例:

xtag.register('settings-pane', {
  lifecycle: {
    created: function () {
      var tpl = document.getElementById('settings-pane'),
          clone = document.importNode(tpl.content, true);
      
      this.appendChild(clone);
    }
  },
  events: {
    'tap:delegate(button.close)': function (e) {
      rootElement.close(); // <- I don't know the best way to get rootElement
    }
  },
  methods: {
    close: function () {
      this.classList.add('hidden');
    }
  }
});
<template id="settings-pane">
  <button class="close">✖</button>
</template>

嘿,

这是库作者,让我澄清一下:

对于您在 DOM、X-Tag 或 vanilla JS 中设置的任何侦听器,您始终可以使用标准属性 e.currentTarget 来访问侦听器附加到的节点。对于 X-Tag,无论您是否使用 delegate 伪,e.currentTarget 都将始终引用您的自定义元素:

xtag.register('x-foo', {
  content: '<input /><span></span>',
  events: {
    focus: function(e){
      // e.currentTarget === your x-foo element
    },
    'tap:delegate(span)': function(e){
      // e.currentTarget still === your x-foo element
      // 'this' reference set to matched span element
    }
  }
});

请记住,这是一个标准 API,用于访问事件侦听器附加到的元素,更多内容请点击此处:https://developer.mozilla.org/en-US/docs/Web/API/Event/currentTarget

处理了几个月之后,解决此问题的最佳方法是创建另一个"伪",类似于:delegate()伪,但调用回调的方式不同。 这会将:descendant()伪添加到 xtag:

xtag.pseudos.descendant = {
    action: function descendantAction(pseudo, event) {
        var match,
            target = event.target,
            origin = target,
            root = event.currentTarget;
        while (!match && target && target != root) {
            if (target.tagName && xtag.matchSelector(target, pseudo.value)) match = target;
            target = target.parentNode;
        }
        if (!match && root.tagName && xtag.matchSelector(root, pseudo.value)) match = root;
        return match ? pseudo.listener = pseudo.listener.bind({component: this, target: match, origin: origin}) : null;
    }
};

你会像:delegate()一样使用它,但this将引用一个对象,而该对象又将引用目标元素(与CSS选择器匹配的元素,例如 button.close )、源(接收事件的元素)和组件(自定义元素本身)。 使用示例:

xtag.register('settings-pane', {
    methods: {
        close: function () {
            this.classList.add('hidden');
        }
    },
    events: {
        'tap:descendant(button.close)': function (e) {
            this.origin;    // <button> or some descendant thereof that was tapped
            this.target;    // <button> element
            this.component; // <settings-pane> element
            this.component.close(); 
        }
    }
});