实现一个很简单的功能,鼠标悬浮在一个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也是一致。