在IE的全系列中都實現了mouseenter和mouseleave事件,可是在早期的w3c瀏覽器中卻沒有實現這兩個事件。有時候,咱們須要使用node
mouseenter事件來防止子元素的冒泡,這就涉及到事件兼容性的問題了。瀏覽器
先比較mouseenter和mouseover的異同點,當從元素外圍進入元素內部時同時觸發mouseover和mouseenter事件,可是在元素內部,dom
鼠標進入元素子節點時會繼續觸發mouseover事件,該事件是能夠向上冒泡的;對於mouseenter則不會冒泡,固然也不會觸發該事件。this
mouseleave亦然。spa
用mouseover來模擬mouseenter的關鍵在於利用事件的relatedTarget斷定鼠標是否在元素內部移動,這也涉及到dom元素contain()code
的實現。爲了高效的實現contain方法,儘可能使用瀏覽器的原生API,若是沒有則只能向上回溯。blog
function contain(p,c){ if(p == c)return false; if(p.compareDocumentPosition){ return !!(p.compareDocumentPosition(c) & 16); }else if(p.contains){ return p.contains(c); } var cur; while(c = c.parentNode){ if(c.nodeType == 3 || c.nodeType == 8) continue; if(c !== p) continue; else{ return true; } } return false; }
而後着重修復mouseover事件:seo
var fixMouseenter = function(el,fn){ return window.VBArray ? { el: el, type: 'mouseenter', fn: fn } : { el: el, type: 'mouseover', fn: function(e){ !contain(el,e.relatedTarget) && fn.call(this,arguments); } }; }; var fixMouseleave = function(el,fn){ return window.VBArray ? { el: el, type: 'mouseleave', fn: fn } : { el: el, type: 'mouseout', fn: function(e){ !contain(el,e.relatedTarget) && fn.call(this,arguments); } }; };
這樣對於非IE瀏覽器都進行事件修復,可是缺點也有很多,就是新版本的w3c瀏覽器都已經實現了這兩個事件,因此咱們就沒有必要事件
在進行事件修復。get