Chrome中操作DataTable的readystatechange事件代码仅清缓存后执行一次
问题解决方案
问题根源
当前代码的核心问题是依赖文档加载状态触发操作,和DataTable自身的异步渲染时机不匹配:
- 清除缓存后静态资源加载速度慢,
document.readyState变为complete时DataTable刚好完成渲染,因此代码执行符合预期 - 刷新后资源走本地缓存,加载速度大幅提升,要么绑定
readystatechange事件时complete状态已经触发过,回调直接不执行;要么DataTable还未完成渲染就执行操作,找不到.dt-buttons元素导致append失效 - wrap操作出现异常也是因为时机不一致:有时执行代码时DataTable的外层
_wrapper容器还未生成,只会包裹表格本身;有时容器已经生成,就会连带容器一起包裹
解决方案
优先使用DataTable官方提供的初始化完成回调,比监听文档加载状态稳定很多,分两种场景处理:
场景1:可以修改DataTable初始化配置
直接在原有DataTable初始化代码中新增initComplete配置项,所有操作写在该回调内:
$('#salaries-datatable-table').DataTable({ // 保留你原来的所有配置(dom、buttons、ajax、分页等参数) initComplete: function(settings, json) { const $table = $('#salaries-datatable-table'); // 加判断避免重复包裹 if (!$table.parent().hasClass('col-12')) { $table.wrap("<div class='col-12' style='overflow-x:auto'></div>"); } const $dtButtons = $("#salaries-datatable-table_wrapper .dt-buttons"); // 加判断避免重复添加按钮 if ($dtButtons.find('.btn-outline-blue.btn_size').length === 0) { $dtButtons.append(`<button class="btn btn-outline-blue btn_size">OK</button>`); } } });
场景2:无法修改DataTable初始化配置(比如第三方组件封装的表格)
监听DataTable全局初始化事件,匹配到目标表格后执行操作:
// 该事件会在任意DataTable初始化完成后触发 $(document).on('init.dt', function(e, settings) { // 只处理目标表格 if (settings.nTable.id !== 'salaries-datatable-table') return; const $table = $('#salaries-datatable-table'); if (!$table.parent().hasClass('col-12')) { $table.wrap("<div class='col-12' style='overflow-x:auto'></div>"); } const $dtButtons = $("#salaries-datatable-table_wrapper .dt-buttons"); if ($dtButtons.find('.btn-outline-blue.btn_size').length === 0) { $dtButtons.append(`<button class="btn btn-outline-blue btn_size">OK</button>`); } });
注意事项
不要依赖document.ready或者readystatechange监听控制DataTable相关操作:DataTable的渲染逻辑独立于文档加载流程,尤其是带异步数据请求的表格,渲染完成时间大概率晚于文档加载完成时间,永远会出现时机不匹配的问题。
内容的提问来源于stack exchange,提问作者Ayah Almahrouq
相关产品推荐
相关产品推荐

