<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                addEventListener ~~~javascript target.addEventListener(type, listener[, options]); target.addEventListener(type, listener[, useCapture]); ~~~ ## **target.addEventListener(type, listener[, options]);** * options包括三個布爾值選項: * capture: 默認值為false(即 使用事件冒泡). 是否使用事件捕獲; * once: 默認值為false. 是否只調用一次,if true,會在調用后自動銷毀listener * passive: if true, 意味著listener永遠不遠調用preventDefault方法,如果又確實調用了的話,瀏覽器只會console一個warning,而不會真的去執行preventDefault方法。**根據規范,默認值為false. 但是chrome, Firefox等瀏覽器為了保證滾動時的性能,在document-level nodes(Window, Document, Document.body)上針對touchstart和touchmove事件將passive默認值改為了true**, 保證了在頁面滾動時不會因為自定義事件中調用了preventDefault而阻塞頁面渲染。 ## **target.addEventListener(type, listener[, useCapture]);** * useCapture: 默認值為false(即 使用事件冒泡)。 * true - 事件處理程序在捕獲階段執行 * false - 默認。 事件處理程序在冒泡階段執行 ## **DOM的事件傳播機制:** DOM事件流(event flow ): 存在三個階段:事件捕獲階段、處于目標階段、事件冒泡階段。 ## **事件冒泡(event capturing) :子傳父** 當一個元素接收到事件的時候 會把他接收到的事件傳給自己的父級,一直到window 。(注意這里傳遞的僅僅是事件 并不傳遞所綁定的事件函數。所以如果父級沒有綁定事件函數,就算傳遞了事件 也不會有什么表現 但事件確實傳遞了。) 就是事件向上傳導,當后代元素的事件被觸發時,其祖先元素的相同事件也會觸發 例子:點擊span,父元素也觸發了點擊事件 ~~~ <body style="width: 1000px;height: 1000px;"> <div id="info" style="width: 100px;height:100px;background-color: aquamarine;border:5px solid darkred;"> xxx<span id="s1" style="background-color: bisque;">xxx</span> </div> <script type="text/javascript"> window.onload=function(){ var info=document.getElementById("info"); var s1=document.getElementById("s1"); s1.onclick=function(event){ console.log("span單擊事件響應函數") } info.onclick=function(event){ console.log("div單擊事件響應函數") } document.body.onclick=function(event){ console.log("body單擊事件響應函數") } } </script> </body> ~~~ 結果: ~~~ span單擊事件響應函數 div單擊事件響應函數 body單擊事件響應函數 ~~~ 大部分事件冒泡是很有用的,如果不想事件冒泡可以通過事件對象取消事件冒泡 ~~~ <body style="width: 1000px;height: 1000px;"> <div id="info" style="width: 100px;height:100px;background-color: aquamarine;border:5px solid darkred;"> xxx <span id="s1" style="background-color: bisque;">xxx</span> </div> <script type="text/javascript"> window.onload=function(){ var info=document.getElementById("info"); var s1=document.getElementById("s1"); s1.onclick=function(event){ console.log("span單擊事件響應函數") event=event||window.event; event.cancelBubble=true; } info.onclick=function(event){ console.log("div單擊事件響應函數") } document.body.onclick=function(event){ console.log("body單擊事件響應函數") } } </script> </body> ~~~ 結果: ~~~ span單擊事件響應函數 ~~~ ## **事件捕獲(event capturing):父傳子** 當鼠標點擊或者觸發dom事件時,瀏覽器會從根節點開始由外到內進行事件傳播,即點擊了子元素,如果父元素通過事件捕獲方式注冊了對應的事件的話,會先觸發父元素綁定的事件 在DOM2級事件流中包含事件捕獲和事件冒泡兩個階段。 * 觸發事件處理程序時,先是進入事件捕獲階段,事件由外層向內層具體元素傳播; * 然后進入事件冒泡階段,由內層具體元素再向外層進行傳播,事件的處理默認是在冒泡階段。 事件捕獲是不能被阻止的,否則定位不到具體的元素。 ``` <div class="parent" onclick="handleParent()"> <div class="children1"> <div class="children2"></div> </div> </div> ``` 當點擊父元素parent時,事件進入捕獲階段: Document → html → body → div.parent → div.children1 → div.children2 然后進入冒泡近段并且執行處理方法: div.children2(觸發事件) → div.children1 (觸發事件) → div#parent(觸發事件) → body → html → Document ``` e.stopPropagation();//停止事件傳遞 e.cancelBubble = true;//取消冒泡 ``` 給父元素綁定事件,觸發事件event.target卻是子元素。若要拿綁定事件的初始元素,可用event.currentTarget 或者給子元素加上`pointer-events: none;`樣式 ## 關于event對象中的currentTarget屬性有時候為null這件事 ``` <div id="outer"> <div id="inner"></div> </div> //JavaScript document.getElementById('outer').addEventListener('click', function(event) { console.log('event.currentTarget:', event.currentTarget);//<div id=?"outer">?…?</div> console.log('event.target:', event.target);//<div id=?"inner">?</div> console.log('this:', this);//<div id=?"outer">?…?</div> 注意:若事件處理程序為箭頭函數,則this指向window(not strict)或為undefined('use strict') }); ``` 實際上,currentTarget這個屬性是一個實時值而不是快照,隨著事件冒泡階段的結束,它將被解引用,這就是它為null的原因。也就是說如果我們在事件處理程序中使用異步代碼訪問該屬性,就會發生這個問題 ``` document.getElementById('outer').addEventListener('click', function(event) { const ct = event.currentTarget; setTimeout(() => { console.log('event.currentTarget:', event.currentTarget)//null console.log('ct:', ct)//<div id=?"outer">?…?</div> }, 0); setTimeout(() => { console.log('event.target:', event.target)//<div id=?"inner">?</div> }, 0); setTimeout(() => { console.log('this:', this)//<div id=?"outer">?…?</div> }, 0); }); ``` #### 如何與removeEventListener 方法合作? removeEventListener的參數與addEventListener類似: > ~~~javascript > target.removeEventListener(type, listener[, options]); > target.removeEventListener(type, listener[, useCapture]); > > ~~~ 在移除之前添加的監聽事件時,很顯然需要傳入同樣的type和listener,那第三個參數options和useCapture呢? **只會檢查addEventListener的useCapture或options中的capture值。** 例如: > ~~~javascript > element.addEventListener("mousedown", handleMouseDown, { passive: true }); > element.removeEventListener("mousedown", handleMouseDown, { passive: true }); // Succeeds > element.removeEventListener("mousedown", handleMouseDown, { capture: false }); // Succeeds > element.removeEventListener("mousedown", handleMouseDown, { capture: true }); // Fails > element.removeEventListener("mousedown", handleMouseDown, { passive: false }); // Succeeds > element.removeEventListener("mousedown", handleMouseDown, false); // Succeeds > element.removeEventListener("mousedown", handleMouseDown, true); // Fails > > ~~~ #### 是否一定要與removeEventlister成對兒出現? 當DOM元素與事件擁有不同的生命周期時,倘若不remove掉eventListener就有可能導致內存泄漏(保留或增加了不必要的內存占用)。比如在單頁應用中,切換了頁面后,原組件已經卸載,但其注冊在document上的事件卻保留了下來,白白占用了內存空間。**所以removeEventlister與addEventListener成對兒出現是best practice,可以避免可能出現的內存泄漏問題。**
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看