e = e || window.event用法細節討論


<!DOCTYPE HTML>
<html>
<head>
    <title></title>
    <style type="text/css">
    #aa{ border:1px solid #000; width:100px; height:40px; margin-top:50px;}
    #bb{ border:1px solid #000; width:500px; height:40px; margin-top:50px;}
    #cc{ border:1px solid #000; width:500px; height:40px;}
    </style>
</head>
<body>
    <div id="aa"></div>
    <div id="bb">dfdfddfsd</div>
    <div id="cc">gregreger</div>

    <script type="text/javascript">

        document.getElementById("aa").onclick = function (e) {
            if (e) alert(e.toString()); // IE6/7/8 e為undefined  IE9中e為W3標准事件對象。
            //e = window.event;
            alert(e.srcElement.tagName || e.currentTarget.tagName);
        }
        /*  element.onXXX方式(比較古老,不推薦使用)

        這種方式添加事件IE6/7/8只支持window.event不支持參數傳入,
        Firefox只支持參數傳入不支持其它方式。
        IE9/Opera/Safari/Chrome 兩種方式都支持。
        */

        
        var d4 = document.getElementById('bb');
        function clk(e) {
            alert(e);  // 所有瀏覽器彈出的信息框顯示都是事件對象。
            alert(e.srcElement.tagName || e.currentTarget.tagName);
            e = e || window.event;
            alert(e);  // IE6/7/8中和上個e彈出相同的對象。
        } 
        if (d4.addEventListener) {
            d4.addEventListener('click', clk, false);
            alert("addEventListener");
        }
        if (d4.attachEvent) {
            d4.attachEvent('onclick', clk);
            alert("attachEvent");
        }
        /*  addEventListener、attachEvent方式(推薦使用)

        結論:
        通常事件句柄里有這句話:e = e || window.event;
        但是在這種調用方式(addEventListener、attachEvent方式)中沒什么作用,
        這是什么原因呢?上邊參考文章的總結里指出了原因,即:
        “IE6/7/8支持通過window.event獲取對象,
        通過attachEvent方式添加事件時也支持事件對象作為句柄第一個參數傳入”
        因為IE6/7/8在attachEvent方式添加事件時同時支持兩種方式,所以事件句柄中的參數e在
        IE6/7/8中會自動轉換為window.event。
        這么以來,這句e = e || window.event;在此處就不需要了(個人結論)。

        */


        /*  
        在編寫跨瀏覽器的函數庫時,IE和標准事件對象的屬性的差異的問題需要解決。
        下邊抽出相關代碼,討論這個問題在這里的體現。
        */
        var _E = {
            BindEvent: function (object, fun) {
                if (arguments.length == 1) {
                    fun = arguments[0];
                    object = null;
                }
                var args = Array.prototype.slice.call(arguments, 2);
                return function (event) {
                    return fun.apply(object, [fixEvent(event)].concat(args));
                }
            }
        };
        function fixEvent(event) {  // 統一不同瀏覽器的event對象
            if (event) return event;  
            event = window.event;
            event.pageX = event.clientX + getScrollLeft(event.srcElement);
            event.pageY = event.clientY + getScrollTop(event.srcElement);
            event.target = event.srcElement;
            event.stopPropagation = stopPropagation;
            event.preventDefault = preventDefault;
            var relatedTarget = {
                "mouseout": event.toElement, "mouseover": event.fromElement
            }[event.type];
            if (relatedTarget) { event.relatedTarget = relatedTarget; }

            return event;
        };
        function stopPropagation() { this.cancelBubble = true; };
        function preventDefault() { this.returnValue = false; };

        // 測試代碼如下
        function get(ev) {
            alert(ev.pageX);
        }
        var cc = document.getElementById("cc");
        var clickHandler = _E.BindEvent(get);
        cc.attachEvent('onclick', clickHandler);  // IE6/7/8下測試
        /*
        結果點擊id為cc的div元素后,彈出undefined。說明ev.pageX根本不存在。
        可是我們在fixEvent()里已經做了事件對象的統一工作。
        調試會發現:fixEvent()里if (event) return event;這句是執行后就直接return了,
        這里的event按照道理說應該是undefined,但是事實並不是。

        //
        至於原因個人覺得就是這里:因為IE6/7/8在attachEvent方式添加事件時同時支持兩種方式,
        所以事件句柄中的參數會自動轉換為window.event。也就是說參數不是undefined
        
        //
        所以在這里用if (event) return event;判斷事件對象不妥。
        (說明:fixEvent()這段代碼參考自博客園里cloudgamer的函數庫,
         他里邊就是這種寫法,個人覺得有錯誤,希望有興趣的朋友也做做驗證)
        */

    </script>
</body>
</html>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM