event.preventDefault()、event.stopPropagation()、event.stopImmediatePropagation()思考

event.preventDefault()

MDN解釋:

Event 接口的 preventDefault()方法,告訴user agent:如果此事件沒有被顯式處理,它默認的動作也不應該照常執行。此事件還是繼續傳播,除非碰到事件偵聽器調用stopPropagation() 或stopImmediatePropagation(),才停止傳播。

個人理解:

事件後續動作別執行了,如submit觸發函數加這麼一句,就是別提交表單了,input的keydown事件觸發函數加這麼一句,就是別輸入到文本框裏面了。

<body>
<input type="text" οnkeydοwn="test(event)"/>
<a href="http://www.baidu.com" οnclick="test(event)">to baidu</a>
</body>
<script type="text/javascript">
      function test(e) {
        console.log("默認的動作不照常執行");
        e.preventDefault();
      }
</script>

在文本框輸入,或點擊超鏈接

 

stopPropagation、stopImmediatePropagation

因爲有事件的冒泡和捕獲,所以會有需要阻止的情況出現吧。(真是廢話來的 - _ -,總之得先弄白冒泡和捕獲吧。https://blog.csdn.net/qq_28842789/article/details/105975205

event.stopPropagation()

MDN解釋:

阻止捕獲和冒泡階段中當前事件的進一步傳播。

<body οnlοad="load();">
<div id="d1" style="width: 400px; height: 400px; border: solid 1px;">
    <div id="d2" style="width: 200px; height: 200px; border: solid 1px;">
        <div id="d3" style="width: 100px; height: 100px; border: solid 1px;">one</div>
    </div>
</div>
</body>

栗子1(冒泡階段的阻斷)

<script type="text/javascript">
      function load() {
        div1 = document.getElementById("d1");
        div2 = document.getElementById("d2");
        div3 = document.getElementById("d3");
        
        div1.addEventListener("click", (e) => {
          console.log("div1被點擊,監聽觸發於捕獲階段");
        }, true);
        div2.addEventListener("click", (e) => {
          console.log("div2被點擊,監聽觸發於捕獲階段");
        }, true);
        div3.addEventListener("click", (e) => {
          console.log("div3被點擊,監聽觸發於捕獲階段");
        }, true);

        div1.addEventListener("click", (e) => {
          console.log("div1被點擊,監聽觸發於冒泡階段");
        }, false);
        div2.addEventListener("click", (e) => {
          console.log("div2被點擊,監聽觸發於冒泡階段");
          e.stopPropagation();
        }, false);
        div3.addEventListener("click", (e) => {
          console.log("div3被點擊,監聽觸發於冒泡階段");
        }, false);
        
      }
    </script>

點擊 d3 div 結果:捕獲全部執行完,冒泡到div2時,最後一個div1的冒泡被阻止

栗子2(捕獲階段的阻斷)

<script type="text/javascript">
      function load() {
        div1 = document.getElementById("d1");
        div2 = document.getElementById("d2");
        div3 = document.getElementById("d3");

        div1.addEventListener("click", (e) => {
          console.log("div1被點擊,監聽觸發於捕獲階段");
        }, true);
        div2.addEventListener("click", (e) => {
          console.log("div2被點擊,監聽觸發於捕獲階段");
          e.stopPropagation();
        }, true);
        div3.addEventListener("click", (e) => {
          console.log("div3被點擊,監聽觸發於捕獲階段");
        }, true);

        div1.addEventListener("click", (e) => {
          console.log("div1被點擊,監聽觸發於冒泡階段");
        }, false);
        div2.addEventListener("click", (e) => {
          console.log("div2被點擊,監聽觸發於冒泡階段");
        }, false);
        div3.addEventListener("click", (e) => {
          console.log("div3被點擊,監聽觸發於冒泡階段");
        }, false);

      }
</script>

點擊 d3 div 結果:執行到div2的捕獲函數時,直接阻斷了後面所有沒執行的捕獲和冒泡函數

event.stopImmediatePropagation()

MDN解釋:

阻止事件冒泡並且阻止相同事件的其他偵聽器被調用。(可能翻譯不靠譜,其實在捕獲階段調用且後面的元素還有捕獲函數,也不會執行了,個人理解:stopImmediatePropagation=stopPropagation+阻斷目標元素其他未執行的同一事件監聽函數)

<body οnlοad="load();">
<div id="d1" style="width: 400px; height: 400px; border: solid 1px;">
    <div id="d2" style="width: 200px; height: 200px; border: solid 1px;">
        <div id="d3" style="width: 100px; height: 100px; border: solid 1px;">one</div>
    </div>
</div>
</body>

栗子1(冒泡階段的阻斷)

<script type="text/javascript">
      function load() {
        div1 = document.getElementById("d1");
        div2 = document.getElementById("d2");
        div3 = document.getElementById("d3");

        div1.addEventListener("click", (e) => {
          console.log("div1被點擊,監聽觸發於捕獲階段");
        }, true);
        div2.addEventListener("click", (e) => {
          console.log("div2被點擊,監聽觸發於捕獲階段");
        }, true);
        div3.addEventListener("click", (e) => {
          console.log("div3被點擊,監聽觸發於捕獲階段");
        }, true);

        div1.addEventListener("click", (e) => {
          console.log("div1被點擊,監聽觸發於冒泡階段");
        }, false);
        div2.addEventListener("click", (e) => {
          console.log("div2被點擊,監聽觸發於冒泡階段, 第1個監聽函數");
        }, false);
        div2.addEventListener("click", (e) => {
          console.log("div2被點擊,監聽觸發於冒泡階段, 第2個監聽函數");
          e.stopImmediatePropagation();
        }, false);
        div2.addEventListener("click", (e) => {
          console.log("div2被點擊,監聽觸發於冒泡階段, 第3個監聽函數");
        }, false);
        div3.addEventListener("click", (e) => {
          console.log("div3被點擊,監聽觸發於冒泡階段");
        }, false);

      }
    </script>

 點擊 d3 div 結果:

栗子2(捕獲階段的阻斷)

<script type="text/javascript">
      function load() {
        div1 = document.getElementById("d1");
        div2 = document.getElementById("d2");
        div3 = document.getElementById("d3");

        div1.addEventListener("click", (e) => {
          console.log("div1被點擊,監聽觸發於捕獲階段");
        }, true);
        div2.addEventListener("click", (e) => {
          console.log("div2被點擊,監聽觸發於捕獲階段, 第1個監聽函數");
        }, true);
        div2.addEventListener("click", (e) => {
          console.log("div2被點擊,監聽觸發於捕獲階段, 第2個監聽函數");
          e.stopImmediatePropagation();
        }, true);
        div2.addEventListener("click", (e) => {
          console.log("div2被點擊,監聽觸發於捕獲階段, 第3個監聽函數");
        }, true);
        div3.addEventListener("click", (e) => {
          console.log("div3被點擊,監聽觸發於捕獲階段");
        }, true);

        div1.addEventListener("click", (e) => {
          console.log("div1被點擊,監聽觸發於冒泡階段");
        }, false);
        div2.addEventListener("click", (e) => {
          console.log("div2被點擊,監聽觸發於冒泡階段");
        }, false);
        div3.addEventListener("click", (e) => {
          console.log("div3被點擊,監聽觸發於冒泡階段");
        }, false);

      }
    </script>

點擊 d3 div 結果:一元素對同一事件的多個監聽函數,按代碼順序執行,執行到div2的第二個監聽函數,阻止了後面的函數執行。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章