2017-10-14 7 views
1

Dies ist ein Problem, das ich mit oninput und onchange auch habe.Wie überschreibe ich onclick-Ereignis für ein benutzerdefiniertes html-Element, so dass es nur löst, wenn ich es frage?

Im folgenden Beispiel möchte ich das Onclick des benutzerdefinierten Elements nur aktivieren können, wenn auf die interne Schaltfläche geklickt wird.

https://jsfiddle.net/xk5w95gf/

class TestElm extends HTMLElement { 
    constructor() { 
     super(); 
     this._value = null 
     this._box 
     this._button 
    } 

    connectedCallback(){ 

     this._box = document.createElement("div") 
     this._button = document.createElement("button") 
     this._box.style.height = "200px" 
     this._box.style.background = "green" 
     this._button.innerHTML = "Only clicking this should trigger the outside onclick" 
     this.appendChild(this._box) 
     this._box.appendChild(this._button) 

     this._button.onclick =() => this.dispatchEvent(new MouseEvent("click", { 
      bubbles: true, 
      cancelable: true 
     })) 
    } 
} 

customElements.define('test-elm', TestElm); 

Gerade jetzt, die Onclick Feuer für jede Onclick, mit Klick auf den Button zweimal

<test-elm id="myelm" onclick="console.log('clicked button')"></test-elm> 

Antwort

1

Brennen Ich hatte gerade die Ausbreitung des verschachtelten Elements zu stoppen, in der über obigen Fall musste ich nur das _box Element hinzufügen:

this._box.onclick = (event) => event.stopPropagation() 
+0

Während dies dies funktionieren wird geht auch gegen die übliche Weise Ereignisse Blase. Solange es Ihnen nichts ausmacht, sollte Ihre Lösung gut funktionieren. Aber mit einer Web-Komponente können Sie das 'click'-Ereignis erfassen und immer zulassen. Wenn der Klick auf der Schaltfläche erfolgt, senden Sie ein zusätzliches Ereignis, um die Außenwelt über diese bestimmte Aktion zu informieren. – Intervalia

0

Heres eine Arbeits jsFiddle: https://jsfiddle.net/xk5w95gf/20/

console.clear() 

class TestElm extends HTMLElement { 
    constructor() { 
     super(); 
     this._value = null 
     this._box 
     this._button 
    } 

    connectedCallback(){ 

     this._box = document.createElement("div") 
     this._button = document.createElement("button") 
     this._box.style.height = "200px" 
     this._box.style.background = "green" 
     this._button.innerHTML = "Only clicking this should trigger the outside onclick" 
     this.appendChild(this._box) 
     this._box.appendChild(this._button) 


     /* 
      There is no need to dispatch a `click` event on `this` 
      because `this._button` is a descendant of `this`, the event bubbles up the DOM tree to `this` regardless 

     this._button.onclick =() => this.dispatchEvent(new MouseEvent("click", { 
      bubbles: true, 
      cancelable: true 
     })) 

     */ 



     /* Instead we can prevent subsequent `click` event listners from executing 
      IF `this._button` IS NOT the `event.target 

      Using `this.onclick = ` vs `addEventListener()` ensurs that it IS THE FIRST executing listener. 

      NOTE: a simple setter like `testElmNode.onclick = newVal` will overwrite this logic. 
       USE: `addEventListener()` while building your application 
     `*/ 
     this.onclick = (event) => { 
      if (event.target !== this._button) { 
      event.stopImmediatePropagation(); 
      event.preventDefault(); 
      event.returnValue = false; 


      console.log('Not the button though..'); 
      } 
     }; 
    } 
} 

customElements.define('test-elm', TestElm); 
const myelm = document.getElementById("myelm") 

myelm.addEventListener('click',() => console.log('clicked button')); 
Verwandte Themen