1. 程式人生 > >jQuery 巢狀 event 會觸發多次的原因?

jQuery 巢狀 event 會觸發多次的原因?

 最近,在公司做專案時,發現在click中巢狀click事件,會發生多次呼叫的問題,經過查詢相關資料 ,特整理。文中有參考https://segmentfault.com/q/1010000000458432等。

HTML程式碼:

<div id="cover">
  <input type="button" id="inside" value="submit_inside" />
</div>
<div id="cover_js">
   <input type="button" id="inside_js" value="submit_inside_js" />
</div>
<input type="button" id="outside" value="submit_outside" />


JS程式碼:

$('#cover').mouseover(function () {
  $('#inside').click(function () {
    alert('multiple times');
  });    
});

$('#cover_js').mouseover(function () {
  document.getElementById('inside_js').onclick = function () {
    alert('just one time');
  }    
});

$('#outside').click(function () {
  alert('just one time');
});


隨後,本人又進行了原生js中addEventListener,發現不論是jQuery的事件(click,mouseover等),還是原生的addEventListener,或者原生的onclick,只要放在外層函式,而內層函式是jQuery的事件繫結,或者原生addEventListener,都會有事件累積的效應。但是如果內層函式是onlick,則不會有事件累積發生。 

以上是發現的規律,解決方法有:

1.unblind方法

$('#cover').mouseover(function () {
  $('#inside').unbind('click').click(function () {
    alert('multiple times');
  });    
});


2.儘可能不要使用事件巢狀,把事件拆出來

3.通過定義一個相反的外層事件解綁內嵌的事件

var foo = function () {
    alert('multiple times');
};

$('#cover').mouseover(function () {
    $('#inside').bind('click', foo);        
});

$('#cover').mouseout(function () {
    $('#inside').unbind('click', foo);
});


4.通過定義一個 flag 變數來阻止內嵌事件的累加

var flag = true;

var foo = function () {
    alert('multiple times');
};

$('#cover').mouseover(function () {
    if (flag) {
        $('#inside').bind('click', foo);
        flag = false;
    }
});


產生這種現象的原因(照搬過來了):

  1. 所有的事件繫結(.click.mouseover.hover 等等)都是委託給更底層的 .on 方法的,通過檢視其原始碼得知 .on 最終會呼叫 $.event.add 方法

  2. 我沒有細細去看 $.event 物件的全部內容,只是看到這一行的時候,我似乎有些明悟了。

    1. jQuery 為每一個事件回撥函式生成一個 guid,保證它們都是獨一無二的(即使函式內容相同)

    2. 如果你繼續往後看,會發現這些回撥函式都被 push 到一個數組裡儲存,所以當時間觸發的時候,它們也應該是一個個從數組裡取出來再執行(或許是為了保證註冊在同一事件下不同回撥函式的執行順序,但是像你這樣內容一樣的回撥函式就不好判斷了,所以如果你不得不多次繫結內容一樣的回撥,先解綁)。這就是為什麼會產生你問題中效果的原因。

  3. 至於 jQuery 為什麼要這樣去設計我還沒有去求證,我猜是為了更強大的事件管理能力,至於 bind after unbind 這樣的副作用也許在 jQuery Team 看來是微不足道的犧牲吧。


相關推薦

jQuery event 觸發原因

 最近,在公司做專案時,發現在click中巢狀click事件,會發生多次呼叫的問題,經過查詢相關資料 ,特整理。文中有參考https://segmentfault.com/q/1010000000458432等。 HTML程式碼: <div id="cover"&g

jQuery 嵌套 event 觸發原因

document button 鼠標 div 結果 rip multipl sub javascrip Html代碼如下: <div id="cover"> <input type="button" id="inside" value="submit

JQuery Mobile - 為什麽綁定事件後執行?

ext csdn 一個 修改 min 兩種 密碼 mon info JQuery Mobile 在綁定事件時候,發現會被多次執行,為什麽啊? 原來,jquery click 不是替換原有的function ,而是接著添加,所以才會執行次數越來越多,怎麽辦才能按需實現功能?

EPOLL在ET模式下觸發麼?

前幾天和同學一起討論EPOLLONESHOT的作用,它的功能是這樣的: 對於註冊了EPOLLONESHOT事件的檔案描述符,作業系統最多觸發其上註冊的包括可讀,可寫,錯誤中的一個,且只觸發一次 剛一看感覺EPOLLONESHOT咋麼就是ET模式相對於LT模

工作總結 頁面通過ajax 動態綁定 列表頁面 列表每一項的事件 事件觸發

