Search code examples
javascriptfirefoxdom-eventsshadow-domcustom-element

FireFox/Safari Event target vs current target in shadow DOM


I have seen many seemingly similar (Firefox + Event Target) questions but not dealing with my paticular issue.

Basically, everything I have read here and in reference docs states that the target is where the event/click occured and current target is where the Event Listener was registered.

Either way, I've been using Event.Target to tell me "What was clicked" for a long time (srcElement before that) and event.target with the Shadow DOM Chrome comes up trumps.

Take this example line#119 in toggle.js the e.target.tagName is "LABEL" in Chrome but "ABC-TOGGLE" in FireFox and I assume Safari.

Now, as those of you who have handle clicks on LABELs know, that event bubbles up with the checkbox state as it was when the click occured (and should be ignored) and then bubbles through a click event on the checkbox with the updated/new checkbox state with a tagName of INPUT. I let that input bubble up to the light DOM where the target gets converted to ABC-TOGGLE and everyone is happy! Except FireFox and Safari :-(

Anyway it appears that "currentTarget" in FireFox is what I'm looking for.

Is this what other web-component / custom-element developers are using? Standards?


Solution

  • Ok, FireFox (and according to caniuse.com, ONLY FireFox) uses something called originalTarget: -

        this.#toggle.addEventListener('click', (e) => {
                var trueTarget = null;
                switch  (true) {
                    case    (e.target.tagName == "INPUT"):
                            trueTarget = e.target;
                            break;
                    case    (e.currentTarget.tagName == "INPUT"):
                            trueTarget = e.currentTarget;
                            break;
                    case    (e.originalTarget != undefined && e.originalTarget.tagName == "INPUT"):
                            trueTarget = e.originalTarget;
                            break;
                    default:
                }
    
                if (trueTarget == null) {
                    e.stopPropagation();
                    return;
                }
                
                console.log("Inside " + this.#checkbox.checked + " " + trueTarget.tagName);
    
                this.setAttribute("checked", this.#checkbox.checked);
                this.setAttribute("aria-checked", this.#checkbox.checked);
            })
    

    The first CASE handles Chrome, Edge, and Opera. The third case handles FireFox. And I'm pinning my hopes on the first or second CASE clause working in Safari.

    Don't know if Safari morphs the event.type from CLICK to INPUT like FF but we'll see.