欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一文詳解JavaScript的事件監(jiān)聽(最新整理)

 更新時間:2024年01月11日 16:50:36   作者:DustinWangq  
Web頁面需要經常和用戶之間進行交互,而交互的過程中我們可能想要捕捉這個交互的過程,比如用戶點擊了某個按鈕、用戶在輸入框里面輸入了某個文本、用戶鼠標經過了某個位置,下面介紹下JavaScript的事件監(jiān)聽,感興趣的朋友一起看看吧

一、認識事件處理

1.認識事件

Web頁面需要經常和用戶之間進行交互,而交互的過程中我們可能想要捕捉這個交互的過程:

  • 比如用戶點擊了某個按鈕、用戶在輸入框里面輸入了某個文本、用戶鼠標經過了某個位置;
  • 瀏覽器需要搭建一條JavaScript代碼和事件之間的橋梁
  • 當某個事件發(fā)生時,讓JavaScript可以響應(執(zhí)行某個函數(shù)),所以我們需要針對事件編寫處理程序(handler);

如何進行事件監(jiān)聽呢?

  • 事件監(jiān)聽方式一:在script中直接監(jiān)聽(很少使用);
  • 事件監(jiān)聽方式二:DOM屬性,通過元素的on來監(jiān)聽事件;
  • 事件監(jiān)聽方式三:通過EventTarget中的addEventListener來監(jiān)聽;
<body>
  <!-- 監(jiān)聽方式一 script--> 
  <button onclick="alert('hello world');">nihao1</button>
  <button>nihao2</button>
  <button>nihao3</button>
  <script>
    // 監(jiān)聽方式二 on
    var btn2El = document.body.children[1];
    btn2El.onclick = function () {
      alert("監(jiān)聽方式2");
    }
    // 監(jiān)聽方式三 addListenEvent
    var btn3El = document.body.children[2];
    btn3El.addEventListener("click", function () {
      alert("監(jiān)聽方式3");
    })
</script>

2.常見的事件列表

鼠標事件:

  • click —— 當鼠標點擊一個元素時(觸摸屏設備會在點擊時生成)。
  • mouseover / mouseout —— 當鼠標指針移入/離開一個元素時。
  • mousedown / mouseup —— 當在元素上按下/釋放鼠標按鈕時。
  • mousemove —— 當鼠標移動時。

鍵盤事件:

  • keydown 和 keyup —— 當按下和松開一個按鍵時。

表單(form)元素事件:

  • submit —— 當訪問者提交了一個<form> 時。
  • focus —— 當訪問者聚焦于一個元素時,例如聚焦于一個<input> 。

Document 事件:

  • DOMContentLoaded —— 當 HTML 的加載和處理均完成,DOM 被完全構建完成時。

CSS 事件:

  • transitionend —— 當一個 CSS 動畫完成時。

二、事件冒泡捕獲

1.認識事件流

事實上對于事件有一個概念叫做事件流,為什么會產生事件流呢?

  • 我們可以想到一個問題:當我們在瀏覽器上對著一個元素點擊時,你點擊的不僅僅是這個元素本身
  • 這是因為我們的HTML元素是存在父子元素疊加層級的;
  • 比如一個span元素是放在div元素上的,div元素是放在body元素上的,body元素是放在html元素上的;
<div class="box">
    <span class="word">哈哈哈哈</span>
</div>
// 認識事件流
var boxEl = document.querySelector(".box");
var wordEl = document.querySelector(".word");
boxEl.addEventListener("click", function() {
    console.log("boxboxbox");
})
wordEl.addEventListener("click", function () {
    console.log("wordwordword");
})

2.事件冒泡和事件捕獲

我們會發(fā)現(xiàn)默認情況下事件是從最內層的span向外依次傳遞的順序,這個順序我們稱之為事件冒泡(Event Bubble);

事實上,還有另外一種監(jiān)聽事件流的方式就是從外層到內層(body -> span),這種稱之為事件捕獲(Event Capture);

為什么會產生兩種不同的處理流呢?

  • 這是因為早期瀏覽器開發(fā)時,不管是IE還是Netscape公司都發(fā)現(xiàn)了這個問題;
  • 但是他們采用了完全相反的事件流來對事件進行了傳遞;
  • IE采用了事件冒泡的方式,Netscape采用了事件捕獲的方式;

那么我們如何去監(jiān)聽事件捕獲的過程呢?

