父元素onmouseover触发事件在父子元素间移动不停触发的问题

Posted 三坷油

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了父元素onmouseover触发事件在父子元素间移动不停触发的问题相关的知识,希望对你有一定的参考价值。

今天写了一个侧边栏动态展开收缩的效果 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <style>
        body{ font-size: 20px;font-weight: bold;color: white;line-height: 30px;text-align: center}
        .container{height: 347px;position: absolute;right: 0;border: 1px solid black}
        .container li{position: relative;list-style: decimal;height: 30px;width: 200px;
            margin-bottom: 3px;border: 1px solid black;display: list-item;right: -165px}
        .container li::before{content: "";display: block;position: relative;
            height: 30px;width: 35px;background: red}

        @keyframes bance {
            0%{right: -165px}
            100%{right:0 }
        }
        @keyframes bance1 {
            0%{right:0 }
            100%{right:-165px}
        }
    </style>
</head>
<body>
    <div class="container">
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li>6</li>
        <li>7</li>
        <li>8</li>
        <li>9</li>
        <li>10</li>
    </div>
    <script>


        window.onload=function(){
            var lilist=document.querySelectorAll(‘li‘);
            var container=document.querySelector(‘.container‘);
            var T1=null,T2=null;

            container.onmouseover=function(){
                var n=0;
                T1=setInterval(function(){
                    lilist[n].style.animationName=‘bance‘;
                    lilist[n].style.animationDuration=‘0.5s‘;
                    lilist[n].style.animationFillMode="forwards";
                    n++;
                    if(n>9){clearInterval(T1)}
                },50)
            };

        container.onmouseout=function(){
                var i=0;
                T2=setInterval(function(){
                    lilist[i].style.animationName=‘bance1‘;
                    lilist[i].style.animationDuration=‘0.5s‘;
                    lilist[i].style.animationFillMode="forwards";
                    i++;
                    if(i>9){clearInterval(T2)}
                },100)
            }

        }
        
    </script>
</body>
</html>

执行过程中不断报错,仔细检查逻辑没有发现什么问题,百度之发现可能是父元素onmouseover触发事件在父子元素间移动不停触发的问题,着手解决吧。读完http://blog.sina.com.cn/s/blog_7488043d0101dnuz.html 这篇文章后知道了解决方法;

在onmouseover时先进行如下判断,结果为true时再执行方法体:
if(!this.contains(event.fromElement)){MouseOverFunc()}
在onmouseout时先进行如下判断,结果为true时再执行方法体:
if(!this.contains(event.toElement)){MouseOutFunc()}
下面来解释一下上面两行代码的含义:
在IE中,所有的HTML元素都有一个contains方法,它的作用是判断当前元素内部是否包含指定的元素。我们利用这个方法来判断外层元素的事件是不是因为内部元素而被触发,如果内部元素导致了不需要的事件被触发,那我们就忽略这个事件。
event.fromElement指向触发onmouseover和onmouseout事件时鼠标离开的元素;event.toElement指向触发onmouseover和onmouseout事件时鼠标进入的元素。
那么上面两行代码的含义就分别是:
○ 当触发onmouseover事件时,判断鼠标离开的元素是否是当前元素的内部元素,如果是,忽略此事件;
○ 当触发onmouseout事件时,判断鼠标进入的元素是否是当前元素的内部元素,如果是,忽略此事件;
这样,内部元素就不会干扰外层元素的onmouseover和onmouseout事件了。

添加判断后如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <style>
        body{ font-size: 20px;font-weight: bold;color: white;line-height: 30px;text-align: center}
        .container{height: 347px;position: absolute;right: 0;border: 1px solid black}
        .container li{position: relative;list-style: decimal;height: 30px;width: 200px;
            margin-bottom: 3px;border: 1px solid black;display: list-item;right: -165px}
        .container li::before{content: "";display: block;position: relative;
            height: 30px;width: 35px;background: red}

        @keyframes bance {
            0%{right: -165px}
            100%{right:0 }
        }
        @keyframes bance1 {
            0%{right:0 }
            100%{right:-165px}
        }
    </style>
</head>
<body>
    <div class="container">
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li>6</li>
        <li>7</li>
        <li>8</li>
        <li>9</li>
        <li>10</li>
    </div>
    <script>


        window.onload=function(){
            var lilist=document.querySelectorAll(‘li‘);
            var container=document.querySelector(‘.container‘);
            var T1=null,T2=null;

            container.onmouseover=function(){
                if(!this.contains(event.fromElement)){
                    var n=0;
                    T1=setInterval(function(){
                        lilist[n].style.animationName=‘bance‘;
                        lilist[n].style.animationDuration=‘0.5s‘;
                        lilist[n].style.animationFillMode="forwards";
                        n++;
                        if(n>9){clearInterval(T1)}
                    },50)
                }
            };


            container.onmouseout=function(){
                if(!this.contains(event.toElement)){
                    var i=0;
                    T2=setInterval(function(){
                        lilist[i].style.animationName=‘bance1‘;
                        lilist[i].style.animationDuration=‘0.5s‘;
                        lilist[i].style.animationFillMode="forwards";
                        i++;
                        if(i>9){clearInterval(T2)}
                    },100)
                }
            };


        }

    </script>
</body>
</html>

没有问题。。

以上是关于父元素onmouseover触发事件在父子元素间移动不停触发的问题的主要内容,如果未能解决你的问题,请参考以下文章

JS中onmouseover与onmouseout的bug

Jquery mouseover多次触发问题

JS:子元素 onmouseover 触发了父元素的 onmouseout,子元素的onmouseout 同时也触发 父元素的 onmouseout

Javascript中的事件委托机制

当元素被禁用时触发 onmouseover 事件

事件冒泡以及onmouseenter 和 onmouseover 的不同