为 <th> 元素添加排序箭头,类似于表格排序器

12

我想在我的表格中添加双向箭头(上下),就像tablesorter插件所做的那样。

这是我的fiddle。由于某种原因,在jsfiddle中甚至没有一个箭头显示出来,但它在我的原始表格中运行正常。

我尝试了这个:

$("table th").addClass("headerSortUp");
$("table th").addClass("headerSortDown");

但是它没有起作用。你有什么办法可以做到这一点吗?

9个回答

28

最佳解决方案无需图片,纯 CSS。 只需在tdth行上放置 headerSortDownheaderSortUp 的classname,就会出现小箭头。

table td,
table th {
  border: 1px solid silver;
}

.headerSortDown:after,
.headerSortUp:after {
  content: ' ';
  position: relative;
  left: 2px;
  border: 8px solid transparent;
}

.headerSortDown:after {
  top: 10px;
  border-top-color: silver;
}

.headerSortUp:after {
  bottom: 15px;
  border-bottom-color: silver;
}

.headerSortDown,
.headerSortUp {
  padding-right: 10px;
}
<table>
  <thead>
    <tr>
      <th class="headerSortDown">ID</th>
      <th class="headerSortUp">Username</th>
      <th>Fullname</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>John</td>
      <td>John Doe</td>
    </tr>
    <tr>
      <td>2</td>
      <td>Jenny</td>
      <td>Jenny Smith</td>
    </tr>
    <tr>
      <td>3</td>
      <td>Tom</td>
      <td>Tom Doe</td>
    </tr>
  </tbody>
</table>

同时检查我的JSFiddle:http://jsfiddle.net/rTXXz/ ,其中提供可工作的示例。

更新:已修复适用于Chrome


1
这在 Chromium 上不起作用(在 Firefox 上可以)。不知道为什么。 - maaartinus

3

我在Chrome中遇到了“无效的属性值”错误。

使用引号可以解决问题:

background: url("data:image/gif;base64, R0lGODlhFQAJAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw=") no-repeat 99%;

我也将双箭头转换为base64格式了。 JSFiddle

3

使用Unicode字符的不同方法

从未排序的表开始,使用默认插入符号

<th>Table Column</th>

在排序后,根据排序顺序并使用Jquery,我这样做:

$(this).text($(this).text().slice(0,-2) + " ▲")

或者
$(this).text($(this).text().slice(0,-2) + " ▼")

这里有一个小问题 - 一旦设置了插入符号(caret),在对另一列进行排序时,不会重置之前列上的插入符号。不确定是否是问题,但如果它成为问题,我需要一个功能来重置其他列标题上的插入符号。

这是我的JSFiddle示例