3.事件捕獲和冒泡的過程

如果我們都監(jiān)聽,那么會按照如下順序來執(zhí)行:

  • 捕獲階段(Capturing phase):

事件(從 Window)向下走近元素。

  • 目標階段(Target phase):

事件到達目標元素。

  • 冒泡階段(Bubbling phase):

事件從元素上開始冒泡。

事實上,我們可以通過event對象來獲取當前的階段:

  • eventPhase

開發(fā)中通常會使用事件冒泡,所以事件捕獲了解即可。

// 默認情況下是事件冒泡
spanEl.addEventListener("click", function() {
    console.log("span元素發(fā)生了點擊~冒泡")
})
divEl.addEventListener("click", function() {
    console.log("div元素發(fā)生了點擊~冒泡")
})
bodyEl.addEventListener("click", function() {
    console.log("body元素發(fā)生了點擊~冒泡")
})
// 設置希望監(jiān)聽事件捕獲的過程
spanEl.addEventListener("click", function() {
    console.log("span元素發(fā)生了點擊~捕獲")
}, true)
divEl.addEventListener("click", function() {
    console.log("div元素發(fā)生了點擊~捕獲")
}, true)
bodyEl.addEventListener("click", function() {
    console.log("body元素發(fā)生了點擊~捕獲")
}, true)

三、事件對象event

1.事件對象

當一個事件發(fā)生時,就會有和這個事件相關的很多信息:

  • 比如事件的類型是什么,你點擊的是哪一個元素點擊的位置是哪里等等相關的信息;
  • 那么這些信息會被封裝到一個Event對象中,這個對象由瀏覽器創(chuàng)建,稱之為event對象;
  • 該對象給我們提供了想要的一些屬性,以及可以通過該對象進行某些操作;

如何獲取這個event對象呢?

  • event對象會在傳入的事件處理(event handler)函數(shù)回調時,被系統(tǒng)傳入;
  • 我們可以在回調函數(shù)中拿到這個event對象;

這個對象中都有哪些常見的屬性和操作呢?

2.event常見的屬性和方法

常見的屬性:

  • type:事件的類型;
  • target:當前事件發(fā)生的元素;
  • currentTarget:當前處理事件的元素;
  • eventPhase:事件所處的階段;
  • offsetX、offsetY:事件發(fā)生在元素內的位置;
  • clientX、clientY:事件發(fā)生在客戶端內的位置;
  • pageX、pageY:事件發(fā)生在客戶端相對于document的位置;
  • screenX、screenY:事件發(fā)生相對于屏幕的位置;

常見的方法:

  • preventDefault:取消事件的默認行為;
  • stopPropagation:阻止事件的進一步傳遞(冒泡或者捕獲都可以阻止);
// 認識事件流
var boxEl = document.querySelector(".box");
var wordEl = document.querySelector(".word");
// 事件冒泡
wordEl.addEventListener("click", function (event) {
    console.log("word冒泡", event.target, event.currentTarget);
    console.log(event.type);//click
    console.log(event.eventPhase);//2
})
wordEl.addEventListener("click", function (event) {
    console.log("word捕獲", event.target, event.currentTarget);
    console.log(event.type);//click
    console.log(event.eventPhase);//2
}, true)
boxEl.addEventListener("click", function (event) {
    console.log("box捕獲", event.target, event.currentTarget);
    console.log(event.type);//click
    console.log(event.eventPhase);//1
}, true)
document.body.addEventListener("click", function (event) {
    console.log("body捕獲", event.target, event.currentTarget);
    console.log(event.type);//click
    console.log(event.eventPhase);//1
    // 停止傳遞
    // event.stopPropagation();
}, true)
var aEl = document.querySelector("a");
console.log(aEl);
console.log(aEl.href);
aEl.addEventListener("click", function (event) {
    console.log("a標簽冒泡");
    // 阻止默認行為:比如a標簽的跳轉
    event.preventDefault();
})

3.事件處理中的this

在函數(shù)中,我們也可以通過this來獲取當前的發(fā)生元素:

divEl.onclick = function(event) {
    console.log(this)
    console.log(event.currentTarget)
    console.log(divEl)
    console.log(this === divEl)
}

這是因為在瀏覽器內部,調用event handler是綁定到當前的target上的

四、EventTarget使用

1.EventTarget類

