mouseenter 的非 IE 实现

Extjs 实现

 

关于 mouseenter : 当第一次鼠标进入节点区域时触发,以后在节点区域内(子节点间)移动 时不触发。

属于 ie 的特有事件,貌似不是 w3c 标准 ,但是很有用。


extjs 3.0 对 非ie浏览器实现了这个事件,原理很简单 , 监控 mouseover 事件,只不过 当判断只是内部移动的话(触发自内部子节点冒泡过来的 ),就把该事件屏蔽掉,不再调用用户处理函数。以及利用 事件的标准属性 (IE 没有) currentTarget ,具体看见:


extjs 3.0 ext-base-debug.js 1946 行 。


这里 用 extjs 2.2.1 模拟一下 3.0 的实现。


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>mouseenter测试</title>


<script type="text/javascript" src="ext-base.js"></script>
<script type="text/javascript" src="ext-core.js"></script>


<script type="text/javascript">
//<![CDATA[

window.consoleH={
	log:function(str){
		Ext.get("log").update(Ext.get("log").dom.innerHTML+"<br/>"+str);
		Ext.get("log").dom.scrollTop=Ext.get("log").dom.scrollHeight;
	}
};
Ext.onReady(function() {
	
	var no=1;
	
	if(Ext.isIE) {
		
		alert("你可以利用 mouseenter 事件");
		Ext.get("t1").on("mouseenter",function(be){
			consoleH.log(no++ + " : enter inside currentTarget");
		});
	
	}else {
	
		Ext.get("t1").on("mouseover",function(be){
			consoleH.log(no++ + " :----------------");
			
			//事件发生的节点
			if(be.getTarget()) consoleH.log("target - "+be.getTarget().id);
			else consoleH.log("target - null");
				
			
			//事件处理的当前节点	
			if(be.browserEvent.currentTarget) consoleH.log("currentTarget - "+be.browserEvent.currentTarget.id);
			else consoleH.log("currentTarget - null");
				
				
			//从哪个节点移到事件发生的节点	
			if(be.getRelatedTarget())consoleH.log("related - "+be.getRelatedTarget().id);
			else consoleH.log("getRelatedTarget - null");
			
			
			if(be.browserEvent.currentTarget)	{
				
				//如果相关节点是处理节点的子节点,或者就是处理节点 ,不是第一次进入了,属于内部移动
				if(be.browserEvent.currentTarget == be.getRelatedTarget() || Ext.get(be.browserEvent.currentTarget).contains(be.getRelatedTarget()))
					consoleH.log("  moveinside currentTarget");
				else
				//恩,是第一次	
					consoleH.log("enter inside currentTarget");
			}
		
		});
		
	 }

       
});
//]]>

</script>

</head>
<body>
	
	<div id="log" style="position:absolute;right:0;height:400px;width:300px;border:1px solid red;overflow:scroll;">
</div>
<div style="width:400px;height:400px;border:1px solid green;" id="t1">


<div style="width:200px;height:200px;border:1px solid red;" id="t2">

<div style="width:100px;height:100px;border:1px solid black;" id="t3">



</div>

</div>

</div>

</body>
</html>
 



同理可实现  mouseleave 事件。

 

 

 

jquery 实现:

 

思路类似,判断当前触发节点是否是自己的子节点,是的话就忽略了 !

 

// Checks if an event happened on an element within another element
// Used in jQuery.event.special.mouseenter and mouseleave handlers
var withinElement = function(event) {
    // Check if mouse(over|out) are still within the same parent element
    var parent = event.relatedTarget;
    // Traverse up the tree
    while (parent && parent != this)
    try {
        parent = parent.parentNode;
    }
    catch(e) {
        parent = this;
    }

    //这里判断 this 吧
    if (parent != this) {
        // set the correct event type
        event.type = event.data;
        // handle event if we actually just moused on to a non sub-element
        jQuery.event.handle.apply(this, arguments);
    }
};

 

鼠标系列总结:


mousedown mouseup 的发生节点可能不一样,在a节点上mousedown,然后挪动鼠标在b节点上mouseup,则a节点上触发事件 mousedown,b节点上触发事件 mouseup,故对于拖放 mouseup 应绑定在 document 上面,而不是拖放节点。

mouseover,mouseout 可能会有一些想不到的效果,比如内部嵌套节点的mouseover,mouseout 事件会冒泡到主节点的事件处理器,并不是自己想要的效果,可以根据target以及relatedTarget来判断

mousemove 每个像素的变化都会导致触发,可用定时器来减缓提高性能。

 

你可能感兴趣的:(JavaScript,jquery,XHTML,IE,ext)