溫故而知新-JavaScript事件與兼容性相關

w簡書的markdown不支持[toc]? ??

不知不覺,從開始做android的項目后就很少寫JS了,最近項目中需要用到大量的H5,也來湊湊HTML5開發的熱鬧。。。當然前提要學好JS,好記性不如爛筆頭,開始學著寫點筆記,提升學習效率~

這里只是記錄一些比較容易忘記,API之類的需要時再去查閱

[toc]

事件對象

接受對象的差異性

W3C可直接通過參數接收事件對象,而IDE自己定義了一個Event對象,通過window.event獲取。

兼容獲取事件對象的代碼
    <input type="button" id="btn" value="提交"/>
    <script>
        var btn = document.getElementById("btn");
        btn.onclick = function(event){
            var e = event || widnow.event;
            alert(e);
        }
    </script>

鼠標事件

鼠標事件的兼容性問題

onmousemove:鼠標移動
onmousedown:鼠標點擊
onmouseup:鼠標松開
onmouseover:鼠標移動到元素區域內
onmouseout :鼠標移出元素

在這三個事件對象中,有一個button屬性,表示按下或者釋放的按鈕,遺忘的是對于這個button屬性,坑爹的IE也與W3C不同(怪不得你爹不要你了)

W3C中的button屬性

IE中的button屬性

可以看出,IE和W3C在button屬性上各個數值所表示的按鈕和狀態都不一樣,但是一般我們只需要兼容W3C那三種就好了
兼容代碼

 function getButton(evt) {
            var e = evt || window.event;
            if (evt) {
                return e.button;
            } else
                if (window.event) {
                    switch(e.button) {
                        case 1 :
                            return 0;
                        case 4 :
                            return 1;
                        case 2 :
                            return 2;
                }
            }
        }

        document.onmouseup = function (evt) {
            if (getButton(evt) == 0) {
                alert('按下了左鍵!');
            } else if (getButton(evt) == 1) {
                alert('按下了中鍵!');
            } else if (getButton(evt) == 2) {
                alert('按下了右鍵!' ); }
        };

鼠標事件-可視區和坐標的獲取

可通過clienX,screex獲取,這個就不記錄了,查一下文檔即可

鍵盤事件

onkeydown
onkeypress:只對能在屏幕上輸出字符的按鈕有效果
onkeyup


屬性:
keyCode:鍵碼---獲取一個代碼,與鍵盤特定的鍵對應,與ASCII碼中對應的編碼相同(不區分大小寫)
charCode:字符編碼 --- 只有在keypress中才包含值,對應的是鍵所代碼的字符的ASCII編碼(區分大小寫)
document.onkeypress = function (event) {
    alert("charCode == "+ event.charCode); //得到相應的 charCode

};
document.onkeydown = function (event) {
    alert("keyCode == "+ event.keyCode); //得到相應的 keyCode

};

兼容性問題:

不同瀏覽器中,獲取的keyCode(鍵碼)和charCode(字符編碼)有可能不一樣,要謹慎操作

事件對象的其他屬性

