4.事件源对象

144
作者 素弥
2016.10.10 17:55 字数 575
事件对象是事件触发时关于事件的一些信息
事件源对象是事件对象里面的一部分,表示的是真正触发事件的那个对象



以下面这段代码为例:

<!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文档中一层一层的向下查找,直到找到最里层的那个触发事件的源对象


那么它主要应用在哪里呢?

我们可以来看一个例子:
有一个界面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的父级上去完成
故这个操作称为事件委托(代理)