动态加载JSON数据后Tablesorter插件日期列排序报错及未识别表格问题
解决Tablesorter动态表格排序问题的方案
首先咱们梳理下你遇到问题的核心根源:
- jQuery版本冲突:页面同时加载了两个不同版本的jQuery(1.8.2和3.1.1),这会导致插件与jQuery的交互出现异常,是前端插件报错的常见诱因。
- Tablesorter初始化时机错误:页面加载时就初始化了空表格,但动态添加数据后没有通知Tablesorter更新表格结构,插件无法识别新插入的行数据。
- 日期格式不兼容:你自定义的
日/月/年 时:分:秒格式不是Tablesorter默认支持的解析格式,直接排序会因无法解析数据导致报错。
下面是具体的分步修复方案:
步骤1:移除冲突的jQuery版本
删除页面头部的<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>,只保留3.1.1版本的jQuery,彻底解决版本冲突问题。
步骤2:调整Tablesorter初始化与动态更新逻辑
由于你的数据是递归异步加载的,需要在所有数据请求完成后触发Tablesorter的更新操作,让插件识别新的表格内容:
先初始化空表格(带基础配置)
$(function(){ // 初始化空表格,为日期列指定自定义排序规则 $('#keywords').tablesorter({ headers: { 2: { // 第三列(索引从0开始)为发布日期,使用自定义解析器 sorter: 'customDate' } } }); });
修改递归加载函数,添加请求完成判断
var apiKey = 'apikey'; var pageToken = ''; var numOfResult = 0; var activeRequests = 0; // 跟踪所有异步请求的状态 function searchVideo(keyword) { var maxResults = parseInt($('#max_results').val()) || 50; // 给默认值,避免NaN activeRequests++; $.getJSON('https://www.googleapis.com/youtube/v3/playlistItems?playlistId=' + keyword + '&key=' + apiKey + '&maxResults=50&pageToken=' + pageToken + '&part=snippet&callback=?',function(data){ var l = data.items.length; pageToken = data.nextPageToken; numOfResult += l; for(var i = 0; i < l; i++) { activeRequests++; var videoId = data.items[i].snippet.resourceId.videoId; $.getJSON('https://www.googleapis.com/youtube/v3/videos?part=snippet,statistics&id='+videoId+'&key='+ apiKey + '&callback=?',function(data1){ var time = data1.items[0].snippet.publishedAt; var date = new Date(time); // 生成显示用的日期格式,同时添加隐藏的时间戳用于排序 var myDate = date.getDate() + "/" + (date.getMonth() + 1) + "/" + date.getFullYear()+" "+date.getHours()+":"+date.getMinutes()+":"+date.getSeconds(); var sortableDate = '<span style="display:none;">' + date.getTime() + '</span>' + myDate; $('table tbody').append("<tr><td><a target='_blank' href='https://www.youtube.com/watch?v="+data1.items[0].id+"'>"+data1.items[0].id+"</a></td><td>"+data1.items[0].snippet.title+"</td><td>"+sortableDate+"</td><td>"+data1.items[0].snippet.channelTitle+"</td><td>"+data1.items[0].statistics.viewCount+"</td></tr>"); activeRequests--; checkIfAllRequestsDone(); // 每完成一个请求就检查是否全部结束 }); } activeRequests--; // 只有存在下一页且未达到最大结果数时才继续递归 if( numOfResult < maxResults && pageToken) { searchVideo(keyword); } else { checkIfAllRequestsDone(); } }); } // 所有请求完成后,更新Tablesorter function checkIfAllRequestsDone() { if(activeRequests === 0) { $('#keywords').trigger('update'); // 通知插件更新表格数据 $('#keywords').trigger('sorton', [[[2,0]]]); // 可选:默认按发布日期升序排序 } }
步骤3:(可选)添加自定义日期解析器(替代隐藏时间戳方案)
如果你不想用隐藏时间戳的方式,可以给Tablesorter添加自定义解析器,直接解析你的日期格式:
$(function(){ // 注册自定义日期解析器 $.tablesorter.addParser({ id: 'customDate', is: function(s) { // 匹配你的日期格式:日/月/年 时:分:秒 return /\d{1,2}\/\d{1,2}\/\d{4}\s\d{1,2}:\d{1,2}:\d{1,2}/.test(s); }, format: function(s) { // 将日期转换为时间戳,用于数值排序 var parts = s.split(/[\/\s:]/); var date = new Date(parts[2], parts[1]-1, parts[0], parts[3], parts[4], parts[5]); return date.getTime(); }, type: 'numeric' }); // 初始化表格 $('#keywords').tablesorter({ headers: { 2: { sorter: 'customDate' } } }); });
额外优化建议
- 确保你的YouTube API Key拥有足够的权限,避免请求失败导致数据加载不完整。
- 递归调用时一定要判断
pageToken是否存在,防止无下一页时无限发送请求。 - 动态添加表格行时,建议先将所有行拼接成字符串再一次性append,减少DOM操作次数提升性能。
内容的提问来源于stack exchange,提问作者Sameera Cheema
相关产品推荐
相关产品推荐

