跨瀏覽器的事件處理程序

摘自 js權(quán)威指南第三版

第一個要創(chuàng)建的方法是addHandler()续语,它的職責(zé)是視情況分別使用DOM0 級方法冒萄、DOM2 級方
法或IE 方法來添加事件充易。這個方法屬于一個名叫EventUtil 的對象菇民,本書將使用這個對象來處理瀏覽
器間的差異禁筏。addHandler()方法接受3 個參數(shù):要操作的元素持钉、事件名稱和事件處理程序函數(shù)。
與addHandler()對應(yīng)的方法是removeHandler()篱昔,它也接受相同的參數(shù)右钾。這個方法的職責(zé)是移
除之前添加的事件處理程序——無論該事件處理程序是采取什么方式添加到元素中的,如果其他方法無
效,默認(rèn)采用DOM0 級方法舀射。

var EventUtil = {
    addHandler: function(element, type, handler) {
        if (element.addEventListener) {
            element.addEventListener(type, handler, false);
        } else if (element.attachEvent) {
            element.attachEvent("on" + type, handler);
        } else {
            element["on" + type] = handler;
        }
    },
    removeHandler: function(element, type, handler) {
        if (element.removeEventListener) {
            element.removeEventListener(type, handler, false);
        } else if (element.detachEvent) {
            element.detachEvent("on" + type, handler);
        } else {
            element["on" + type] = null;
        }
    }
};

這兩個方法首先都會檢測傳入的元素中是否存在DOM2 級方法窘茁。如果存在DOM2 級方法,則使用
該方法:傳入事件類型脆烟、事件處理程序函數(shù)和第三個參數(shù)false(表示冒泡階段)。如果存在的是IE 的
方法邢羔,則采取第二種方案驼抹。注意拜鹤,為了在IE8 及更早版本中運(yùn)行,此時的事件類型必須加上"on"前綴敏簿。
最后一種可能就是使用DOM0 級方法(在現(xiàn)代瀏覽器中,應(yīng)該不會執(zhí)行這里的代碼)惯裕。此時,我們使用
的是方括號語法來將屬性名指定為事件處理程序蜻势,或者將屬性設(shè)置為null撑刺。
可以像下面這樣使用EventUtil 對象:

var btn = document.getElementById("myBtn");
var handler = function() {
    alert("Clicked");
};
EventUtil.addHandler(btn, "click", handler);
//這里省略了其他代碼
EventUtil.removeHandler(btn, "click", handler);
var EventUtil = {
    addHandler: function(element, type, handler) {
        if (element.addEventListener) {
            element.addEventListener(type, handler, false);
        } else if (element.attachEvent) {
            element.attachEvent("on" + type, handler);
        } else {
            element["on" + type] = handler;
        }
    },
    getEvent: function(event) {
        return event ? event: window.event;
    },
    getTarget: function(event) {
        return event.target || event.srcElement;
    },
    preventDefault: function(event) {
        if (event.preventDefault) {
            event.preventDefault();
        } else {
            event.returnValue = false;
        }
    },
    removeHandler: function(element, type, handler) {
        if (element.removeEventListener) {
            element.removeEventListener(type, handler, false);
        } else if (element.detachEvent) {
            element.detachEvent("on" + type, handler);
        } else {
            element["on" + type] = null;
        }
    },
    stopPropagation: function(event) {
        if (event.stopPropagation) {
            event.stopPropagation();
        } else {
            event.cancelBubble = true;
        }
    }
};

以上代碼顯示够傍,我們?yōu)镋ventUtil 添加了4 個新方法。第一個是getEvent()挠铲,它返回對event
對象的引用王带。考慮到IE 中事件對象的位置不同市殷,可以使用這個方法來取得event 對象愕撰,而不必?fù)?dān)心指
定事件處理程序的方式。在使用這個方法時醋寝,必須假設(shè)有一個事件對象傳入到事件處理程序中搞挣,而且要
把該變量傳給這個方法,如下所示音羞。

btn.onclick = function(event) {
    event = EventUtil.getEvent(event);
};

在兼容DOM 的瀏覽器中囱桨,event 變量只是簡單地傳入和返回。而在IE 中嗅绰,event 參數(shù)是未定義
的(undefined)舍肠,因此就會返回window.event搀继。將這一行代碼添加到事件處理程序的開頭,就可以確
保隨時都能使用event 對象翠语,而不必?fù)?dān)心用戶使用的是什么瀏覽器叽躯。
第二個方法是getTarget(),它返回事件的目標(biāo)肌括。在這個方法內(nèi)部点骑,會檢測event 對象的target
屬性,如果存在則返回該屬性的值谍夭;否則黑滴,返回srcElement 屬性的值〗羲鳎可以像下面這樣使用這個方法袁辈。

btn.onclick = function(event) {
    event = EventUtil.getEvent(event);
    var target = EventUtil.getTarget(event);
};

