onMouseEnter 和onMouseOver区别以及跨浏览器解决策略

news/2024/5/20 4:35:48/文章来源:https://blog.csdn.net/l498948617/article/details/21158359
对于 mouseover 和mouseenter 两个事件 最大的区别就是 mouseenter 是 不冒泡的事件 ..这话怎么理解呢? 
<div id=="parent"> 
<div id="child"></div> 
</div> 

对于mouseover 时间来说 当鼠标从其他元素 移动到 child节点时发生 但此事件会冒泡 所以会导致 parent 也出发mouseover 
如果我们对 parent注册了 mouseover监听. 则可能会产生一个什么问题呢? 从 parent移动到child 同样出发parent的mouseover  有时候我们不希望这样的事情发生. 这时候 如果注册的监听 是mouseenter的话  无论鼠标从任何元素 移动到child时 只有child元素 发生mouseenter事件 而其祖宗节点 都不会因为冒泡 而触发此事件...这就 使我们可以彻底放弃  我们以往为了 实现同样的逻辑  又要对子节点禁止mouseover冒泡 或者又去判断事件源对象 或判断srcElement/relatedTarget 那样麻烦的方案. 
对于 mouseout 和mouseleave 也是如此 当鼠标从child 移出时 mouseout同样会冒泡到 parent 从而触发parent的 mouseout 二mouseleave 同样无此问题. 

知道了区别 剩下的事情就好办多了. 遇到此类需求 我们一律mouseenter mouseleave就好..问题是 这玩意只有ie支持 怎么办呢? 
我们只能 用mouseover 和mouseout来模拟  但是如果我们的模拟方案 太过复杂 那是在就意义不大了... 这时候我们就可以 借助 xml 方法compareDocumentPosition 来彻底解决这个问题 
我在我的类库中 封装了一个方法 专门用来判断 某个节点的位置 是否在另一个节点的子节点中... 
ie可以用 parentNode.contains(childNode) 来判断 这没什么好说的 childNode在parentNode DOM树中存在 那么就是true 
而contains方法 ie专属 那么 我们就是借助 !!(node.compareDocumentPosition(node2) &16) 来实现同样的效果. 
那么接下来 我们就来谈谈 compareDocumentPosition 方法 否则 你看到上面的 &16 一定会困惑无比... 

compareDocumentPosition 方法在非ie浏览器 都被实现到 节点对象的 中了  所以 
node.compareDocumentPosition(node2) 的作用就是 比较 node节点与node2节点之间的位置关系.. 
他的返回值是一个number值... 
一般来说 对我们有用的 是以下几个值 
1.  20  (2进制: 010100) 
2.  10  (2进制:   001010) 
3.  4    (2进制:   000100) 
4.  2    (2进制:   000010) 
5.  0    (2进制:   000000) 
6.  2进100***的数... 
那么这些 20 10 4 2 0 是怎么来的呢? 我们接着往下 看... 

试试上 这个2进制算法 是专门用来解释 两个节点之间的关系的 

这个 6位2进制数 才是根本所在 
第6位 代表 两个节点是否一个在DOM树上一个不在 这个是针对整个DOM树而言的.也就是说 如果两个都不在 或两个都在 则为0 否则为1 
第5位 代表node是否是node2的父节点 如果是 则为1 否则为0 
第4位 代表node是否是node2的子节点 如果是则为1 否则为0 
第3位 代表node是否在node2的前面 如果是 则为1 否则为0 (注:如果node是node2的父节则node同时也看做在node2的前面) 
第2位 代表node是否在node2的后面 如果是 则为1 否则为0 (注如果node是node2的子节点 则node同时也看做在node2的后面) 
最后 如果 2 3 4 5 6 位 都为0 即 000000 说明 两个节点 要么同时在DOM树上 要么同时不在. 且 两个节点 没有任何关系 那么只有一种可能 即两个节点是同一个节点...也就是 node==node2 

所以 node.compareDocumentPosition(node2) &16 位运算 的结果是什么呢? 以上几种可能的组合中只有 010100 &010000 以及 110*** &16 的结果是 010000 即返回16 其他情况  均返回 0 然后 用!! 吧number隐式转型成boolean类型 我们就可以判断出 node是否是 node2的父节点了... 
所以 我们也可以使用 node2.compareDocumentPosition(node) & 8 来判断node2 是不是 node的子节点 道理是同样的 
或者我们也可以直接 node.compareDocumentPosition(node2) ==20 来做判断 这样还可以省略 !! 做转型..也是可以的. 