什麽 就會 clas 方法調用 ack gpo 註冊 沒有 ajax 遇到一個問題 困惑了兩天 頁面的事件不知道為什麽觸發多次 試了各種辦法 對比了之前的頁面 各種測試 不是js css 外部鏈接 重復加載問題 也不是嵌套的 div 問題 各種都試過 最終發現 是

#JS 視窗resize避免觸發

window視窗改變時觸發resize,如何避免多次執行,設定一個300ms定時器即可。 //視窗變化監聽,避免resize多次執行卡頓 var resizeTimer = null; $(window).bind('resize', function () { if (resizeTi

解決Extjs一雙擊觸發單擊事件,和一雙擊事件

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興! 給我老師的人工智慧教程打call!http://blog.csdn.net/ji

Phillip and Trains 【CodeForces】【為什麼BFSMLE總結教訓】

題目連結     這道題其實不難,但卻給予了我需要總結的東西,因為當你做bfs的時候,我看這道題是往一個方向的所以就沒考慮是否遍歷過這個問題,但是,確實會重複經過同一個節點的。。。QAQ.....     題目是一個換參考系的BFS裸題,就是告訴你有個人,躲火車,每次往前

ListViewListView,TextView有行文字顯示不全不問題

這是在網上找到的相關的解決方法,記錄下來,方便以後檢視。 關於ListView巢狀ListView,在網上找到的解決方法是呼叫自定義的方法動態計算listview的高度: public void setListViewHeightBasedOnChildren(ListVi

sql的查詢,把一查詢的結果做為表繼續進一步查詢;內聯檢視

Mysql的巢狀表查詢   巢狀SELECT語句也叫子查詢,一個 SELECT 語句的查詢結果能夠作為另一個語句的輸入值。子查詢可以: 出現在Where子句中, 出現在from子句中,作為一個臨時表使用, 出現在select list中,作為一個欄位值來返回。 示例 1、出現在whe

echarts例項 動態更新 資料問題,點選事件觸發

function reloadTable() { var iii = layer.load(1, {shade: [0.1,'#fff'] });//提交的動畫 url = "change/query?selectType=" + $("#select

mybatis 高階結果對映關聯的查詢、一對查詢

這是mybatis的官方例子,基本上看一遍就會了,一定要先去看官方例子,這裡介紹的不詳細 http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html#select 我自己用的聯表查詢 實體類 public class MemberSaleR

Jquery點選事件只觸發的解決方法

方案一: <script> $(function () { $("#all").click(function(){ if(this.checked){ $("#list :checkbox").attr

quartz 暫停後重新啟動,在暫停時 被暫停後的任務,在啟動後補償執行即 連續呼叫job中的execute方法。

public String add() throws IOException, SchedulerException {// 一定要緊跟Validate之後寫驗證結果類String seconds = job.getCronExpression();//String cronExp = "0/" + sec

引入zepto後,用tap事件,為什麼有時候觸發,找不到根本原因??

1原因及解決方案最新版Chrome綁定了三個事件touchend MSPointerUp pointerup,touchend是觸控相關的事件,MSPointerUp 是ie10的觸控事件,pointerup是指標事件。可能是以前的chrome不支援pointerup事件,現

sui mobile 無限滾動時會觸發請求問題

首先,說問題之前,首先我們先看一下sui mobile 官網無限滾動的實現程式碼,(這裡主要是說底部無限滾動)。  官網中提到,要實現無限滾動,只需要“在可滾動的容器上新增“infinite-scroll”類,一般是頁面滾動區域 - div.content” 其中,

JQuery-02】事件繫結造成執行

問題描述:必現。先刪除A記錄,再新增A記錄,再刪除B記錄時,會連同AB一起刪除。 原因: 在彈出確認是否刪除的對話方塊中,註冊的事件{記錄id,如果點選確定則刪除該id對應的記錄;},該modaldialog一直在dom中,每刪除一次就會繫結一次。 A已經被

iOS 點贊機制(防止按鈕重複點選觸發請求)

一、在按鈕的點選事件中實現下面方法:// 防止重複點選觸發多次請求        [[selfclass] cancelPreviousPerformRequestsWithTarget:selfsel

Flink window ReduceFunction 在一個事件到來的時候被觸發

今天有一個同學在群裡面問了如下一個問題:“每輸入條記錄,都會立即執行四次。。”------因為一直都是用的event time + watermark的方式來做的流,不太清楚他這個情況。一度以為是事件被複制了多份,導致了視窗Function被觸發多次。後來看了一下原始碼,發現

ListViewRadioButton導致的

1、首先ListView獲取點選事件需要設定RadioButton的焦點android:focusable=”false” 2、通過一個List集合管理所有的RadioButton,然後在點選事件中,清空所有的狀態。private List<RadioB