我写了一个轮播图,悬停时候停止轮播,我使用的是addEvnetListener实现(onmouseenter/onmouseleave)第三个参数我用的是true,即事件捕获时候执行,但是这样会出错,每次我鼠标移进/移出左右箭头的时候,又会再次触发onmouseenter和onmouseleave事件!
但是根据我的理解,第三个参数为true为事件捕获,我在最外层的container绑定的监听函数,为什么我在里层的dom移动仍然会触发container的监听事件呢?这不该是冒泡的结果吗?
dom结构如下
<body>
<div id="container" class="container">
<div class="pics">
<img src="https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3057381651,2463402979&fm=26&gp=0.jpg" alt="">
<img src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=4117493074,4130557145&fm=26&gp=0.jpg" alt="">
<img src="https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=347260778,2859369145&fm=26&gp=0.jpg" alt="">
</div>
<a href="javascript:;" id="prev" class="arrow"><</a>
<a href="javascript:;" id="next" class="arrow">></a>
</div>
</body>
然后用js写了两个功能,一个是鼠标移开时,图片自动播放,左右箭头消失;鼠标放在图片上,图片自动停止,并且左右箭头出现可点击移动左右图片。
主要js如下
play();
//点击左移图片
prev.onclick = function() {
animate(600);
}
//点击右移图片
next.onclick = function() {
animate(-600);
}
//鼠标悬停时,停止播放图片,由stop函数实现
container.addEventListener('mouseenter',function () {
console.log('in');
prev.style.display = 'block';
next.style.display = 'block';
stop();
},true)
//鼠标移开,开始播放,由play函数实现
container.addEventListener('mouseleave',function () {
prev.style.display = 'none';
next.style.display = 'none';
play();
},true)
//自动播放图片,setInterval
function play() {
timer = setInterval(function(){
animate(-600);
}, 2000);
}
//停止播放图片,clearInterval
function stop(){
clearInterval(timer);
}
事件从document往具体元素传播,叫事件捕获(向下传播)。
事件从集体元素往document传播,叫事件冒泡(向上传播)。
onmouseenter/onmouseleave 这两个事件是不会冒泡的,当你在子元素移动,并不会触发父元素。
当addEvnetListener第三个参数为true,表示该事件需要在捕获阶段执行。而,所有能向下传播到子元素的事件,一定会经过父元素。所以出现了你所说的问题
因此,你需要将addEvnetListener的第三个参数去掉(默认为false)。
这篇文章希望对你有帮助