到了这里 聪明你的 一定发现 这玩意是什么? 分明就是c#中  flag 标识枚举 的用法... 
c# 中 File.Attributes 枚举 可能同时具备 n多属性 比如一个文件 可以是 只读的同时 还可以是 隐藏的 或者同时还可以是 共享的. 等等 
那么 用一个枚举 值 如何确定 一个文件同时具备哪些属性 又不产生冲突呢? 答案 于 compareDocumentPosition是一样的... 

我用js 实现了一个 类似逻辑 来管理 flag标识的类 来说明这个问题 代码如下 
// flag 类 
    function flag(sFlags) { 
        this._flags = {}; 
        this._status = 0; 
        sFlags && this.initFlags(sFlags); 
    } 
    flag.prototype = { 
        constructor: flag, 
        initFlags: function(sFlags) {//sFlags "状态1,状态2,状态3...... 初始化原始标识集合... 
            sFlags = sFlags.split(','); 
            for (var i = 0, len = sFlags.length; i < len; i++) this._flags[sFlags[i]] = 1 << i; 
           //这里初始化标识的值 如果同时具备n种状态 则 每种状态的值一定是 000001  000010 000100 001000 010000 100000 
        }, 
        setStatus: function(sFlags) { //sFlags "状态1,状态3......设置当前状态 
            sFlags = sFlags.split(','); 
    this._status=0; 
            for (var i = 0, len = sFlags.length; i < len; i++) { 
                this._check[sFlags[i]]; 
                this._status |= this._flags[sFlags[i]]; 
            } 
        }, 
        addStatus: function(sFlags) {//sFlags "状态1,状态3......检查当前状态标示 是否有 状态1和状态3 如果没有则添加 
            sFlags = sFlags.split(','); 
            for (var i = 0, len = sFlags.length; i < len; i++) { 
                this._check(sFlags[i]); 
                if (this.hasStatus(sFlags[i])) continue; //判断是否已经有这个状态如果有 跳过. 
                this._status |= this._flags[sFlags[i]]; 
                //当前的状态值 与 允许的标识值 做 | 运算 即添加状态 
            } 
        }, 
        removeStatus: function(sFlags) { 
            sFlags = sFlags.split(','); 
            for (var i = 0, len = sFlags.length; i < len; i++) { 
                this._check(sFlags[i]); 
                if (!this.hasStatus(sFlags[i])) continue; 
                this._status ^= this._flags[sFlags[i]]; 
                // 当前状态值 与 要去掉的状态值做 ^运算 即删除状态 
            } 
        }, 
        clear: function() { 
            this._status = 0; 
        }, 
        hasStatus: function(sFlags) {//sFlags "状态1,状态3.....状态 n.检查当前状态标识 是否同时 具备状态1和状态3 以及状态n 
            sFlags = sFlags.split(','); 
            for (var i = 0, len = sFlags.length; i < len; i++) { 
                this._check(sFlags[i]); 
                if ((this._status & this._flags[sFlags[i]]) != this._flags[sFlags[i]]) return false; 
                //当前状态值 与输入的状态做 & 运算  如果返回值 不等于 改状态 的标识值 则 return false . 
               //比如 010101 & 010000 返回010000则 说明当前标识值具备 010000这个状态. 
            } 
            return true; 
        }, 
        _check: function(sFlag) { 
            if (!sFlag in this._flags) throw new Error(" 当前 flag 中不存在" + sFlag + "标识"); 
            //检查当前输入状态字符串 是否是合法值. 
        } 
    } 

用法: 
var fileStatus=new flag('readOnly,hidden,otherStatus'); 
fileStatus.setStatus('readOnly,hidden'); 
alert(fileStatus.hasStatus('readOnly'))//true; 
alert(fileStatus.hasStatus('hidden'))//true; 
alert(fileStatus.hasStatus('otherStatus'))//false; 


最后 我们回到正题 我们借助 compareDocumentPosition 来模拟 mouseenter mouseleave 

DOM结构: 
01 
<div id="dd" style="background-color:#369;width:50%;height:50%;position:absolute;left:25%;top:25%;" > 
02 
    <div style="background-color:#ff0;width:50%;height:50%;position:relative;left:25%;top:25%" > 
03 
        <div style="background-color:#789;width:50%;height:50%;position:relative;left:25%;top:25%" > 
04 
            <div style="background-color:#123;width:50%;height:50%;position:relative;left:25%;top:25%" > 
