2017-10-14 52 views
1

這是我遇到的oninputonchange的問題。如何覆蓋自定義html元素的onclick事件,以便在我詢問時才發送?

在下面的例子中,我希望能夠讓自定義元素的onclick僅在內部按鈕被點擊時觸發。

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

眼下,的onclick火災任何的onclick,與點擊按鈕開火兩次

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

回答

1

我不得不停止嵌套元素的傳播,在以上情況我只需要將其添加到_box元素中:

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

雖然這會工作,這也違背了標準的方式對事件泡沫。只要你不介意,你的解決方案應該很好。但是,對於Web組件,您可以捕獲「click」事件並始終允許它通過,如果點擊發生在按鈕上,則發送額外事件以讓外部世界知道該特定操作。 – Intervalia

0

繼承人工作的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'));