jQuery DataTables分页后click点击事件不生效问题解决
问题原因
这是jQuery动态元素事件绑定的经典问题,本质是两个点:
- 你用的
$(".check").click()是直接事件绑定,只会给代码执行时已经存在于DOM里的.check元素绑事件 - DataTables分页的实现逻辑,是把非当前页的表格行从DOM里移除,切页的时候再把对应页的行重新插回DOM——这些后续插进来的行,还有初始加载时不在首屏的行,根本没被绑定过事件,当然点了没反应。
你改每页显示50条的时候只有前50条能触发,就是因为DataTables初始化时只把首屏50条渲染进了DOM,剩下的行都是切页时才动态插入的,没绑上事件。
另外你现有代码里还有几个低级错误,顺便一起修了。
修复方法
第一步:先改事件绑定方式,用事件委托
不要直接给.check绑事件,把事件绑在页面初始化时就存在、永远不会被DataTables删掉的父元素上(比如表格的tbody),利用事件冒泡机制,不管子元素什么时候动态插进来,点击事件都能传到父元素上触发逻辑。
注意:你JS里选表格的选择器写错了,JSP里表格id是tblQuestion,你写的$('#tblSoru'),ID不对DataTables都不会正常初始化,先把这个拼写错误改了。
第二步:修正原有逻辑里的bug
你写的click回调里有好几个错误:
- 取问题ID的逻辑错了:你现在取的是
.check的父元素(label标签)的id,label根本没设id属性,真正的问题ID在外层tr上,格式是tr{questionId} - 数组操作错了:
selectedQuestionIdArray.push(selectedQuestionIdArray)是把整个数组往自己里面塞,完全不对,而且没处理取消勾选时把ID从数组里移除的逻辑 - 隐藏域选择器大小写写错了:赋值时用的
#inputSelectedQuestionIdArray,后面打印值的时候写的#inputselectedQuestionIdArray,s小写了,根本拿不到DOM元素 - 控制台打印的字符串引号没配对,会直接报JS语法错
修正后的完整JS代码
<script type="text/javascript"> var selectedQuestionIdArray = []; $(document).ready(function() { console.log("select question ready!"); // 修正表格ID,和JSP里的id="tblQuestion"保持一致 $('#tblQuestion').DataTable({ "iDisplayLength": 50 // 自定义每页显示条数在这里配置即可 }); // 事件委托:把click事件绑在表格的tbody上,监听子元素.check的点击 $('#tblQuestion tbody').on('click', '.check', function(){ console.log("check clicked"); // 向上查找当前所在的表格行 var currentTr = $(this).closest('tr'); // 从tr的id属性里截出问题ID,tr的id格式是tr+数字,比如tr6对应问题ID 6 var questionId = currentTr.attr('id').replace('tr', ''); console.log("Chosen id: " + questionId ); // 判断当前复选框是选中还是取消状态 var isChecked = $(this).siblings('input[type="checkbox"]').prop('checked'); if(isChecked){ // 选中时把ID加入数组,先判重避免重复添加 if(selectedQuestionIdArray.indexOf(questionId) === -1){ selectedQuestionIdArray.push(questionId); } }else{ // 取消勾选时把ID从数组里移除 var idIndex = selectedQuestionIdArray.indexOf(questionId); if(idIndex > -1){ selectedQuestionIdArray.splice(idIndex, 1); } } console.log(selectedQuestionIdArray.length + " number(s) of questions selected."); // 把数组转成逗号分隔的字符串存入隐藏域,方便后端接收 $("#inputSelectedQuestionIdArray").val(selectedQuestionIdArray.join(',')); console.log("Content of selectedQuestionIdArray: " + $("#inputSelectedQuestionIdArray").val()); }); }); </script>
可选优化
你现在复选框的value写死成了1,其实可以直接在JSP渲染的时候就把问题ID放到复选框的value里,后续JS拿值更方便,不用解析tr的id:
把JSP里复选框的代码改成:
<input type="checkbox" data-style="2" data-role="checkbox" name="table_row_check[]" value="${questionView.questionId}" class="" data-role-checkbox="true">
改完之后JS里取问题ID直接用$(this).siblings('input').val()就行,逻辑更简单也不容易出错。
内容的提问来源于stack exchange,提问作者tahasozgen
相关产品推荐
相关产品推荐