![](http://upload-images.jianshu.io/upload_images/205088-36015df534702463.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

事件冒泡

事件流:當幾個具有事件的元素疊在一起的時候,那么你點擊一個元素后,所有層疊在你點擊范圍內的元素都會觸發事件。

來個簡單的圖感受一下。

屏幕快照 2016-04-17 上午12.01.00.png

Button,紫色和藍色的DIV都具有點擊事件,因為Button在最內層,當點擊button時,click事件會從內往外觸發----這就是事件冒泡(特征:從里往外觸發)
事件捕獲:與事件冒泡相反,是從外往內觸發

阻止冒泡

從前面的==事件的其他屬性==中看到,關于阻止事件冒泡IE和W3C有不同的屬性

IE:是通過cancelBubble = true 取消事件冒泡
W3C:調用stopProgagation()方法取消事件冒泡

阻止的兼容方法

function stopPro(event) {
    var e = event || window.event;
    window.event ? e.cancelBubble = true : e.stopPropagation(); }

事件的綁定

事件的綁定有兩種方式
一,傳統的事件綁定,分為內聯模型,腳本模型
二,DOM2級的現代事件綁定

傳統的事件綁定

內聯模型

基本上很少用,維護起來簡直想殺人。。。
下面這兩種形式

    <input value="點擊" id="btn" type="button" onclick="alert('aaa')">
   <input value="點擊" id="btn" type="button" onclick="btnOnclick()">

腳本模型

即用JavaScript獲取DOM設置事件

傳統事件綁定的問題

一、多次綁定會被覆蓋

很直觀的問題,重復綁定會覆蓋掉前面的
  /*缺點1:綁定多次會被覆蓋 */
  window.onload = function(){
    alert("onload 111111");
  }
  window.onload = function(){
    alert("onload 2222222");
  }

二、this的指向問題

  var myDiv = document.getElementById("myDiv");
  myDiv.onclick = toBlue;
  function toBlue(){
      alert(this);//第一次就是DivElement   第二次就是window了
      this.className = "blue";
      this.onclick = toRed;
  }
  function toRed(){
      this.className = "red";
      this.onclick = function(){
            toBlue();
      }
  }

三、too much recursion的問題

當你不停的add事件時,可能會報出too much recursion的錯誤,這是因為你積累了太多的保存事件,太多遞歸導致瀏覽器卡死。
解決方法:用完的事件,立即處理掉

        var myDiv = document.getElementById("myDiv");
        //可以通過[]的形式獲取綁定事件
        myDiv['onclick'] = function(){
            alert("aaa");
        };

        /**
         *  obj : 要移出的元素
         *  type: 要移出的事件類型 click等
         **/
        function removeEvent(obj,type){
            if(obj['on'+type]) obj['on'+type] = null;
        }

W3C事件處理

DOM2級中,定義了addEventListener和removeEventListener方法。最后一個參數 true:表示捕獲,false:表示冒泡

一,解決了this的指向問題,再也不怕too much recursion了

我們將上面this指向的代碼稍微修改一下
            var myDiv = document.getElementById("myDiv");

            myDiv.addEventListener('click',toBlue);
            function toBlue(){
                alert(this);//都是DivElement
                this.className = "blue";
                this.addEventListener('click',toRed);
            }
            function toRed(){
                this.className = "red";
                myDiv.addEventListener('click',function(){
                    toBlue();
                });
            }

二,解決重復綁定覆蓋的問題

 var myDiv = document.getElementById("myDiv");
 myDiv.addEventListener('click',function(){
     alert("event 11111");
 })
 /**
 * 不再覆蓋,兩個都會執行,共存
 * */
 myDiv.addEventListener('click',function(){
     alert("event 222222");
 })

IE的事件處理函數

IE9就全面支持W3C的事件函數了,這里就做個簡單的了解

提供了兩個方法:
attachEvent()
detachEvent()

幾個不同點

1,IE不支持捕獲,只支持冒泡
2,IE不能屏蔽重復的函數
3,IE中this指向的是window對象
4,之前說到,IE在傳統事件中接收不到event事件對象的
但是attchEvent可以做到。。。真是讓人爪機

不想裝個IE瀏覽器,這就不測試了,做個簡單的記錄,方便以后用到的時候查詢

添加/刪除事件,得到事件對象的兼容代碼

    //添加事件兼容
    function addEvent(obj, type, fn) {
        if (obj.addEventListener) {
            obj.addEventListener(type, fn);
        } else
                if (obj.attachEvent) {
                   obj.attachEvent('on' + type, fn); }
    }

    //移除事件兼容
    function removeEvent(obj, type, fn) {
        if (obj.removeEventListener) {
            obj.removeEventListener(type, fn);
        } else if (obj.detachEvent) {
             obj.detachEvent('on' + type, fn);
        }
    }
    //得到事件目標
    function getTarget(evt) { if (evt.target) {
        return evt.target;
    } else if (window.event.srcElement) {
        return window.event.srcElement; }
    }

事件其他補充(主要是兼容方面)

獲取移入和移出的DOM對象的兼容問題

 W3C版:事件對象屬性:relatedTarget
 IE版:fromElement 和 toElement,分別對應 mouseover 和 mouseout。

不同的實現,又需要兼容的代碼~

 function getTarget(evt) {
        var e = evt || window.event;
        if (e.srcElement) {//如果支持,就是IE瀏覽器(srcElement:事件目標)
            if (e.type == 'mouseover') {
                return e.fromElement;
            } else if (e.type == 'mouseout') {
                return e.toElement;}
        } else if (e.relatedTarget) {
            //如果支持 relatedTarget,表示 W3C ;
            return e.relatedTarget;
        }
    }

取消事件默認行為的兼容性問題

場景:取消超鏈接的默認行為.

解決方法一:
設置 return false。
缺點:
1)、必須寫在最后,那么中間的代碼執行后,
可能執行不到return false;(例如中間報錯了,但是頁面依舊會跳轉)
2)、如果寫在最前面,那么就無法做一些跳轉判斷了(通過一段邏輯判斷后才決定是否跳轉)
` <a id="aLink" >aaaa</a>`
    var aLink = document.getElementById("aLink");
    aLink.onclick = function(){
        /**
         *
         * */
        var person = function(){

        }
        var p = new Person();
        p.show();//這里沒有show方法,報錯了,所以后面的return false沒有執行到,頁面依舊跳轉了
        return false;
    }
解決方法二:取消事件的默認行為

W3C:event.preventDefault(); IE:window.event.returnValue = false;

頭疼,又需要兼容。。。

兼容代碼
    function preDef(event) {
        var e = event || window.event;
        if(e.preventDefault) {
            e.preventDefault();
        }else {
            e.returnValue= false;
        }
    }

oncontextmenu事件

可用于取消右鍵事件,提升瀏覽器性能

    window.document.oncontextmenu = function(event){
        var e = event || window.event;
        if(e.preventDefault) {
            e.preventDefault();
        }else {
            e.returnValue= false;
        }
    }
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,431評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,637評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,555評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,900評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,629評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,976評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,976評論 3 448
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,139評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,686評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,411評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,641評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,129評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,820評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,233評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,567評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,362評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,604評論 2 380

推薦閱讀更多精彩內容

  • 以下文章為轉載,對理解JavaScript中的事件處理機制很有幫助,淺顯易懂,特分享于此。 什么是事件? 事件(E...
    jxyjxy閱讀 3,060評論 1 10
  • 有關jQuery 事件模塊結構部分的分析可以參考這篇文章,作者分析的很不錯,贊一個。 進題之前,有幾個名詞 Eve...
    江楓閱讀 1,464評論 1 13
  • 聲明:本文來源于http://www.webzsky.com/?p=731我只是在這里作為自己的學習筆記整理一下(...
    angryyan閱讀 7,079評論 1 6
  • JavaScript 程序采用了異步事件驅動編程模型。在這種程序設計風格下,當文檔、瀏覽器、元素或與之相關的對象發...
    劼哥stone閱讀 1,273評論 3 11
  • 上海是個神奇的城市,她不問你的出生,學歷,不會鄙視你家庭條件,她只看你是否努力,真的。
    徐利奧小朋友的心情閱讀 262評論 0 1