點擊每個li輸出里面的內容(前端很常問的面試題之一)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>click事件的幾種寫法</title>
</head>
<body>
<ul id="parent">
<li>第1個</li>
<li>第2個</li>
<li>第3個</li>
<li>第4個</li>
<li>第5個</li>
<li>第6個</li>
<li>第7個</li>
</ul>
<script> var ul = document.getElementById('parent'); var li = ul.getElementsByTagName('li'); </script>
</body>
</html>
這是一道很常見的前端面試題,讓你點擊每個li輸出里面相應的內容,今天就來給大家放上我最常用的三種方法,並解釋里面用到的知識點~
第一種
function Closure() {
for(var i = 0; i < li.length; i++) {
(function(j){
li[j].onclick = function() {
console.log(li[j].innerHTML);
}
})(i);
}
}
第一種方法是使用吃掉閉包的方法,因為onclick的異步執行導致只能輸出第li.length
個li內部的文字,但因為並沒有第li.length
個li所以代碼並不會輸出(可以去掉代碼內部的立即執行函數進行實驗)。加入立即執行函數就延長了click事件的活動對象,強制使代碼符合預期。
關於閉包
第二種
function This() {
for(var j = 0; j < li.length; j++) {
li[j].onclick = function() {
console.log(this.innerHTML);
}
}
}
第二種方法是使用this的原理,因為對於this的隱式綁定來說,this
指向的是調用位置上的包含對象,也就是你點擊的那個li[i]
。通過this的指向就可以輕松得到我們想要的答案了~
關於this
第三種
function eve() {
ul.onclick = function(eve) {
if(eve.target.tagName.toLowerCase() === 'li') {
console.log(eve.target.innerHTML);
}
}
}
第三種使用的是事件代理以及event事件的內置屬性來達到效果。事件代理不必再細說了,就是因為瀏覽器的事件冒泡機制將事件綁定在發生事件的上級元素上。因為event
事件有很多屬性及方法,在這里插播列舉一下這些方法吧
屬性/方法 | 類型 | 說明 |
---|---|---|
bubbles | Boolean | 表示事件是否冒泡 |
cancelable | Boolean | 表示是否可以取消事件的默認行為 |
currentTarget | Element | 表示事件處理程序當前正在處理的那個元素 |
defaultPrevented | Boolean | 為true表示已調用了preventDefault() |
detail | Integer | 與事件相關的細節信息 |
eventPhase | Integer | 調用事件處理程序的階段:1表示捕獲階段,2表示‘處於目標’,3表示冒泡階段 |
preventDefault() | Function | 取消事件的默認行為 |
stopImmediatePropagation() | Function | 取消事件的進一步捕獲或者冒泡,同時阻止任何事件處理程序被調用 |
stopPropagation() | Function | 取消事件的進一步捕獲或者冒泡 |
target | Element | 事件的目標元素 |
trusted | Boolean | 為true表示事件是瀏覽器生成的,為false表示事件由開發人員通過JavaScript創建的 |
type | String | 被觸發事件的類型 |
view | AbstractView | 與事件相關的抽象視圖 |
在這個需求中我們只需要使用eve.target
這個屬性就能獲得你點擊的目標元素。if的判斷是避免綁定事件的元素下級還有其他不是li的元素也會執行這個代碼。
好了,這個簡單的題目就講解到這里了,不同的面試對這道題會有一定程度的改變,不過只要理解了相關的知識就不怕應付千變萬化啦~