纯JavaScript实现表格列悬停效果?

3
我需要一个纯Javascript(不使用jQuery)的HTML表格列悬停效果。
我发现这个答案声称可以修复Firefox中的问题,但在我看来仍然有缺陷。
我还发现这个答案只适用于第一列。
不幸的是,我的Javascript技能非常菜,所以我修改它们的尝试都失败了。
这可能吗?任何建议都将不胜感激。

6
jQuery是用纯JavaScript编写的,那这算不算? :-p - Wiseguy
你能否使用JavaScript添加CSS的:hover属性,或者这也是不行的? - thatidiotguy
@thatidiotguy,只要它能正常工作,我不认为会有任何问题! - carmenism
1
你不能只使用 CSS 吗? - Isaac Gonzalez
1
据我所知,您只能将鼠标悬停在行和单元格上,而不能悬停在列上。 - carmenism
2
@Wiseguy,你的用户名很适合你。 - Steve Robbins
7个回答

7

这里提供一种基于列的方法。当鼠标进入/离开单元格时,通过索引查找相应的<col/>并应用/移除所需的类:

(() => {
  const myTable = document.getElementById("myTable");
  const cols = myTable.querySelectorAll("col");
  const events = {
    mouseover: e => {
      const t = e.target.closest("td");
      if (t) {
        const cellIndex = t.cellIndex;
        for (let i = 0, n = cols.length; i < n; i++) {
          cols[i].classList[i === cellIndex ? "add" : "remove"]("hovered");
        }
      }
    },
    mouseout: e => {
      const t = e.target;
      if (t.nodeName === "TD" && !t.contains(e.relatedTarget)) {
        cols[t.cellIndex].classList.remove("hovered");
      }
    }
  };
  for (let event in events) {
    myTable.addEventListener(event, events[event]);
  }
})();
.hovered {
  background-color: #FF0000;
}
<table id="myTable" cellspacing="0">
  <col />
  <col />
  <col />
  <tbody>
    <tr>
      <td>Col1</td>
      <td>Col2</td>
      <td>Col3</td>
    </tr>
    <tr>
      <td>Col1</td>
      <td>Col2
        <span>nested</span>
      </td>
      <td>Col3</td>
    </tr>
    <tr>
      <td>Col1</td>
      <td>Col2</td>
      <td>Col3</td>
    </tr>
  </tbody>
</table>

另请参阅:

注:本文中保留了HTML标签。

这离成功就差一点,但是当我把鼠标完全移开表格后,最后一列仍然保留着背景颜色。 - carmenism
抱歉,我并不是故意表现得不感激!我没有意识到我需要在我的问题中指明那一点。谢谢您提供您的函数。 - carmenism
1
@vulpix,噗...没问题。已更新。 - canon
非常感谢您的勤奋!非常感谢。如果您不介意我问一下,您是否知道为什么当我在表格中鼠标悬停在图像上时,悬停会消失?http://jsfiddle.net/RmrSJ/ - carmenism
1
因为 td 在你悬停在它的子元素(即嵌套的图像)上时会发送 mouseout 事件。您可以检查 e.toElement 是否是 td 的后代,如果是,则停止传播。 - canon
如果有人想知道,这是我解决嵌套元素问题的方法:http://jsfiddle.net/PJ5QT/ - carmenism

2
这是您的代码(+演示):

demo

var HOVER_CLASS = 'hovered';
var hovered;

table.addEventListener('mouseover', function (e) {
    if (e.target.tagName.toLowerCase() == 'td') {
        var index = e.target.cellIndex;

        hovered && hovered.forEach(function (cell) {
            cell.classList.remove(HOVER_CLASS);
        });

        hovered = Array.prototype.map.call(
            table.rows,
            function (row) {
                var i = index;
                while (!cell && i >= 0) {
                    var cell = row.cells[i];
                    i -= 1;
                }
                return cell;
            }
        );

        hovered.forEach(function (cell) {
            cell.classList.add(HOVER_CLASS);
        });
    }
}, true);

table.addEventListener('mouseout', function (e) {
    hovered && hovered.forEach(function (cell) {
        cell.classList.remove(HOVER_CLASS);
    });
    hovered = null;
}, true);

运行得很好。我现在正在尝试将其应用到我的代码中。谢谢! - carmenism
@vulpix,一点也不。你可能需要在旧版浏览器中使用classListmap/forEach部分进行处理。 - katspaugh

1

我能想到的最好方法是给每个 <td> 元素赋予一个标识其所在列的类名,例如 "col1, col2" 等。

然后,您可以使用 document.getElementsByClassName("colX") 函数获取这些 <td> 元素的数组,循环遍历该数组并修改样式。请注意,这种方法可能无法在旧浏览器中正常工作,因为它们不支持 getElementsByClassName 函数,但是您可以轻松找到解决方法。其中最好的方法是使用 jQuery,不确定您为什么反对它。


0
你在 CSS 中创建一个类。
.HoverTabla > tbody > tr:hover,
.HoverTabla > tbody > tr:focus { 
    background-color: #42C6F7;
}

然后你从HTML表格中调用它

<table class="table HoverTabla" id="tbl_Plan">

            <thead>
                <tr>
                    <th>Tipo de plan</th>
                    <th>Tiempo en días</th>
                    <th>Max. Usuario</th>
                    <th>Max. Capacidad</th>
                    <th>Max. Casos</th>
                    <th>Valor plan</th>
                    <th></th>
                </tr>
            </thead>
 </table>

0
我在谷歌上搜索后找到的仅使用 CSS 的解决方法: https://css-tricks.com/simple-css-row-column-highlighting/ 表格中的每个单元格(<td>)都通过伪元素给出一些填充,用于创建悬停效果。为确保悬停效果不会延伸到表格之外,使用了overflow: hidden
文章中的副标题总结了一切:"技巧是在<td> 上使用巨大的伪元素,它们被表格溢出隐藏"

-1

尝试一下

<td onMouseOver="this.bgColor='yellow';" onMouseOut="this.bgColor='white';">

2
我认为他想要突出整个列,而不仅仅是单元格。 - invertedSpear

-2

这样就可以了,不需要使用JavaScript。因此,即使人们关闭了JavaScript,它仍然可以正常工作。

Jfiddle: http://jsfiddle.net/vJacZ/

HTML:

<table>
<tr>
    <td class="column1">
        Column1
    </td>
    <td class="column2">
        Column2
    </td>
</tr>
</table>

CSS:

.column1{
    color:black;
}
.column1:hover{
    color:red;
}
.column2{
    color:black;
}
.column2:hover{
    color:green;
}

这仅适用于单元格,而不是列。添加第二行,你就会明白我的意思。 - carmenism
使该类别中的每个单元格。据我所知,HTML表是按行定义的,而不是列。 - PRNDL Development Studios
1
正确,表格是按行定义的,这就是为什么您需要使用js来捕获列中的每个单元格以便对它们进行操作。 - invertedSpear
没错,@invertedSpear,我们的答案完全一样,只是我的没有使用JS。无论如何,你都需要将类添加到单元格中。 - PRNDL Development Studios
2
是的,您需要将类添加到列中的每个单元格,但是如果没有JS,您无法操作列中的每个单元格的背景颜色,这正是OP想要做的。 - invertedSpear

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