网络日志

[JS真好玩] 表格不支持排序?用4行JS排序!两种方案:基于flex order或replaceC

我是HullQin,公众号线下聚会游戏的作者(欢迎关注公众号,发送加微信,交个朋友),转发本文前需获得作者HullQin授权。我独立开发了《联机桌游合集》,是个网页,可以很方便的跟朋友联机玩斗地主、五子棋等游戏,不收费没广告。还开发了《Dice Crush》参加Game Jam 2022。喜欢可以关注我 HullQin 噢~我有空了会分享做游戏的相关技术。

互联网用户的困惑

我们在浏览网页表格时,可能有的表格不支持按某列排序。这很难受,尤其是我们想利用表格做数据分析时。

举个例子,在掘金的创作者中心,有个「内容数据」,可以看到所有文章的数据,如下图:

我希望计算出每篇文章的「展现-阅读转化率」、「点赞率」等指标,可以参考我之前文章《掘金创作者必备: 用一行JS查看所有文章的转化率,让你知道什么标题才是好标题》。

随后,我希望根据转化率排个序,怎么办呢?

解决过程

先检查网页元素

我们可以右键,「检查」网页元素,发现它是个table元素,tbody里面就是表格的数据了,每个tr代表一行,如下图:

再提出可行方案

只要让tr按顺序重新排列即可。我有2个想法:

  1. 更快的做法。利用flex布局中的order属性,只要把希望排序的值赋值给tr的css的order属性,再把他们的容器(tbody)设置为flex布局,那么我们不需要修改tr的顺序,浏览器渲染时,会自动排序按order好。
  2. 更舒服的做法。我们不断调用appendChild、removeChild、cloneNode、insertBefore、replaceChild等等dom方法,使这些tr按照预期的顺序排序。

方案一:Flex+order【4行代码】

实现之前,我们先手动验证一下方案可行性:即手动修改css,先随便设置几个order属性,看这种方案对table是否可行。

例如,我把前三个tr分别设置了order 3 2 4。只要他们重新排列了,就说明方案可行。

注意,不要忘记给tbody设置flex属性:

display: flex;
flex-direction: column;

发现flex布局对table也是可行的,只是样式错乱了。我们需要调整一下表格的样式。

经过分析发现,是标题的单元格(td)太宽、数据的单元格(td)太窄,导致产生了这个效果,只要我们设置一下所有的td的max-widthmin-width即可,尝试一下:

虽然展示不完美,但是至少能正常看数据了!

下面,我们就按照之前学过的方法(《掘金创作者必备: 用一行JS查看所有文章的转化率,让你知道什么标题才是好标题》),给每个tr节点设置order即可,这次我们先按照阅读数排序。

const tbody = document.getElementsByTagName('tbody')[0];
for (let tr of tbody.children) {
  tr.style.order = tr.children[3].innerText;
}

执行完毕,只见眼前的网页一闪,整个表格就按照阅读量重新排序了!

方案二:调整tr顺序【4行代码】

话不多说,直接上脚本:

// 获取tbody这个元素
const tbody = document.getElementsByTagName('tbody')[0];
// 根据tr元素,选出排序的基准,应该是数字,便于比较大小
const key = ele => Number(ele.children[3].innerText);
// 对tbody的children进行排序,获得排序后的tr数组
const orderedNodes = Array.from(tbody.children).sort((a, b) => key(a) - key(b);
// 用排序后的tr数组,作为tbody的字元素
tbody.replaceChildren(...orderedNodes);

建议了解一下 Element.replaceChildren 这个好用的Dom API,真是太方便啦!

你这只能对某一页排序啊?如何全表排序?

嘿嘿,我早料到你会这么问!上篇文章,已经做了铺垫:《遇到表格,手动翻页太麻烦?我教你写脚本,一页展示所有数据》

按照上篇文章,先把表格全部数据拿到,一页展示完,你就可以对全表排序啦!

喜欢吗?求赞、求收藏哦!谢谢你!

写在最后

我是HullQin,公众号线下聚会游戏的作者(欢迎关注公众号,发送加微信,交个朋友),转发本文前需获得作者HullQin授权。我独立开发了《联机桌游合集》,是个网页,可以很方便的跟朋友联机玩斗地主、五子棋等游戏,不收费没广告。还开发了《Dice Crush》参加Game Jam 2022。喜欢可以关注我 HullQin 噢~我有空了会分享做游戏的相关技术。