jquery事件中的relatedTarget

jquery事件中的relatedTarget
2009-06-22 01:40

看jq的图片预加载的例子,看到里面有这样一行代码:

$(e.relatedTarget).attr("id")!="newBigPop"

e是jq触发事件后回调的参数

那么这个e到底有什么东东呢?  我在页面的事件中加了debugger;

然后刷新页面,自动触发vs 然后断点进行调试,发现如下特征:

e
{...}
altKey: false
attrChange: undefined
attrName: undefined
bubbles: undefined
button: 0
cancelable: undefined
charCode: undefined
clientX: 685
clientY: 181
ctrlKey: false
currentTarget: undefined
data: undefined
detail: undefined
eventPhase: undefined
fromElement: {...}
jQuery1245604506734: true
keyCode: 0
metaKey: undefined
newValue: undefined
originalEvent: {...}
originalTarget: undefined
pageX: 685
pageY: 181
prevValue: undefined
relatedNode: undefined
relatedTarget: {...}
screenX: 687
screenY: 311
shiftKey: false
srcElement: {...}
target: {...}
timeStamp: 1245604507250
toElement: {...}
type: "mouseenter"
view: undefined
wheelDelta: 0
which: undefined
那还是有些不理解,怎么办?  用GG去搜一下jq relatedTarget,发现早已经有人把jq的源码中的event进行了讲解

related---相关的、关联的,relatedTarget就是触发这个事件的事件源了 类似ie系列中的scrElement或是ff中的target。

 顺便提一下,IE与FF下得到event对象方法为: window.event || arguments.callee.caller.arguments[0];

这是用原生的js方法得到的。那JQ却转了一道弯

以下为GG得到的内容,加了点自己的理解:

Jquery提供了一个 event的包裹,这个相对于其它的lib提供的有点简单,但是足够使用。
//对事件进行包裹。
fix : function(event) {
if (event[expando] == true) return event;//表明事件已经包裹过
//保存原始event,同时clone一个。
var originalEvent = event; ① original译为:起初的,原来的。
event = { originalEvent : originalEvent};
for (var i = this.props.length, prop;i;) { ----------------这个地方在最后我会提到
prop = this.props[--i];
event[prop] = originalEvent[prop];
}
event[expando] = true;
//加上preventDefault and stopPropagation,在clone不会运行
event.preventDefault = function() { ② -阻止浏览器的默认行为,如表单提交事件
// 在原始事件上运行
if (originalEvent.preventDefault)
originalEvent.preventDefault();
originalEvent.returnValue = false;
};
event.stopPropagation = function() {
// 在原始事件上运行
if (originalEvent.stopPropagation)
originalEvent.stopPropagation();
originalEvent.cancelBubble = true; //---------------取消事件冒泡。
};
// 修正 timeStamp ----stamp译为时间戳,这里可以理解为事件触发时的时间
event.timeStamp = event.timeStamp || now();
// 修正target
if (!event.target) ③
event.target = event.srcElement || document;
if (event.target.nodeType == 3)//文本节点是父节点。
event.target = event.target.parentNode;
// relatedTarget
if (!event.relatedTarget && event.fromElement) ④
event.relatedTarget = event.fromElement == event.target
? event.toElement : event.fromElement;
// Calculate pageX/Y if missing and clientX/Y available
if (event.pageX == null && event.clientX != null) { ⑥
var doc = document.documentElement, body = document.body;
event.pageX = event.clientX
+ (doc && doc.scrollLeft || body && body.scrollLeft || 0)
- (doc.clientLeft || 0);
event.pageY = event.clientY
+ (doc && doc.scrollTop || body && body.scrollTop || 0)
- (doc.clientTop || 0);
}

// Add which for key events
if (!event.which && ((event.charCode || event.charCode === 0) ⑦
? event.charCode : event.keyCode))
event.which = event.charCode || event.keyCode;

// Add metaKey to non-Mac browsers
if (!event.metaKey && event.ctrlKey) ⑧
event.metaKey = event.ctrlKey;
// Add which for click: 1 == left; 2 == middle; 3 == right
// Note: button is not normalized, so don't use it
if (!event.which && event.button) ⑨
event.which = (event.button & 1 ? 1 : (event.button & 2
? 3 : (event.button & 4 ? 2 : 0)));
return event;
},
上面的代码①处保留原始事件的引用,同时clone原始事件。在这个clone的事件上进行包裹。②处在原始事件上运行preventDefault 和 stopPropagation两个方法达到是否阻止默认的事件动作发生和是否停止冒泡事件事件向上传递。
③处是修正target个,IE中采用srcElement,同时对于文本节点事件,应该把target传到其父节点。
④处relatedTarget只是对于mouseout、mouseover有用。在IE中分成了to和from两个Target变量,在mozilla中没有分开。为了保证兼容,采用relatedTarget统一起来。
⑥处是进行event的坐标位置。这个是相对于page。如果页面可以scroll,则要在其client上加上scroll。在IE中还应该减去默认的2px的body的边框。
⑦处是把键盘事件的按键统一到event.which的属性上。Ext中的实现ev.charCode || ev.keyCode || 0; ⑨则是把鼠标事件的按键统一把event.which上。charCode、ev.keyCode一个是字符的按键,一个不是字符的按键。⑨处采用&的方式来进行兼容性的处理。 Ext 通过下面三行解决兼容问题。
var btnMap = Ext.isIE ? {1:0,4:1,2:2} : (Ext.isSafari ? {1:0,2:1,3:2} : {0:0,1:1,2:2}); this.button = e.button ? btnMap[e.button] : (e.which ? e.which-1 : -1);

看了上面的应该理解一些了,有兴趣的可以直接再深入到他的源码中去。

如果你要取消事件冒泡,可以这样用:

也就是说,要阻止冒泡,直接使用
$("a").click(function(e) {
e.stopPropagation();
}) 还有一种更简单的方法:

也就是说,要阻止冒泡,直接使用
$("a").click(function(e) {
return false;

})这样也可以的。

仔细看,可以发现里面有这样一个属性:originalEvent

jq中文文档译者:http://shawphy.com/2008/07/the-missing-manual-in-jquery-1.html

这里有提到他的使用:

获取鼠标的相对坐标:

$("#menuWrap").mousemove(function(e) {
var xx=e.originalEvent.x||e.originalEvent.layerX||0;
});

下面为一个简单的菜单JS代码:

<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
<!--
jQuery(function($) {
$("#menuWrap").mousemove(function(e) {
var xx=e.originalEvent.x||e.originalEvent.layerX||0;
var yy=e.originalEvent.y||e.originalEvent.layerY||0;
if (xx<50) xx=50
if ( xx > 450) xx=450
$("#menu").stop(true).animate({"marginLeft":parseInt(0-(xx-50)/399*300)},600,"easeOutBack");
});
});
jQuery.easing.easeOutBack=function (x, t, b, c, d, s) {
if (s == undefined) s = 1.70158;
return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
}
//-->
</script>

前面我作了一个记号:props,它里面又有些什么东东呢?

props : "altKey attrChange attrName bubbles button cancelable charCode clientX "
+ "clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode "
+ "metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX "
+ "screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which"
.split(" "),

到这里,我想应该都明白了我最开始贴出来的那段神奇的代码吧。

想深入了解的可以点击这里继续查看:http://jljlpch.iteye.com/blog/230080
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值