第三個方法是preventDefault(),用于取消事件的默認(rèn)行為珠漂。在傳入event 對象后晚缩,這個方法
會檢查是否存在preventDefault()方法,如果存在則調(diào)用該方法甘磨。如果preventDefault()方法不
存在,則將returnValue 設(shè)置為false眯停。下面是使用這個方法的例子济舆。

var link = document.getElementById("myLink");
link.onclick = function(event) {
    event = EventUtil.getEvent(event);
    EventUtil.preventDefault(event);
};

以上代碼可以確保在所有瀏覽器中單擊該鏈接都不會打開另一個頁面。首先莺债,使用EventUtil.
getEvent()取得event 對象滋觉,然后將其傳入到EventUtil.preventDefault()以取消默認(rèn)行為。
第四個方法是stopPropagation()齐邦,其實(shí)現(xiàn)方式類似椎侠。首先嘗試使用DOM 方法阻止事件流,否
則就使用cancelBubble 屬性措拇。下面看一個例子我纪。

var btn = document.getElementById("myBtn");
btn.onclick = function(event) {
    alert("Clicked");
    event = EventUtil.getEvent(event);
    EventUtil.stopPropagation(event);
};
document.body.onclick = function(event) {
    alert("Body clicked");
};

在此,首先使用EventUtil.getEvent()取得了event 對象丐吓,然后又將其傳入到EventUtil.
stopPropagation()浅悉。別忘了由于IE 不支持事件捕獲券犁,因此這個方法在跨瀏覽器的情況下,也只能用
來阻止事件冒泡粘衬。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市勘伺,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌尺迂,老刑警劉巖冒掌,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件股毫,死亡現(xiàn)場離奇詭異,居然都是意外死亡祭陷,警方通過查閱死者的電腦和手機(jī)趣席,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進(jìn)店門宣肚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人霉涨,你說我怎么就攤上這事÷ジ洌” “怎么了往枷?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵错洁,是天一觀的道長。 經(jīng)常有香客問我墓臭,道長窿锉,這世上最難降的妖魔是什么膝舅? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任仍稀,我火速辦了婚禮埂息,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘享幽。我一直安慰自己拾弃,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布奔坟。 她就那樣靜靜地躺著咳秉,像睡著了一般鸯隅。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上霎奢,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天饼灿,我揣著相機(jī)與錄音碍彭,去河邊找鬼悼潭。 笑死,一個胖子當(dāng)著我的面吹牛舰褪,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播略就,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼窄绒!你這毒婦竟也來了崔兴?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤位谋,失蹤者是張志新(化名)和其女友劉穎倔幼,沒想到半個月后爽待,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡膏燃,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年组哩,在試婚紗的時候發(fā)現(xiàn)自己被綠了处渣。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,566評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡黍衙,死狀恐怖琅翻,靈堂內(nèi)的尸體忽然破棺而出柑贞,到底是詐尸還是另有隱情,我是刑警寧澤钧嘶,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站闸拿,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏胸墙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一但骨、第九天 我趴在偏房一處隱蔽的房頂上張望智袭。 院中可真熱鬧,春花似錦吼野、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至嘀倒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間灌危,已是汗流浹背碳胳。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留浅蚪,地道東北人烫罩。 一個月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓洽故,卻偏偏與公主長得像,于是被迫代替她去往敵國和親隘弊。 傳聞我的和親對象是個殘疾皇子哈踱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 事件處理程序有DOM0級事件處理程序开镣、DOM2級事件處理程序邪财,IE事件處理程序质欲,DOM0級事件處理程序具有簡單,跨...
    小囧兔閱讀 221評論 0 0
  • JavaScript 程序采用了異步事件驅(qū)動編程模型写半。在這種程序設(shè)計風(fēng)格下绊袋,當(dāng)文檔、瀏覽器愤炸、元素或與之相關(guān)的對象發(fā)...
    劼哥stone閱讀 1,252評論 3 11
  • 以下文章為轉(zhuǎn)載掉奄,對理解JavaScript中的事件處理機(jī)制很有幫助,淺顯易懂诞仓,特分享于此。 什么是事件墅拭? 事件(E...
    jxyjxy閱讀 3,028評論 1 10
  • 馬云這次演講的全文大概有9300多字,很長。如果近半年你一直關(guān)注馬云箱季,這次演講內(nèi)容的后半部分你應(yīng)該都看到過棍掐,但如果...
    海岸線心理劉億閱讀 2,390評論 0 0
  • 都說機(jī)會是留給有準(zhǔn)備的人,那么什么是機(jī)會作煌,什么是準(zhǔn)備。 機(jī)會是契機(jī)杯巨,是緣分努酸,是佛法自然,道法超然的論調(diào)获诈,因?yàn)槟阏f不...
    譚惜言閱讀 1,030評論 0 5