我們有個舊專案使用早期的jQuery 1.2,剛巧新增功能的動態建立新元素讓原有的事件無法被觸發,測試後才知道「既有元素」的事件程式無法套用給「未來動態建立的元素」,在jQuery 1.7後使用 .on() 就能有效處理既有與未來元素的事件操作了。
▼ 測試網頁
靜態 tr 元素一切正常
表格 TABLE1 原本有5個靜態的 tr,點擊換背景色與刪除、修改等皆能正常運作。但按下〔Add〕動態新增的 tr 完全無法觸發這些 click 事件。
<html> <head> <script src="https://code.jquery.com/jquery-1.11.3.min.js"></script> <style> .highlight { color: white; background-color: highlight; } </style> </head> <body> <input type="button" id="btnAdd" value=" Add "> <span id="SPAN1"></span> <table id="TABLE1" border="1"> <tbody id="TBODY1"> <tr class='row'><td>static text 1</td><td><input type='Button' value='Delete' class='delButton'><input type='Button' value='Edit' class='editButton'></td></tr> <tr class='row'><td>static text 2</td><td><input type='Button' value='Delete' class='delButton'><input type='Button' value='Edit' class='editButton'></td></tr> <tr class='row'><td>static text 3</td><td><input type='Button' value='Delete' class='delButton'><input type='Button' value='Edit' class='editButton'></td></tr> <tr class='row'><td>static text 4</td><td><input type='Button' value='Delete' class='delButton'><input type='Button' value='Edit' class='editButton'></td></tr> <tr class='row'><td>static text 5</td><td><input type='Button' value='Delete' class='delButton'><input type='Button' value='Edit' class='editButton'></td></tr> </tbody> </table> </body> </html> <script> var iCurrentRowIndex_ = -1; $(document).ready(function() { $("#btnAdd").click(function() { $("#TBODY1").append("<tr class='row'><td>" + (new Date()) + "</td><td><input type='Button' value='Delete' class='delButton'><input type='Button' value='Edit' class='editButton'></td></tr>"); }); $(".row").click(function() { if (iCurrentRowIndex_ > -1) { $('.row:nth-child(' + (iCurrentRowIndex_+1) +')').removeClass('highlight'); } $(this).addClass('highlight'); iCurrentRowIndex_ = $(this).index(); }); $(".delButton").click(function() { $(this).parent().parent().remove(); }); $(".editButton").click(function() { var tr = $(this).parent().parent(); var _sText = tr.find("td").eq(0).text(); // get the 1st cell's innerText $("#SPAN1").text(" Edit: " + _sText); }); }); </script>
動態建立的新元素
只要把 click 事件改寫成 .delegate() 或 .on() 才能解決這個問題。範例直接使用 .on()和.delegate() 來撰寫。.on()的使用語法是:
selector.on( events [, sub-selector ] [, data ], handler )
例如:
$("table tr").on("click", "td:nth-child(1)", function() { // some code... });
修改後的程式碼如下:
<html> <head> <script src="https://code.jquery.com/jquery-1.11.3.min.js"></script> <style> .highlight { color: white; background-color: highlight; } </style> </head> <body> <!-- http://jsfiddle.net/emisjerry/53v4o3ha/ --> <input type="button" id="btnAdd" value=" Add "> <span id="SPAN1"></span> <table id="TABLE1" border="1"> <tbody id="TBODY1"> <tr class='row'><td>static text 1</td><td><input type='Button' value='Delete' class='delButton'><input type='Button' value='Edit' class='editButton'></td></tr> <tr class='row'><td>static text 2</td><td><input type='Button' value='Delete' class='delButton'><input type='Button' value='Edit' class='editButton'></td></tr> <tr class='row'><td>static text 3</td><td><input type='Button' value='Delete' class='delButton'><input type='Button' value='Edit' class='editButton'></td></tr> <tr class='row'><td>static text 4</td><td><input type='Button' value='Delete' class='delButton'><input type='Button' value='Edit' class='editButton'></td></tr> <tr class='row'><td>static text 5</td><td><input type='Button' value='Delete' class='delButton'><input type='Button' value='Edit' class='editButton'></td></tr> </tbody> </table> </body> </html> <script> var iCurrentRowIndex_ = -1; $(document).ready(function() { $("#btnAdd").click(function() { $("#TBODY1").append("<tr class='row'><td>" + (new Date()) + "</td><td><input type='Button' value='Delete' class='delButton'><input type='Button' value='Edit' class='editButton'></td></tr>"); }); /*$(".row").click(function() { if (iCurrentRowIndex_ > -1) { $('.row:nth-child(' + (iCurrentRowIndex_+1) +')').removeClass('highlight'); } $(this).addClass('highlight'); iCurrentRowIndex_ = $(this).index(); });*/ $("#TBODY1").on("click", ".row", function() { if (iCurrentRowIndex_ > -1) { $('.row:nth-child(' + (iCurrentRowIndex_+1) +')').removeClass('highlight'); } $(this).addClass('highlight'); iCurrentRowIndex_ = $(this).index(); }); /*$(".delButton").click(function() { $(this).parent().parent().remove(); });*/ $("#TBODY1").delegate(".delButton", "click", function() { $(this).parent().parent().remove(); // $(this) is #TBODY1 }); /*$(".editButton").click(function() { var tr = $(this).parent().parent(); var _sText = tr.find("td").eq(0).text(); // get the 1st cell's innerText $("#SPAN1").text(" Edit: " + _sText); });*/ $("#TBODY1").delegate(".editButton", "click", function() { var tr = $(this).parent().parent(); var _sText = tr.find("td").eq(0).text(); // get the 1st cell's innerText $("#SPAN1").text(" Edit: " + _sText); }); }); </script>
測試檔案下載或執行
點擊執行或按右鍵另存新檔。
##
您可能也會有興趣的類似文章
- FixedHeader.js:將網頁表格標題列固定住的程式 (0則留言, 2011/09/29)
- 替部落格的側邊欄位加上縮起與展開功能 (2則留言, 2007/03/18)
- jQuery DataTables範例1:啟始設定 (0則留言, 2011/10/20)
- 在Xuite測試 jQuery (0則留言, 2007/09/12)
- 第4個jqGrid範例: 資料列處理 (15則留言, 2010/02/14)
- 使用jQuery的效益 (0則留言, 2007/09/23)
- jQuery神奇的選擇器(Selector) (3則留言, 2007/09/28)
- 第一個jqGrid範例:Local array (1則留言, 2010/02/13)
- jQuery選擇器測試與範例 (0則留言, 2007/09/29)
- jQuery在Xuite的測試 (0則留言, 2007/10/01)
- 第3個jqGrid範例: XML與XML STRING格式 (2則留言, 2010/02/14)
- 初試AJAX:中文的傳遞與接收 (0則留言, 2007/03/16)
- 第2個jqGrid範例:增加額外選項設定 (6則留言, 2010/02/13)
- 使用TiddlyWiki彙總部落格文章的方法與心得 (4則留言, 2007/12/01)
- 在Xuite裡使用jQuery的重點 (0則留言, 2007/09/22)