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

你可能感兴趣的:(jquery,浏览器,IE,ext,Blog)