05 
                <div style="background-color:#456;width:50%;height:50%;position:relative;left:25%;top:25%" > 
06 
                </div> 
07 
            </div> 
08 
        </div> 
09 
    </div> 
10 
</div> 

js脚本: 
  

    var dd = document.getElementById('dd') 
    if (! +'\v1') {//ie 
        dd.onmouseenter = function() { alert(1); }; 
        dd.onmouseleave = function() { alert(2); }; 
    } 
    else {//others 
        dd.onmouseover = function(e) { 
            var t = e.relatedTarget; 
            var t2 = e.target; 
            this == t2 && t && !(t.compareDocumentPosition(this) &  && alert(1); 
        }; 
        dd.onmouseout = function(e) { 
            var t = e.relatedTarget; 
            var t2 = e.target; 
            this == t2 && t && !(t.compareDocumentPosition(this) &  && alert(2); 
        }; 
    } 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_865903.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux权限】apache网站根目录的权限配置

问题引入 阿里云服务器上的一个网站根目录&#xff1a;/var/www/testpublic 这个是通过配置基于端口的虚拟主机设置的站点根目录。里面的东西如截图所示。 昨晚我在该目录下增加了一个menu.html&#xff0c;而该静态网页引用了img目录下的一张图片。但是奇怪的是我通过浏览器访…

什么是移动应用营销新趋势:Web需要SEO,App也需要ASO

android开发环境搭建用户可以通过门户发现自己感兴趣的内容&#xff0c;创业者可以通过36氪找到有价值的内容&#xff0c;所有人都可以通过Googlehttp://www.kmnk03.com/hxpfk/tf/137.html和百度搜索更多的内容。于是沿着这思 路&#xff0c;先有了应用商店和市场&#xff0c;接…

将tomcat用Eclipse发布网站

先建立一个Java 项目 1.新建一个java项目&#xff08;注意是Dynamic Web Project&#xff09;找不到的话在other 的 web中可找到&#xff0c;输入名字和调整版本为2.5点击finish 2.打开项目&#xff0c;右键WebContent&#xff0c;新建一个简单的html的文件 如 3.我们点击控制…

使用动态代理解决网站的中文乱码

动态代理模式方法 实践代码 public class EncodingFilter implements Filter{ Override public void init(FilterConfig filterConfig) throws ServletException { } Override public void doFilter(FilterConfig filterConfig) throws IOException,ServletException { final …

一步步构建大型网站架构

之前我简单向大家介绍了各个知名大型网站的架构&#xff0c;亿万用户网站MySpace的成功秘密、Flickr架构、YouTube网站架构、PlentyOfFish 网站架构学习、WikiPedia技术架构学习笔记。这几个都很典型&#xff0c;我们可以从中获取很多有关网站架构方面的知识&#xff0c;看了之…

响应式网站设计保护层级和内容完整性的方法

本篇文章中&#xff0c;我们将介绍在设计响应式网站过程中&#xff0c;保护层级和内容完整性的方法。 内容编排 在前文中使用媒介查询功能来重排页面元素&#xff0c;再深入一步&#xff0c;不光要考虑可用的空间&#xff0c;还必须照顾到内容。假设有一个4 栏的全宽网站&…

单页web应用是什么?它又会给传统网站带来哪些好处?

什么是单页应用&#xff1f; 单页应用是指在浏览器中运行的应用&#xff0c;它们在使用期间不会重新加载页面。像所有的应用一样&#xff0c;它旨在帮助用户完成任务&#xff0c;比如“编写文档”或者“管理Web服务器”。可以认为单页应用是一种从Web服务器加载的富客户端。 单…

解秘亿级网站的一本书——亿级流量网站架构核心技术

网站是直接面对广大客户的&#xff0c;是公司的门户&#xff0c;必须快速响应&#xff0c;必须持续可用&#xff0c;必须抗得住洪峰。任何一个网站的发展过程中都出现过问题&#xff0c;影响客户体验和商业利益&#xff0c;公司业务规模越大&#xff0c;网站出现问题的损失越大…

瞬时响应:网站的高性能架构

什么叫高性能的网站&#xff1f; 两个网站性能架构设计方案&#xff1a;A方案和B方案&#xff0c;A方案在小于100个并发用户访问时&#xff0c;每个请求的响应时间是1秒&#xff0c;当并发请求达到200的时候&#xff0c;请求的响应时间将骤增到10秒。B方案不管是100个并发用户…

301重定向,301跳转:IIS服务器网站整站301永久重定向设置方法

网站301重定向&#xff1a;阿里云windows服务器IIS6.0-IIS7.5通用全站&#xff08;包括内容页&#xff09;301重定向方法 最近PE准备把二级域名换成全拼域名”www.panoeade.com”试着在服务器iis上面直接设置HTTP重定向&#xff0c; 哪知道操作之后以前的域名可以跳转到新域名…

用Django创建一个照片墙网站

-0- 使用到的资源&#xff1a; 前端: Blueimp Gallery后端: Django缩略图: easy_thumbnails部署: nginx gunicorn supervisor开发环境是Centos 7.2 Python 2.7.5 上个图先: 界面 效果预览 -1- 创建项目 假设当前用户是ljgabc&#xff0c;当前目录是/home/ljgabc。 virtu…

一个礼拜学完前端,获得前端证书,并写出一个商城网站的

前端技术最近几年一直火爆&#xff0c;不会点前端技术&#xff0c;都不敢说自己是个优秀的程序员&#xff0c;即便你是做Java后台&#xff0c;亦或者C#、Python。 当你折腾了很久的后台&#xff0c;再去研究前端的时候&#xff0c;发现前端真的是小儿科&#xff0c;虽然前端技术…

边学边搭建个人网站

网络上搭建个人网站的教程不少&#xff0c;但是都比较零散。自己一个人鼓捣鼓捣&#xff0c;也开始上路了。 搭建个人网站的基本步骤如下&#xff1a; 1.申请域名 2.购买服务器 3.在服务器上配置环境 4.将自己的本地网页上传到云服务器 1.申请域名 这一步我没有尝试&#xff0…

网络安全系列连载(4)网站服务器与数字证书

由于Windows NT系统的容易维护&#xff0c;很多单位或者ISP都采用它&#xff0c;大部分是做WEB服务器使用。虽然IIS存在很多新的漏洞和安全问题&#xff0c;但只要我们做好合理的安全配置&#xff0c;还是可以避免很多安全隐患的。因此&#xff0c;本文选择IIS服务器来测试数字…

Google 联合一些社交网站来对抗 facebook

谷歌 (Google) 将与其它一些行业领先的社交网站联手&#xff0c;共同对抗互联网新贵Facebook。  谷歌将于周四推出一个通用标准集 ( OpenSocial )&#xff0c;允许软件开发者为谷歌旗下社交网站Orkut&#xff0c;以及LinkedIn、hi5、Friendster、Plaxo和Ning等其它社交网站…

CSDN 未来网站内容Tag架构猜想

大概是上周吧&#xff0c;写了一篇blog主观的分析了一下CSDN目前的内容架构&#xff0c;收到许多朋友好的意见和建议&#xff0c;在此首先对他们表示感谢。网络变化真的很快&#xff0c;现在的网站内容架构较2&#xff0c;3年前已经有翻天覆地的变化。很多人也提出了“如今的网…

php 网站添加高防ip

最近做的游戏抽奖平台一直被流量攻击&#xff0c;网址使用的阿里云的服务器&#xff0c;小项目但是阿里的高防2w多实在用不起。只好找的其他平台的&#xff0c;这里推荐个平台挺便宜的:https://www.yisu.com 购买成功后&#xff0c;两个平台都需要添加白名单&#xff1b;高防ip…

seo优化:把百度放进数据库

seo优化:把百度放进数据库 有时候我想&#xff0c;能把百度的数据放进数据库&#xff0c;用广大程序员熟悉的sql语句查询百度的搜索结果应该是一个不错的主意。在这方面Google早已经跨出了一大步&#xff0c;利用Google Search API 把Google的搜索结果放进数据库是很容易办到得…

SEO 比比看: Che168.com VS pcauto.com.cn

SEO 比比看&#xff1a; Che168.com VS pcauto.com.cn 做SEO工作&#xff0c;平常少不了多观察各种网站优化的案例。俗话说的好&#xff0c;懂行的看门道&#xff0c;不懂的看热闹。面对五花八门的网站&#xff0c;如何才能从专家的角度&#xff0c;以最快的速度来了解被观察…

搜索引擎SEO外挂:一边搜索,一边看PageRank

搜索引擎SEO外挂&#xff1a;一边搜索&#xff0c;一边看PageRank 下载地址&#xff1a;多么乐站长工具 我原来曾写过一篇统计分析搜索引擎排名和Page Rank 关联分析 的文章。很多人引用&#xff0c;回复和我讨论了我的结论。有赞成的&#xff0c;有反对的&#xff0c;有鼓励的…