• 关于子级mouseover触发影响父级mouseout


    第一次写文,大神请绕路,求轻喷~~

    先给个简单的布局,先是HTML

    <body>
      <div id="outer">
        <div id="inner">
        </div>
      </div>
    </body>

    然后是CSS

    #outer{ width:400px; height:400px; background-color:red; margin:10px auto; position:relative;}
    #inner{ width:100px; height:100px; background-color:yellow; position:absolute; left:150px; top:150px;}

    这时候页面上看到的布局是这样的

    不要在意丑不丑,仅仅意思一下。。

    var oOuter = document.getElementById('outer');
    var oInner =document.getElementById('inner');
            
    oOuter.onmouseover = function(){
        this.style.background = 'blue';
    }
            
    oOuter.onmouseout = function(){
        this.style.background = 'red';
    }

    简简单单给外层DIV添加了鼠标移入移出事件,然后我们回到页面尝试一下,发现一点问题也没有,移入时候外层DIV颜色变蓝,移出去变回红色

    但是我们如果再加上一句话

    oInner.onmouseover = function(e){
        e.stopPropagation();  //或者是alert(1);
    }

    此时每当我们鼠标移入到黄色DIV的时候,我们发现了外层DIV由蓝色变红了,这是因为鼠标进入子元素的触发了父元素的mouseout事件

    之前正常是因为事件冒泡,其实父元素也变色了,不过速度很快人眼没有察觉

    此时就要吐槽一下safari了,如果用alert(1)这种阻塞查看的话,父元素还是蓝色!!猜测和浏览器渲染机制有关吧,自己不懂

    现在看起来没什么问题,因为反正人眼看不出来

    可是如果mouseover和mouseout触发的是定时器导致元素的位置变化啊之类的效果,那么就会有非常不好的用户体验了

    那该如何解决?

    最简单的方法就是使用mouseenter和mouseleave,这两个事件不会因为鼠标从父元素移到子元素就balabala乱来一通,只要你鼠标还在父级里面,怎么跑,也不会触发mouseleave

    然后好消息是连IE6都兼容!坏消息是safari不兼容!

    这只能手动判断了,下面给出两个方法

    aElement.contains(bElement)和aElement.compareDocumentPosition(bElement)

    先说contains方法,这个很简单,判断bElement是否在aElement内部

    代码如下

    oOuter.onmouseout = function(e){if(this.contains(e.relatedTarget)){
            return ;
        }
        
        this.style.background = 'red';
    }

    注意:有些浏览器(大部分,除了FF之外还支持e.toElement),不过最好用relatedTarget,这个是标准的

    然后就会发现问题没有了~

    下面说我更喜欢也是更强大的compareDocumentPosition方法,先给出一张图~

    何止是只能判断一个元素是否在一个元素之中啊,这完全是判断两个元素文档之间的位置关系啊,非常强大有木有~

    高版本浏览器都支持此方法,修改代码如下

    oOuter.onmouseout = function(e){
        if(this.compareDocumentPosition(e.relatedTarget) == 20){
            return ;
        }
                
        this.style.background = 'red';
    }

    注意:contains虽然不够强大,不过兼容IE6,而compareDocumentPosition只能兼容高版本浏览器

    结语:第一次写好累啊,不过希望坚持下去,多将自己一些经历写出来,是对自己的锻炼,也是算帮助一下起步者。。。(明明自己也是才起步)

  • 相关阅读:
    板子的配置
    检查点队列中未提交的数据块如何管理会减少内存使用
    js求月末new Date(year,month,0)
    js 截取字符串
    es6 x,y 互换值
    android x86 9.0r2 install guide 旧笔记本改造机顶盒
    Linux中常用命令
    在pyspark中调用scala/java代码
    Linux中安装sbt
    IDEA中手动引入JAR包
  • 原文地址:https://www.cnblogs.com/constructor/p/4393596.html
Copyright © 2020-2023  润新知