我們會發(fā)現(xiàn),所有的節(jié)點、元素都繼承自EventTarget

  • 事實上Window也繼承自EventTarget;

那么這個EventTarget是什么呢?

  • EventTarget是一個DOM接口,主要用于添加、刪除、派發(fā)Event事件;

EventTarget常見的方法:

  • addEventListener:注冊某個事件類型以及事件處理函數(shù);
  • removeEventListener:移除某個事件類型以及事件處理函數(shù);
  • dispatchEvent:派發(fā)某個事件類型到EventTarget上;
var btnEl = document.querySelector("button")
// 1.將監(jiān)聽函數(shù)移除的過程
// var foo = function() {
//   console.log("監(jiān)聽到按鈕的點擊")
// }
// btnEl.addEventListener("click", foo)
// // 需求: 過5s鐘后, 將這個事件監(jiān)聽移除掉
// setTimeout(function() {
//   btnEl.removeEventListener("click", foo)
// }, 5000)
// 這種做法是無法移除的
btnEl.addEventListener("click", function() {
    console.log("btn監(jiān)聽的處理函數(shù)~")
})
setTimeout(function() {
    btnEl.removeEventListener("click", function() {})
}, 5000)
// 派發(fā)事件
setTimeout(() => {
    // 3秒后觸發(fā)點擊事件
    btnEl.dispatchEvent(new Event("click"));
}, 3000);

五、事件委托模式

1.事件委托

事件冒泡在某種情況下可以幫助我們實現(xiàn)強大的事件處理模式 – 事件委托模式(也是一種設計模式)

那么這個模式是怎么樣的呢?

  • 因為當子元素被點擊時,父元素可以通過冒泡可以監(jiān)聽到子元素的點擊;
  • 并且可以通過event.target獲取到當前監(jiān)聽的元素;

案例:一個ul中存放多個li,點擊某一個li會變成紅色

  • 方案一:監(jiān)聽每一個li的點擊,并且做出相應;
  • 方案二:在ul中監(jiān)聽點擊,并且通過event.target拿到對應的li進行處理;
    • 因為這種方案并不需要遍歷后給每一個li上添加事件監(jiān)聽,所以它更加高效;
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    ul,li {
      list-style: none;
      margin: 0;
      padding: 0;
    }
    .item {
      display: inline-block;
      padding: 20px;
    }
    .active {
      background-color: yellow;
      color: blue;
    }
  </style>
</head>
<body>
  <ul>
    <li class="item">吃飯睡覺打豆豆</li>
    <li class="item">吃飯睡覺打豆豆</li>
    <li class="item">吃飯睡覺打豆豆</li>
    <li class="item">吃飯睡覺打豆豆</li>
    <li class="item">吃飯睡覺打豆豆</li>
  </ul>
  <script>
    var ulEl = document.querySelector("ul");
    ulEl.addEventListener("click", function (event) {
      // 委托模式
      // 獲取觸發(fā)事件的元素
      event.target.classList.toggle("active");
    })
  </script>
</body>
</html>

2.事件委托的標記

某些事件委托可能需要對具體的子組件進行區(qū)分,這個時候我們可以使用data-*對其進行標記:

比如多個按鈕的點擊,區(qū)分點擊了哪一個按鈕:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div class="box">
    <button data-action="search">搜索~</button>
    <button data-action="new">新建~</button>
    <button data-action="remove">移除~</button>
    <button>1111</button>
  </div>
  <script>
    var boxEl = document.querySelector(".box")
    boxEl.onclick = function(event) {
      var btnEl = event.target
      var action = btnEl.dataset.action
      switch (action) {
        case "remove":
          console.log("點擊了移除按鈕")
          break
        case "new":
          console.log("點擊了新建按鈕")
          break
        case "search":
          console.log("點擊了搜索按鈕")
          break
        default:
          console.log("點擊了其他")
      }
    }
  </script>
</body>
</html>

六、常見的事件

1.常見的鼠標事件

接下來我們來看一下常見的鼠標事件(不僅僅是鼠標設備,也包括模擬鼠標的設備,比如手機、平板電腦)

常見的鼠標事件:

1.1 mouseover和mouseenter的區(qū)別

mouseenter和mouseleave

  • 不支持冒泡
  • 進入子元素依然屬于在該元素內,沒有任何反應

mouseover和mouseout

  • 支持冒泡
  • 進入元素的子元素時
    • 先調用父元素的mouseout
    • 再調用子元素的mouseover
    • 因為支持冒泡,所以會將mouseover傳遞到父元素中;
