簡體   English   中英

如何使用jQuery觸發表格內的按鈕?

[英]How can I trigger a button inside a table using jQuery?

當用戶單擊<tr>標記對象時,我試圖觸發一個按鈕(在我的表中),如下所示:

  $(document).ready(function(){ $('body').on('click', 'tr', function(){ var tridx = $(this).data('track-id'); $('td div#play'+tridx).click(); }); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <table class="sortable"> <thead> <tr> <th data-sort="nope">id</th> <th data-sort="name">Artist</th> <th data-sort="name">Title</th> <th data-sort="name">Genre</th> <th data-sort="duration">Duration</th> <th data-sort="date">Release</th> </tr> </thead> <tbody> <tr data-track-id="252"> <td> <div data-track-name="1" data-track-id="252" id="play252" class="playbtn252" style="display: none;"></div> <div id="countlist252" data-count-list="1" style="display: block;">1</div> </td> <td>Simon Deoro</td> <td>1</td> <td>1</td> <td>3:47</td> <td>2016-12-06</td> </tr> <!-- more tr --> </tbody> </table> 

tridx是正確的,但是我從控制台收到此錯誤:

未捕獲的RangeError:超出最大調用堆棧大小

我的代碼有什么問題,我無法理解看來一切正確嗎?

問題在於您的函數調用(處理click事件)是遞歸的。

jQuery的.on(...)捕獲指定選擇器(在您的情況下為tr及其下所有內容的click事件。 因此, tr 內部按鈕的click事件也會觸發您定義的匿名函數。

在您的方案中,這是不理想的,因為用戶的點擊會觸發另一個click事件,觸發另一個click事件,依此類推。

從函數內部對函數的每次調用都會在調用堆棧上生成一個新條目,該條目最終會變得太大而倒塌。 (這就是您所看到的症狀。)僅當函數實際返回時,堆棧才收縮回縮……(這對您而言從來沒有發生)。

有多種方法可以避免此問題。 可能最簡單:只需忘記在按鈕本身上具有單擊處理程序即可(因為按鈕的單擊始終會觸發包含tr click事件)。

或者,您可以告訴jQuery停止在DOM樹上應用click事件。

引用有關此主題的jQuery文檔:

默認情況下,大多數事件從原始事件目標冒泡到文檔元素。

在此過程中的每個元素上,jQuery都會調用已附加的所有匹配事件處理程序。 處理程序可以通過調用event.stopPropagation()來防止事件在文檔樹中冒泡(從而阻止這些元素上的處理程序運行event.stopPropagation()

但是,附加在當前元素上的任何其他處理程序都將運行。

為防止這種情況,請致電event.stopImmediatePropagation() (綁定到元素的事件處理程序的調用順序與其綁定的順序相同。)

引用: http : //api.jquery.com/on/


在半相關的說明中,我強烈建議以一種盡可能清晰地分離事件處理程序與私有方法與公共方法的方式來構造jQuery代碼。 如何做到這一點有很多“建議”(我當然不能說標准!)-我個人最喜歡的是這里: https : //stackoverflow.com/a/5947280/817132

使用此方法,我為所有UI代碼創建了一個“命名空間”(假設它只是一個小的代碼庫),並具有一個“設置”功能(由onReady調用),該功能將所有事件處理程序連接到其相關選擇器。 這些事件處理程序盡可能地少,主要是調用包含真實邏輯的私有函數。

根據個人喜好,我盡可能避免使用匿名功能。 我將引用附加到函數上。


在半相關的筆記上……如果您還沒有,我強烈建議您掌握瀏覽器的開發人員工具。 (我個人最喜歡的是Chrome隨附的產品。)

專門研究斷點和學習如何在使用手表步驟一行一行(和進出的函數)。

例如: https : //developers.google.com/web/tools/chrome-devtools/javascript/add-breakpoints

正如我在評論中提到的,原因是在同一TR內的元素上遞歸生成click事件。

只需在單擊播放按鈕之前檢查單擊事件是否不是來自播放按鈕:

$(document).ready(function(){
  $('body').on('click', 'tr', function(e){
    var tridx = $(this).data('track-id');
    var $button = $('td div#play'+tridx);
    if (!$button.is(e.target))
    {
        $button.click();
    }
  });
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM