onclick non rilevato dall'elemento personalizzato
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
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>
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.
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} ${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