var boxEl = document.querySelector(".box");
var containerEl = document.querySelector(".container");
// mouseenter mouseleave
// containerEl.addEventListener("mouseenter", function (event) {
//   console.log("鼠標進來拉")
// })
// containerEl.addEventListener("mouseleave", function (event) {
//   console.log("鼠標離開拉")
// })
// mouseover mouseout
containerEl.addEventListener("mouseover", function (event) {
    console.log("鼠標進來拉")
})
containerEl.addEventListener("mouseout", function (event) {
    console.log("鼠標離開拉")
})

2.常見的鍵盤事件

常見的鍵盤事件:

事件的執(zhí)行順序是 onkeydown、onkeypress、onkeyup

  • down事件先發(fā)生;
  • press發(fā)生在文本被輸入;
  • up發(fā)生在文本輸入完成;

我們可以通過key和code來區(qū)分按下的鍵:

  • code:“按鍵代碼”(“KeyA”,“ArrowLeft” 等),特定于鍵盤上按鍵的物理位置。
  • key:字符(“A”,“a” 等),對于非字符(non-character)的按鍵,通常具有與 code 相同的值。
var inputEl = document.querySelector("input")
var btnEl = document.querySelector("button")
// inputEl.onkeydown = function() {
//   console.log("onkeydown")
// }
// inputEl.onkeypress = function() {
//   console.log("onkeypress")
// }
// inputEl.onkeyup = function(event) {
//   console.log(event.key, event.code)
// }
// 1.搜索功能
btnEl.onclick = function() {
    console.log("進行搜索功能", inputEl.value)
}
inputEl.onkeyup = function(event) {
    if (event.code === "Enter") {
        console.log("進行搜索功能", inputEl.value)
    }
}
// 2.按下s的時候, 搜索自動獲取焦點
document.onkeyup = function(event) {
    if (event.code === "KeyS") {
        inputEl.focus()
    }
}

3.常見的表單事件

針對表單也有常見的事件:

var inputEl = document.querySelector("input")
// 1.獲取焦點和失去焦點
// inputEl.onfocus = function() {
//   console.log("input獲取到了焦點")
// }
// inputEl.onblur = function() {
//   console.log("input失去到了焦點")
// }
// 2.內容發(fā)生改變/輸入內容
// 輸入的過程: input
// 內容確定發(fā)生改變(離開): change
// inputEl.oninput = function() {
//   console.log("input事件正在輸入內容", inputEl.value)
// }
// inputEl.onchange = function() {
//   console.log("change事件內容發(fā)生改變", inputEl.value)
// }
// 3.監(jiān)聽重置和提交
var formEl = document.querySelector("form")
formEl.onreset = function(event) {
    console.log("發(fā)生了重置事件")
    event.preventDefault()
}
formEl.onsubmit = function(event) {
    console.log("發(fā)生了提交事件")
    // axios庫提交
    event.preventDefault()
}

4.文檔加載事件

DOMContentLoaded:瀏覽器已完全加載 HTML,并構建了 DOM 樹,但像<img> 和樣式表之類的外部資源可能尚未加載 完成。

load:瀏覽器不僅加載完成了 HTML,還加載完成了所有外部資源:圖片,樣式等。

// 注冊事件監(jiān)聽
window.addEventListener("DOMContentLoaded", function() {
    // 1.這里可以操作box, box已經加載完畢
    // var boxEl = document.querySelector(".box")
    // boxEl.style.backgroundColor = "orange"
    // console.log("HTML內容加載完畢")
    // 2.獲取img對應的圖片的寬度和高度
    var imgEl = document.querySelector("img")
    console.log("圖片的寬度和高度:", imgEl.offsetWidth, imgEl.offsetHeight)
})
window.onload = function() {
    console.log("文檔中所有資源都加載完畢")
    // var imgEl = document.querySelector("img")
    // console.log("圖片的寬度和高度:", imgEl.offsetWidth, imgEl.offsetHeight)
}
window.onresize = function() {
    console.log("創(chuàng)建大小發(fā)生改變時")
}

事件類型:https://developer.mozilla.org/zh-CN/docs/Web/Events

到此這篇關于JavaScript的事件監(jiān)聽的文章就介紹到這了,更多相關JavaScript的事件監(jiān)聽內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論