www.qjdy.com-奇迹赌场 > www.qjdy.com官网 > 跨浏览器的 mouseenter mouseleave 以及 compareDocumentP

原标题:跨浏览器的 mouseenter mouseleave 以及 compareDocumentP

浏览次数:65 时间:2019-09-06

写了这么久 js应用 笔者以致不亮堂那四个事件 于是 去google寻找了一番. 才意识那多少个事件 是那样的完美 且好用... 但搜索进度中 发现 好五个人就好像不太明了那多个事件 和mouseover mouseout 真正的界别 和用途..  并且看来google中找出得到的 一些相恋的人 完毕的 跨浏览器 应用方案. 认为就像有个别繁琐...所以发生了写一篇blog 把那玩意 说透顶的冲动... 好啦.大家进去正题.

对于 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

第四位 代表node是或不是是node2的子节点 借使是则为1 不然为0

第4位 代表node是不是在node2的先头 纵然是 则为1 不然为0 (注:假使node是node2的父节则node同不日常间也视作在node2的日前)

第1位 代表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 的结果是 0一千0 即重临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 0010000一千0 一千00 
        },
        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 重返0一千0则 表明当前标志值具有 0一千0以此状态.

            }
            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结构:

<div id="dd" style="background-color:#369;width:50%;height:50%;position:absolute;left:25%;top:25%;" >
    <div style="background-color:#ff0;width:50%;height:50%;position:relative;left:25%;top:25%" >
        <div style="background-color:#789;width:50%;height:50%;position:relative;left:25%;top:25%" >
            <div style="background-color:#123;width:50%;height:50%;position:relative;left:25%;top:25%" >
                <div style="background-color:#456;width:50%;height:50%;position:relative;left:25%;top:25%" >
                </div>
            </div>
        </div>
    </div>
</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) & 8) && alert(1);
        };
        dd.onmouseout = function(e) {
            var t = e.relatedTarget;
            var t2 = e.target;
            this == t2 && t && !(t.compareDocumentPosition(this) & 8) && alert(2);
        };
    }

功勋卓著告成!!!!!

js应用 笔者居然不掌握那三个事件 于是 去google寻找了一番. 才意识那七个事件 是那般的精良 且好用... 但找出进程中 开采 好四个人...

本文由www.qjdy.com-奇迹赌场发布于www.qjdy.com官网,转载请注明出处:跨浏览器的 mouseenter mouseleave 以及 compareDocumentP

关键词: bbin电子游戏

上一篇:JSQL 一个 web DB 的封装

下一篇:没有了