方法和事件都不難理解,分開用也都沒問題,但是一起用就有些小問題出現。
直接上結論:使用trigger方法觸發一個文本類型的 input 元素的select事件時,chrome瀏覽器會錯誤的觸發三次,firefox和ie11只會正常觸發一次
解決辦法也簡單,把trigger換成triggerHandler()即可。
網上搜了下,有說是trigger()的方法的問題,有說是冒泡問題的,有說是select觸發機制的問題。
然而這些並沒有說服我,填補不了好奇心,所以找不到答案就自己嘗試
<html> <head> <script type="text/javascript" src="/jquery/jquery.js"></script> <script type="text/javascript"> $(document).ready(function(){ $("input").select(function(){ $("input").after("文本被選中!"); }); $("button").click(function(){ $("input").trigger("select"); }); }); </script> </head> <body> <input type="text" name="FirstName" value="Hello World" /> <br /> <button>激活 input 域的 select 事件</button> </body> </html>
這是代碼,點擊按鈕,會在頁面添加 文本被選中!的提示,但是會出現三次!!!
問題是在查api時在w3school時發現的,trigger可以觸發的事件那么多,前輩們故意選擇會出錯的select是為了提醒我們小心么0.0
給個鏈接,好奇的自己去試試http://www.w3school.com.cn/tiy/t.asp?f=jquery_event_trigger
首先發現時,第一反應是是不是jquery給元素的捕獲階段、目標階段、冒泡階段分別綁定了事件。
查看trigger說明,它會觸發所有匹配元素的指定事件。所以就換成了triggerHandler();然后果然只觸發一次了。
好開心有沒有,解決問題了有沒有。然而我就是那么閑的蛋疼
忍不住想,jQ那么出名流行的庫,沒理由綁定事件綁定的那么奇葩啊,捕獲目標冒泡全綁定,多層事件觸發要怎么搞?一個一個的阻斷事件?不可能啊。
所以又換回trigger,把input的select事件換成click。然后果然也只會觸發一次。
mouseover也一樣,這樣就確定了是select的問題,不是trigger的問題
然后好奇是否是選擇機制的問題,把文本內容刪至一字母----還是三次;刪完文本內容---兩次,看起來似乎和select的選中有些關系,但是這和他們說的觸發機制完全不同。
再試試事件問題。注釋了jQ的select事件綁定,用Dom2事件綁定了一個事件,當然,要給input一個id方便獲取
document.getElementById("FirstName").addEventListener('select', function() { console.log('false'); }, false);
然后一運行一點擊奇跡就出現了
完全超出預期啊有沒有
干脆就把捕獲和目標階段分別用Dom2級Dom0級給綁定了,為了方便查看事件觸發順序,把捕獲目標冒泡打印內容分別為1 2 3.
document.getElementById("FirstName").addEventListener('select', function() { console.log('1'); }, true); document.getElementById("FirstName").onselect=function(){ console.log('2');} document.getElementById("FirstName").addEventListener('select', function() { console.log('3'); }, false);
這次的結果是
事件是綁定了三個,trigger卻觸發了7次事件,由此可以證明,jQ沒有分別綁定捕獲目標冒泡,不然就是觸發7次了。
那問題出在哪里呢,仔細觀察目標階段被觸發了三次!
而且多次試驗以后發現,無論有無其他兩個階段的事件,無論三事件綁定順序,目標階段事件必然在最開始、最后、最中間,一共出現三次(冒泡和捕獲若有,則遵循綁定先后順序觸發各兩次)
刪除文本以后目標階段觸發兩次,到此select事件觸發多次的真正原因終於找到了。
處於某種原因trigger方法觸發select事件,會把select的目標階段事件重復觸發三次,而且捕獲階段和冒泡階段的也會分別觸發兩次。
那這個原因究竟是什么呢,為了弄明白,又在ie11和firefox上測試,發現兩個瀏覽器是正常的一次。
用firefox 查看控制台,多次實驗,發現三階段均只會觸發一次,且無論三事件綁定順序,目標階段事件必然在最開始觸發,冒泡和捕獲按照綁定順序觸發。
由於firefox和ie顯示正常,chrome異常,所以我猜測,應該要么,chrome對於trigger方法觸發select事件的處理比較提別;要么是jQ對trigger方法觸發select事件的內部處理有問題,而firefox和ie做了額外的優化。個人更傾向與前者。
因為也曾懷疑是w3school的jquery庫版本較舊的原因,換成了百度提供的jQ2.1.1的cdn但還是錯誤觸發三次
不過暫時沒有技術能力和時間成本再更深入的研究。寫個博客,也算是留個坑,以后研究了再補吧0.0