如何按包含 Travis CI 徽章状态图像的列对 HTML table 进行排序?

How can I sort an HTML table by column containing Travis CI badge status images?

事实如下:

如果我可以按 Travis CI 构建状态对构建列进行排序,那就太好了。不幸的是,构建状态仅从 <img> 标签的图像内容加载,因此 sorttable.js 在 HTML 本身没有任何内容。

所以我请教了 HTML 和 javascript 大师!

如何使 Travis table sortable 生成状态 CI?

一些软要求:

这是对我有用的过程。通过最小的调整,该方案可用于在客户端通过 javascript 使任何 <img> 元素排序 table,例如 sorttable.js.

  1. 根据 Andreas 的建议(感谢 Andreas!),我写了一些 javascript 将每个 <img> 绘制到它自己的 canvas 上,然后通过 [=14= 提取 base64 数据].
  2. 我对 toDataURL() 的内容进行了哈希处理,为 sorttable.js 创建了自定义排序键,并将其分配给包含 <td>sorttable_customkey 属性。就我的目的而言,取数据的前 64 个字符就足够了,但是您当然可以为此编写任何您喜欢的哈希函数,具体取决于您的图像像素。
  3. 为了避免错误 Tainted canvases may not be exported,我将每个 <img> src 复制到一个新的 Image 并设置 crossOrigin=anonymous,按照 [=29] 的建议=].

这是我的工作解决方案的 JavaScript 代码:

function imageData(img) {
  var canvas = document.createElement("canvas");
  canvas.width = img.width;
  canvas.height = img.height;

  // HACK: Avoid 'Tainted canvases may not be exported' error.
  // See: 
  var anonImg = new Image();
  anonImg.setAttribute('crossOrigin', 'anonymous');
  anonImg.src = img.src;

  canvas.getContext("2d").drawImage(anonImg, 0, 0);
  return canvas.toDataURL();
}

function hashCode(s) {
  // NB: Using the first 64 characters is good enough here, and much faster.
  return s.substring(0, 64);
}

// See: 
function makeBadgesSortable() {
  var tds = document.body.getElementsByClassName("badge");
  for (var i=0; i<tds.length; i++) {
    var imgs = tds[i].getElementsByTagName("img");
    if (imgs.length < 1) continue;
    tds[i].setAttribute("sorttable_customkey", hashCode(imageData(imgs[0])));
  }
}

然后在 HTML 一侧,将 class="badge" 添加到包含 Travis <img> 徽章的 table 中的每个 <td>,以及 onload="makeBadgesSortable()"<body> 元素。