1. 程式人生 > >Javascript和jquery事件--事件監聽器

Javascript和jquery事件--事件監聽器

之前看完了js和jq的冒泡捕獲和事件物件event,這裡看看同時使用js和jq後我最容易混淆的監聽器的繫結。

(1) js的監聽器繫結解綁

繫結監聽器有兩種方式:

a.on-事件type,比如onclick,onfocus

  這種方式可以直接使用在html介面中:

    

<button onclick=’alert(‘點選成功!’)’>點選</button>

 

  也可以在js中使用:

    

btn.onclick=function(){};

btn.setAttribute('onclick', 'doSomething()');

 

   其實這個繫結方法有點像屬性,所以可以用setAttribute設定,而且只有一個值,所以它只能繫結一個事件,後面設的值會覆蓋前面的值。

如果進行解綁,直接用空值覆蓋,如果想要阻止事件的繼續觸發可以用onclick=“return false”阻止

 

 b.target.addEventListener()

  最標準的的繫結監聽器的方式,可以繫結多個監聽器。也可以使用removeEventListener進行解綁。

  傳入的是事件控制代碼,也就是不包含園括號的函式名。這樣也會導致一個問題,就是這個函式你沒有辦法傳參。Jq已經實現了傳參的封裝,而如果你想要在js中傳參,使用模組級變數,資料記錄在dom的data中等等,只能自己想辦法。

 c.target.attachEvent()

  和addEventListener()相似,不過是ie特有的,不符合W3C標,ie不支援addEventListener,對應的解綁方法是detachEvent()。不過 ie8以上已經不支援attachEvent(),反而支援addEventListent()了。至少我測試的時候的確是不支援attachListener(),而支援addEventListener()了。

 下面是一個相容的程式碼(引自https://www.cnblogs.com/zhn0823/p/5821505.html):

/**

* @description 事件繫結,相容各瀏覽器

* @param target 事件觸發物件

* @param type 事件

* @param func 事件處理函式

*/ function addEvent(target, type, func) { if (target.addEventListener) //非ie 和ie9 target.addEventListener(type, func, false); else if (target.attachEvent) //ie6到ie8 target.attachEvent("on" + type, func); else target["on" + type] = func; //ie5 }; /** * @description 事件移除,相容各瀏覽器 * @param target 事件觸發物件 * @param type 事件 * @param func 事件處理函式 */ function removeEvent(target, type, func){ if (target.removeEventListener) target.removeEventListener(type, func, false); else if (target.detachEvent) target.detachEvent("on" + type, func); else target["on" + type] = null; };

 

2、  jq的監聽器繫結解綁

jQuery中提供了四種事件監聽方式,分別是bind、live、delegate、on,對應的解除監聽的函式分別是unbind、die、undelegate、off。而這幾個函式的前面可以是一個jq物件集,有幾個物件就幫幾個物件繫結監聽器,如$(‘#myol li’).on()會幫該ol下所有的li繫結監聽器。

其他三種方法都是通過觸發on實現的,官方推薦的儘量使用on,但是其他方法也有各自的優勢。看原始碼看得我頭疼,那就不糾結了,暫時只分析各自的使用優勢應該就行了。

<1>on(type,[selector],[data],fn,/*INTERNAL*/ one)

其中,

  type就是事件名稱,比如“click”“dbclick”

  [selector]不懂,但是可以不用傳

  [data]是可以傳的資料、引數,函式裡面用event.data來獲取

  Fn是繫結的函式控制代碼

  one是用來區分只觸發一次的監聽器,當one===1時,只觸發一次

on為所有指定元素新增監聽器,如果元素用on繫結監聽器之後制定的元素有數量的增加,不會為新增加的元素繫結監聽器。

<2>bind(type,[data],function(eventObject))

這個方法就幾乎與on一模一樣了,只是剔除了selector的傳入,所存在的缺點也有

<3>live(type, [data], fn)

這個方法就克服了對新增元素無效的問題,它是將監聽器繫結在this.context(一般是document)上面,然後根據事件委託機制,根據currenttarget來獲取節點進行監聽事件。但是看效率來說,沒必要的時候還是使用on吧

<4>delegate(selector,type,[data],fn)

 引數多了一個selector,用來指定觸發事件的目標元素,監聽器將被繫結在呼叫此方法的元素上。這個也可以克服新增元素無效的問題,因為事件是繫結在父元素身上的。on方法中的selector應該就是專門為這個函式設計的吧?

  

$('#myol').delegate('li','click',getHtml);

  如上語句,點選每個li會觸發getHtml顯示li裡的文字,但是輸出的currentTarget是ol,target是點選的li,

3、  js監聽器的觸發

target.dispatchEvent(event);

該方法在當前節點上觸發指定事件,從而觸發監聽函式的執行。該方法返回一個布林值,只要有一個監聽函式呼叫了Event.preventDefault(),則返回值為false,否則為true。

var event = new Event('click');

add.dispatchEvent(event);

或者

var evt = document.createEvent( 'HTMLEvents' );

evt.initEvent('click', true, true);

add.dispatchEvent(evt);

 

舊版ie使用fireEvent(),事實上新版ie已經支援其他瀏覽器繫結解綁觸發監聽器的函數了,不想管了。

遺留問題:但是使用dispathchEvent()觸發超連結的操作上有問題,谷歌認為:“點選超連結下載檔案”是一個“預設響應”,而預設響應不應由指令碼觸發,所以從M53版本開始禁止所有由指令碼觸發的預設響應。火狐谷歌都不支援觸發超連結、ie支援。具體下面再具體討論。

Chrome瀏覽器M53更新後超連結的dispatchEvent(evt)方法無法觸發檔案下載:

  https://www.cnblogs.com/ljzc002/p/6003214.html

 

4、  jq監聽器的觸發

  $(selector).trigger(event,[param1,param2,...])

同時,不支援觸發超連結,在ie中也不觸發

 

參考:

1、js

http://www.cnblogs.com/dacuotecuo/p/3510823.html

https://www.cnblogs.com/huangjianwu/p/4536155.html

https://www.cnblogs.com/zhn0823/p/5821505.html

https://blog.csdn.net/namejs/article/details/50885698

https://blog.csdn.net/baihuaxiu123/article/details/53148780

2、jq

https://blog.csdn.net/lookbackward/article/details/78363997

http://www.cnblogs.com/webFrontDev/p/3509775.html

3、js觸發

https://blog.csdn.net/magic__man/article/details/51831227

https://www.cnblogs.com/ljzc002/p/6003214.html