onclick non rilevato dall'elemento personalizzato

Oct 04 2020

Sto definendo un elemento personalizzato

customElements.define("my-button", class extends HTMLButtonElement {
  onclick() {
    console.log("bar");
  }
}, { extends: "button" })

https://jsfiddle.net/tuxkjp3q/

Ma quando lo clicco non succede nulla.

Perché e come posso collegare gestori di eventi a ciascuna istanza della classe senza sovrascrivere il costruttore?

Modificare:

Quando controllo l'oggetto DOM c'è un gestore onclick, ma non funziona. Questo è confusionario

Modifica 2:

Ulteriori scoperte, se omesse dal prototipo, la definizione di un gestore funziona

customElements.define("my-button", class extends HTMLButtonElement {
  constructor() {
    super();
    this.onclick = () => console.log("bar");
  }
}, { extends: "button" })

Ma quando il prototipo contiene onclick, lo stesso gestore non funziona più

customElements.define("my-button", class extends HTMLButtonElement {
  onclick() {
    console.log("bar");
  }

  constructor() {
    super();
    this.onclick = () => console.log("bar");
  }
}, { extends: "button" })

Sarei davvero felice se riusciamo a ottenere una spiegazione di questo fenomeno.

MODIFICA 3:

Ho escogitato un modo per aggirare, se qualcuno deve affrontare lo stesso problema. Probabilmente vale la pena notare che verranno allegati solo i gestori definiti nel prototipo diretto della classe istanziata, il che è positivo per le prestazioni ma probabilmente logica difettosa. In ogni caso potrebbe essere adattato alle tue esigenze.

// Only in the base class
constructor() {
  super();

  for (let prop of Object.getOwnPropertyNames(this.constructor.prototype)) {
    if (prop.indexOf("on") === 0) {
      this.addEventListener(prop.substring(2).toLowerCase(), this.constructor.prototype[prop]);
    }
  }
}

Sono ancora molto interessato a scoprire il motivo di ciò.

Risposte

3 DerekMenénedez Oct 04 2020 at 08:50

Il problema è che devi definire l'ascoltatore di clic ... non la funzione su clic

class CustomButton extends HTMLButtonElement  {
  constructor() {
    super();

    this.addEventListener('click', () => {
      console.log('clicked');
    });
  }
}

customElements.define('custom-button', CustomButton, { extends: "button" });

html

<button is="custom-button">
  Hi
</button>
ScottMarcus Oct 04 2020 at 23:43

Tutto ciò che hai fatto è creare una onclickproprietà per il tuo elemento personalizzato e assegnargli una funzione. Solo perché ha un nome onclicknon significa intrinsecamente che il sistema sappia che è un clickevento perché stai creando il tuo elemento. Dovrai creare un evento personalizzato per il tuo elemento personalizzato.

Danny'365CSI'Engelman Nov 15 2020 at 17:31

Il tuo sono molto schietto nel collegare tutti i gestori che iniziano con il

Indovina quanti potrebbero essere:

document.body.append(
  ...Object.getOwnPropertyNames(window).filter(prop => prop.indexOf("on") === 0)
  .map((prop, idx, arr) => {
    let div = document.createElement("div");
    div.innerHTML = `${arr.length-idx} &nbsp; ${prop}`;
    return div;
  }));

Non devi usare addEventListener;

L'utilizzo del ( vecchio ) this.onclick=gestore in Components può essere più flessibile,
perché l'utente del Component può facilmente sovrascriverlo.
Con addEventListenerl' autore del componente deve fornire un removeListenermetodo; altrimenti l'utente non può rimuovere un listener.

Informazioni sui diversi modelli di eventi JavaScript:

  • https://www.quirksmode.org/js/events_tradmod.html