实现一个很简单的功能,鼠标悬浮在一个dom上,使它的边框颜色发生变化。我很快写出了下面的代码

        .outer{
            width:360px;
            background-color: white;
            margin: auto;
            vertical-align: text-top;
        }
        .left{
            display:inline-block;
            width:90px;
            height:90px;
            margin:18px 0 18px 18px;
            line-height:90px;
            *display:inline;
            *zoom:1;
        }
        .right{
            display: inline-block;
            line-height:90px;
            *display:inline;
            *zoom:1;
        }

    <div class='outer' id='outer'>
        <div class='left'>左边</div>
        <div class='right'>右边</div>
    </div>

<script type="text/javascript">
    document.getElementById('outer').onmouseover=function(event){
        event=event||window.event;
        var target=event.target||event.srcElement;
            target.style.borderColor='blue';
    }
    document.getElementById('outer').onmouseout=function(event){
        event=event||window.event;
        var target=event.target||event.srcElement;
            target.style.borderColor='black';
    }
</script>

结果肯定是不对。我只想让最外围的边框变色,而不想让子元素变色。

问题出在target上,target和srcElement是触发事件的元素,而不是绑定事件的元素。currentTarget是绑定事件的元素,但是IE没有这个属性。所以就只能对target进行特殊处理。将js代码改为

<script type="text/javascript">
    document.getElementById('outer').onmouseover=function(event){
        event=event||window.event;
        var target=event.target||event.srcElement;
        if(target.className==='outer')
            target.style.borderColor='blue';
    }
    document.getElementById('outer').onmouseout=function(event){
        event=event||window.event;
        var target=event.target||event.srcElement;
        if(target.className==='outer')
            target.style.borderColor='black';
    }
</script>

仍然不对!放在left或right上时,outer没有反应。本以为事件会冒泡,交由父元素outer处理,看来我对冒泡的理解有误。

冒泡的事情一会处理,先把代码改对

<script type="text/javascript">
    document.getElementById('outer').onmouseover=function(event){
        event=event||window.event;
        var target=event.target||event.srcElement;
        while(target!==null)
        {
            if(target.className==='outer'){
                target.style.borderColor='blue';
                break;    
            }
            else{
                target=target.parentNode;
            }            
        }
    }
    document.getElementById('outer').onmouseout=function(event){
        event=event||window.event;
        var target=event.target||event.srcElement;
        while(target!==null)
        {
            if(target.className==='outer'){
                target.style.borderColor='black';
                break;    
            }
            else{
                target=target.parentNode;
            }    
        }
    }
</script>

这次向父元素进行遍历,找到目标节点就改变样式。这次功能总算对了。但是仍然存在两个问题:一个是冒泡,另一个是直接使用this行不行?

第一个问题:参考了这篇文章http://blog.csdn.net/ckstory/article/details/7860239

对比了一下代码的不同。我只给外层元素绑定了事件,而它给所有的元素绑定了事件。果然我对冒泡的理解和target的理解一直是错误的,冒泡的前提是会多次触发事件,但是无论触发多少次,event.target都是不变的,变化的是event.currentTarget。而我的代码里仅仅绑定了一次事件,没有其他事件可供处理,所以就不存在冒泡的问题。

第二个问题:使用this行不行。刚才提到的那篇文章里用的就是this。js原生的事件绑定方式有三种:1、直接写在html标签里,2、用onclick(mouseover,keydown...)去绑定3、用attachEvent或者addEventListener。分别测试了三种绑定方式下的this,都和currentTarget一致。jQuery的4中绑定方式中on,bind,delegate,live的this和currentTarget也是一致。

 

posted on 2017-02-12 17:50  lichliu  阅读(349)  评论(0编辑  收藏  举报