- 問題引入,先貼一段有問題的代碼,如果你對 trigger() 這個函數了解不透徹,還真看不出這段代碼錯在哪。完成的功能是樣式轉換器,想讓頁面在加載后自行觸發點擊事件隱藏三個按鈕,但是效果如圖並沒有隱藏按鈕們:
控制台會報錯:
target 屬性是 undefined ,肯定是 event 這個事件對象沒獲取到的問題,程序到17行出錯停止,這讓我感到疑問:自定義觸發的事件難道沒有event對象嗎?。
1 <div id="switcher" class="switcher"> 2 <h3>Style Switcher</h3> 3 <button id="switcher-default">Default</button> 4 <button id="switcher-narrow">Narrow</button> 5 <button id="switcher-large">Large</button> 6 </div> 7 <script type="test/javascript"> 8 function func(){ 9 if(!$(event.target).is('button')){ 10 $('#switcher button').toggle('slow'); 11 } 12 } 13 function setBodyClass(classname){ 14 //... 15 } 16 $('#switcher').on('click',function(){ 17 if($(event.target).is('button')){ 18 var classbody=event.target.id.split('-')[1]; 19 setBodyClass(classbody); 20 } 21 }).on('click',func); 22 $('#switcher').trigger('click'); 23 </script>
- 問題思考,看看到底有沒有事件對象, undefined 表明居然沒有,千萬別以為jQuery真的不支持自定義的事件對象其實這里是代碼寫的方式不對才導致 undefined ,后面會有詳細代碼驗證!
1 $('#switcher').on('click',function(){ 2 //if($(event.target).is('button')){ 3 // var classbody=event.target.id.split('-')[1]; 4 //setBodyClass(classbody); 5 //} 6 console.log(event); 7 }); 8 9 $('#switcher').trigger('click');
迷惑不解的我查看了下jQuery官方文檔最后一句說:“盡管 trigger() 模仿了激活事件的作用,完成與合成事件對象,它不完全復制的天然發生的事件”。為啥文檔居然說有事件對象,只不過這個事件對象和天然的事件對象不一樣。之前我還以為人工觸發是不是就沒有 event 事件對象,人工觸發只是在機械地執行事件處理程序才導致的 undefined 。。。
As of jQuery 1.3,.trigger()
ed events bubble up the DOM tree; an event handler can stop the bubbling by returningfalse
from the handler or calling the.stopPropagation()
method on the event object passed into the event. Although.trigger()
simulates an event activation, complete with a synthesized event object, it does not perfectly replicate a naturally-occurring event.
既然沒有 event 就執行不了,那就造一個事件對象,看到官網給了這樣的示例,自行創建一個 jQuery.Event() 的實例事件對象:
var event = jQuery.Event( "submit" );
$( "form:first" ).trigger( event );
if ( event.isDefaultPrevented() ) {
// Perform an action...
}
- 問題驗證,相應我的代碼就要改成:(這也是創建 jQuery.Event 實例對象方式一)
1 $('#switcher').on('click',function(event){ 2 if($(event.target).is('button')){ 3 var classbody=event.target.id.split('-')[1]; 4 setBodyClass(classbody); 5 } 6 console.log(event) 7 }).on('click',func); 8 9 var e=jQuery.Event('click');//可以省略new 關鍵字 10 $('#switcher').trigger(e);
看看這個自創的事件對象是什么東西, target 屬性終於是我想要的了。
- 1.使用 triggle() 應注意的問題,同一個元素的自定義的觸發代碼要寫在其綁定事件處理程序代碼之后,不然執行自定義觸發代碼時找不到事件處理程序會告終而亡。
2.創建 jQuery.Event 實例對象方式二 ele.trigger('eventType') 直接創建
//包含事件處理程序1
1 $(document).ready(function(){ 2 $('#switcher').trigger('click');
3 })
//包含事件處理程序2 4 $('#switcher').on('click',function(){ 5 console.log(event); 6 if($(event.target).is('button')){ 7 var classbody=event.target.id.split('-')[1]; 8 setBodyClass(classbody); 9 } 10 })
target 是 document ,可以看出 trigger() 如果不傳參事件對象,則事件處理程序2的 event 是上一個事件對象即執行 $('#switcher').trigger('click'); 所在事件處理程序1里的事件對象。若傳了事件對象的參數則會將事件處理程序2中的默認傳入的 event 覆蓋掉成為新的由 trigger() 觸發的事件對象(上面的 document 例子)或直接傳入由 trigger() 觸發的事件對象(事件處理程序2現在沒有 event 所以不用覆蓋,下面例子):
1 $('#switcher').on('click',function(event){ 2 console.log(event); 3 if($(event.target).is('button')){ 4 var classbody=event.target.id.split('-')[1]; 5 // setBodyClass(classbody); 6 } 7 }) 8 $('#switcher').trigger('click');
這個由 trigger() 觸發得來的事件對象是 jQuery.Event() 的實例對象,看到 target 屬性正確我就放心了。
- 總結:創建自定義的事件對象有兩種方式,你可以用 ele.trigger('eventType'); 自定義觸發事件(當然這句一執行就自動構造了一個 jQuery.Event 實例事件對象),也可以用不帶 new 關鍵字構造事件對象。但傳不傳這個事件對象的參數就看你事件處理程序中需要不需要了,不傳意味着事件處理程序里的 event 為 undefined (在不存在上一個事件對象情況下)或使用上一個 event 事件對象,傳了就意味着事件處理程序中的事件對象是由 trigger() 得來的 jQuery.Event 實例對象。
- 參考:http://api.jquery.com/trigger/