简体   繁体   中英

x-tag event delegation: accessing the root element

I need to delegate a 'tap' event to a close button in a custom element, and in turn call a close() method on the root element. Here is an example:

 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> 

​Hey there, this is the library author, let me clear this up:

For any listener you set in the DOM, X-Tag or vanilla JS, you can always use the standard property e.currentTarget to access the node the listener was attached to. For X-Tag, whether you're using the delegate pseudo or not, e.currentTarget will always refer to your custom element:

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
    }
  }
});

Remember, this is a standard API for accessing the element an event listener was attached to, more here: https://developer.mozilla.org/en-US/docs/Web/API/Event/currentTarget

The best approach to this problem, after dealing with it for several months, is to create another "pseudo", similar to the :delegate() pseudo, but that calls the callback differently. This adds the :descendant() pseudo to 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;
    }
};

You would use this exactly as you would :delegate() , but this will reference an object which will in turn reference the target element (the element matching the CSS selector eg button.close ), the origin (the element that received the event), and the component (the custom element itself). Usage example:

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(); 
        }
    }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM