点击每个li输出里面的内容(前端很常问的面试题之一)
点击每个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的元素也会执行这个代码。
好了,这个简单的题目就讲解到这里了,不同的面试对这道题会有一定程度的改变,不过只要理解了相关的知识就不怕应付千变万化啦~