事件对象是事件触发时关于事件的一些信息
事件源对象是事件对象里面的一部分,表示的是真正触发事件的那个对象
<br />
以下面这段代码为例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div>
<p>
<span></span>
</p>
</div>
</body>
<script>
var div = document.querySelector('div');
div.onclick=function(){
console.log(1);
};
</script>
</html>
上面这段代码中,点击事件前面的对象是div,然而在我点击span或者p的时候,真正触发这个事件的对象就不是div了,而是span或者p,那么如果html嵌套层数过多,那么如何去获取事件的源对象呢?
可以用如下的代码
div.onclick=function(ev){
console.log(ev.target);
}
此时
- 点击div(p和span以外的区域)的时候,控制台输出的结果为
<div>...</div>
- 点击p(span以外的区域)的时候,控制台输出出来的结果为
<p>...</p>
- 点击span的时候,控制台输出出来的结果为
<span>...</span>
事件的源对象可以利用事件对象.target
的方法来找到
它的作用机制是从html文档中一层一层的向下查找,直到找到最里层的那个触发事件的源对象
<br />
那么它主要应用在哪里呢?
我们可以来看一个例子:
有一个界面html结构如下
<body>
<ul></ul>
</body>
它里面的li都是动态添加进去的,我需要在点击里面的li的时候,获得当前li里面的内容,大部分人会这么去做
var lis=document.querySelectorAll('li');
document.body.innerHTML+='<li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li>'
for(var i=0;i<lis.length;i++){
lis[i].onclick=function(){
console.log(this.innerHTML);
};
};
在这里功能失效了,因为添加li的操作在获取li的操作之后,所以这里的li是获取不到的
如果将获取操作写在添加操作前,调换一下它们的位置,那么功能可以生效
document.body.innerHTML+='<li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li>'
var lis=document.querySelectorAll('li');
for(var i=0;i<lis.length;i++){
lis[i].onclick=function(){
console.log(this.innerHTML);
};
};
可是如何忽视这种顺序问题呢?
这时候就需要用到事件源对象
var ul = document.querySelector('ul');
ul.onclick=function(ev){
console.log(ev.target.innerHTML);
};
ul.innerHTML='<li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li>';
而且这里存在一个问题,如果点击到li旁边ul的空白上,就会在控制台输出<ul>...</ul>
这时就需要添加一个判断条件来完善这段代码
var ul = document.querySelector('ul');
ul.onclick=function(ev){
if(ev.target.tagName=='LI'){ //这里的tagName使用存在兼容性问题,在ie中是小写的li
console.log(ev.target.innerHTML);
}
};
ul.innerHTML='<li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li>';
本来这个点击事件是在li身上,但是我们这时候利用了事件源对象,将事件委托到了li的父级上去完成
故这个操作称为事件委托(代理)