2
问题出在你的`.headerSortUp`背景上。我已经用下面的代码进行更改:
background: url(http://tablesorter.com/themes/blue/bg.gif) no-repeat 99%;

这个jsFiddle使用绝对背景


为什么要加载资源,而不是通过CSS来实现呢?我非常喜欢这个解决方案。https://codepen.io/imarkrige/pen/vgmij - Taha Rehman Siddiqui

2

这是一个内联的降序箭头。不幸的是,我不知道如何使数据更小,但生成的图像大小是相同的。

background: url('data:image/gif;base64,R0lGODlhFQAEAPcAAAAAACMtMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAP8ALAAAAAAVAAQAAAgaAP8JHCgwgMGDAQgqXIgw4cKHAw9CnFhwYkAAOw==') no-repeat 99%;


2
以下示例根据添加到th元素的data-sort-dir属性应用样式。 data-sort-dir属性可以具有ascdesc的值,并且通过JavaScript在用户单击标题时添加和删除。

$('table.table-sortable th').on('click', function(e) {
  sortTableByColumn(this)
})

function sortTableByColumn(tableHeader) {
  // extract all the relevant details
  let table = tableHeader.closest('table')
  let index = tableHeader.cellIndex
  let sortType = tableHeader.dataset.sortType
  let sortDirection = tableHeader.dataset.sortDir || 'asc' // default sort to ascending

  // sort the table rows
  let items = Array.prototype.slice.call(table.rows);
  let sortFunction = getSortFunction(sortType, index, sortDirection)
  let sorted = items.sort(sortFunction)

  // remove and re-add rows to table
  for (let row of sorted) {
    let parent = row.parentNode
    let detatchedItem = parent.removeChild(row)
    parent.appendChild(row)
  }

  // reset heading values and styles
  for (let header of tableHeader.parentNode.children) {
    header.classList.remove('currently-sorted')
    delete header.dataset.sortDir
  }

  // update this headers's values and styles
  tableHeader.dataset.sortDir = sortDirection == 'asc' ? 'desc' : 'asc'
  tableHeader.classList.add('currently-sorted')
}

function getSortFunction(sortType, index, sortDirection) {
  let dir = sortDirection == 'asc' ? -1 : 1
  switch (sortType) {
    case 'text': return stringRowComparer(index, dir);
    case 'numeric': return numericRowComparer(index, dir);
    default: return stringRowComparer(index, dir);
  }
}

// asc = alphanumeric order - eg 0->9->a->z
// desc = reverse alphanumeric order - eg z->a->9->0
function stringRowComparer(index, direction) {
  return (a, b) => -1 * direction * a.children[index].textContent.localeCompare(b.children[index].textContent)
}

// asc = higest to lowest - eg 999->0
// desc = lowest to highest - eg 0->999
function numericRowComparer(index, direction) {
  return (a, b) => direction * (Number(a.children[index].textContent) - Number(b.children[index].textContent))
}
table.table-sortable th.currently-sorted[data-sort-dir="asc"]::after {
    content: "\25b2";
}

table.table-sortable th.currently-sorted[data-sort-dir="desc"]::after {
    content: "\25bc";
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table-sortable">
    <thead>
        <tr>
            <th data-sort-type="text">Course</th>
            <th data-sort-type="numeric">In Progress</th>
            <th data-sort-type="numeric">Not Started</th>
            <th data-sort-type="numeric">Passed</th>
            <th data-sort-type="numeric">Failed</th>
        </tr>
    </thead>
    <tbody>
      <tr>
        <td>How to be good at stuff</td>
        <td>0</td>
        <td>1000</td>
        <td>0</td>
        <td>0</td>
      </tr>
      <tr>
        <td>Quantum physics for artists</td>
        <td>200</td>
        <td>6</td>
        <td>66</td>
        <td>66</td>
      </tr>
      <tr>
        <td>The best way to skin a cat</td>
        <td>34</td>
        <td>16</td>
        <td>200</td>
        <td>7</td>
      </tr>
      <tr>
        <td>Human cookbook</td>
        <td>4</td>
        <td>7</td>
        <td>4</td>
        <td>50</td>
      </tr>
      <tr>
        <td>Aristocracy rules</td>
        <td>100</td>
        <td>3</td>
        <td>6</td>
        <td>18</td>
      </tr>
    </tbody>
</table>


如果可能的话,请针对Angular发布相同的答案。 - sankar muniyappa

2
如果你正在使用Bootstrap,请使用以下代码:

th, td {
    border: 1px solid black;
    text-align: center !important;
    font-size: 0.8rem !important;
  }

  td:hover, th:hover {
    -webkit-box-shadow: 0 0 5px -1px rgba(115, 127, 255, 1);
    -moz-box-shadow: 0 0 5px -1px rgba(115, 127, 255, 1);
    box-shadow: 0 0 5px -1px rgba(115, 127, 255, 1);
    border: 1px solid rgba(115, 127, 255, 1) !important;
  }

  th i{
     cursor: pointer !important;
  }

  th i:hover{
     color: red !important;
  }
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet"/>

<link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css" integrity="sha384-AYmEC3Yw5cVb3ZcuHtOA93w35dYTsvhLPVnYs9eStHfGJvOvKxVfELGroGkvsg+p" crossorigin="anonymous"/>

<table>
    <thead>
    <tr>
      <th>
        <div class="d-flex flex-row align-items-center">
          <span>ID</span>
          <div class="d-flex flex-column ml-2">
            <i class="fa fa-caret-up"></i>
            <i class="fa fa-caret-down"></i>
          </div>
        </div>
      </th>
      <th>
        <div class="d-flex flex-row align-items-center">
          <span>UserName</span>
          <div class="d-flex flex-column ml-2">
            <i class="fa fa-caret-up"></i>
            <i class="fa fa-caret-down"></i>
          </div>
        </div>
      </th>
    </tr>
    </thead>
  </table>


1
我使用了另一张背景图片来使其工作。也许这能帮你更好地理解问题:
.headerSortUp {
  background: url(http://placehold.it/25x25) no-repeat 99%;
}
.headerSortDown {
  background: url(http://placehold.it/25x25) no-repeat 99%;
}

Fiddle

Fiddle


0
注意:我添加了这个答案,因为它提供了一种在不使用图片的情况下添加箭头的替代方法,但是遵循了保持箭头在背景中的逻辑。

一种在没有图像的情况下添加箭头的方法,同时保持图像的样式(只需微调即可,并且我没有优化div或css中的逻辑 ~ 更像是概念性证明(快速原型))。此方法的另一个好处是,您可以轻松使用类更改箭头的颜色,如果将两个箭头放置在单独的div中,则甚至可以在已选择一个箭头时隐藏一个箭头(当前它们仅在悬停时分别更改颜色)。

查看示例

HTML

<table class="test-table">
  <tr class="headRow">
    <th>
<div class="table-head-container">
    <div class="table-head-background">
      <div class="right-text">
        <div class="small-frame">
            <div class="up-arrow">&#9650</div>
            <div class="down-arrow">&#9660</div>
        </div>
      </div>
    </div>
  <div class="Col-header">First</div>
</div>
    </th>
    <th>
<div class="table-head-container">
    <div class="table-head-background">
      <div class="right-text">
        <div class="small-frame">
            <div class="up-arrow">&#9650</div>
            <div class="down-arrow">&#9660</div>
        </div>
      </div>
    </div>
  <div class="Col-header">Last</div>
</div>
     </th>
    <th>
<div class="table-head-container">
    <div class="table-head-background">
      <div class="right-text">
        <div class="small-frame">
            <div class="up-arrow">&#9650</div>
            <div class="down-arrow">&#9660</div>
        </div>
      </div>
    </div>
  <div class="Col-header">Phone</div>
</div>
    </th>
  </tr>
  <tr>
    <td>John</td>
    <td>Doe</td>
    <td>555-5555</td>
  </tr>
  <tr class="evenRow">
    <td>Jane</td>
    <td>Smith</td>
    <td>555-5555</td>
  </tr>
  <tr>
    <td>Homer</td>
    <td>Simpson</td>
    <td>555-5555</td>
  </tr>
</table>

CSS

.table-head-container {
   position: relative;
  color: white;
  max-width: 100px;
}

.test-table {
  border: solid black 1px;
}

.headRow {
  background-color: green;
  color: white;
}

.headRow > th {
  border: solid black 2px;
  padding: 10px 20px 10px 5px;
  min-width:100px;
  font-size: 1.6em
}

.evenRow {
  background-color: #E8E8E8;
}

table {
  border-collapse: collapse;
}

tr > td {
  border: solid black 1px;
  padding: 5px;
}

.Col-header {
  text-align: left;
}

.table-head-background {
   position: absolute;
   top: -10;
   left: 15;
   bottom: 0;
   right: 0;
   z-index: 1;
  width: 0;
  color: white;
  background-color:green;
}

.table-head-background > .right-text {
  text-align: right;
}

.table-head-background > .right-text > .small-frame {
  position: absolute;
  left: 80px;
  width: 5px !important;
  word-wrap: break-word;
}

.table-head-background > .right-text > .small-frame > .up-arrow, .table-head-background > .right-text > .small-frame > .down-arrow {
font-size: .8em;
}

.table-head-background > .right-text > .small-frame > .up-arrow:hover, .table-head-background > .right-text > .small-frame > .down-arrow:hover {
    color: blue !important;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接