Javascript:根据鼠标悬停的元素突出显示相同类名的元素

时间:2017-03-14 23:42:55

标签: javascript html dom html-table dom-events

我又回来了另一个JavaScript DOM问题。避免使用jQuery。

我正在尝试在HTML表格中选择同一类的所有元素,并在鼠标悬停时将其突出显示为蓝色。我想强调所有与hovered元素具有相同类名的单元格。到目前为止,我已经提出了两个解决这个问题的方法,但两个方法都没有。

解决方案一:

var cellElements = document.getElementsByTagName('td');
for (var i = 0; i < cellElements.length; i++){
  cellElements[i].addEventListener('mouseover', function(e){
    var hoveredElement = e.target;
    if (cellElements[i].className === hoveredElement.className){
      cellElements.style.color = "blue";
    }
    else {
      cellElements.style.color = "black";
    }
  })
}

解决方案二:

var cellElements = document.getElementsByTagName('td');
for (var i = 0; i < cellElements.length; i++){
  cellElements[i].addEventListener('mouseover', function(e){
    var hoveredElement = e.target;
    document.getElementsByClassName(hoveredElement.className).style.color="blue";
  })
}

HTML代码段

<tr class="row-c tr-selected">
  <td><input type="checkbox"></input></td>
  <td class="column-a">Specification 3</td>
  <td class="column-b">Specification 3</td>
  <td class="column-c">Specification 3</td>
</tr>
<tr class="row-d tr-selected">
  <td><input type="checkbox"></input></td>
  <td class="column-a">Specification 3</td>
  <td class="column-b">Specification 3</td>
  <td class="column-c">Specification 3</td>
</tr>

我想尝试弄清楚如何在没有jQuery的情况下完成这项工作。

2 个答案:

答案 0 :(得分:0)

您已正确绑定事件侦听器,但之后您只需捕获与hovered元素具有相同class的元素并将其放入变量中。然后,使用Array#forEach,迭代这些元素以改变它们的风格。

var cellElements = document.getElementsByTagName('td');
for (var i = 0; i < cellElements.length; i++) {

  cellElements[i].addEventListener('mouseover', function(e) {
    var elems = document.getElementsByClassName(this.className);
    Array.from(elems).forEach(v => v.style.color = 'red');
  })
  
  cellElements[i].addEventListener('mouseleave', function(e) {
    var elems = document.getElementsByClassName(this.className);
    Array.from(elems).forEach(v => v.style.color = 'black');
  })
  
}
<table>
<tr class="row-c tr-selected">
  <td><input type="checkbox"></td>
  <td class="column-a">Specification 3</td>
  <td class="column-b">Specification 3</td>
  <td class="column-c">Specification 3</td>
</tr>
<tr class="row-d tr-selected">
  <td><input type="checkbox"></td>
  <td class="column-a">Specification 3</td>
  <td class="column-b">Specification 3</td>
  <td class="column-c">Specification 3</td>
</tr>
</table>

答案 1 :(得分:0)

你的第二个例子实际上非常接近,你需要进行一些调整。

首先,小心不要在for循环中声明一个函数;这样做会产生一些奇怪的副作用。您可以轻松地将声明移出:

var cellElements = document.getElementsByTagName('td');
function colorSimilar (e) {
  var hoveredElement = e.target;
  document.getElementsByClassName(hoveredElement.className).style.color="blue";
}
for (var i = 0; i < cellElements.length; i++){
  cellElements[i].addEventListener('mouseover', colorSimilar)
}

其次,您尝试修改getElementsByClassName调用结果的属性style,但结果不是单个元素,而是array-like object of all child elements which have all of the given class names。所以你要做的就是迭代那个类似数组的对象;一种简单的方法是使用标准for循环:

function colorSimilar (e) {
  var hoveredElement = e.target;
  var similarElements = document.getElementsByClassName(hoveredElement.className)
  for (var i = 0; i < similarElements.length; i++) {
    similarElements[i].style.color = "blue";
  }
}

(另一种方法是使用Array.fromHTMLCollection投射到数组(如果您的浏览器支持它),或者forEach通常使用Array.prototype.forEach.call

第三,你可能会注意到你的元素实际上保持蓝色,即使将鼠标移到另一组相似的类名上也是如此。这是因为你永远不会重置颜色!一种简单的方法是迭代所有候选者,并根据类名切换颜色:

function colorSimilar(e) {
  var hoveredElement = e.target;
  for (var i = 0; i < cellElements.length; i++) {
    if (cellElements[i].className == hoveredElement.className) {
      cellElements[i].style.color = 'blue';
    } else {
      cellElements[i].style.color = null;
    }
  }
}

您的最终结果应如下所示:

(请注意,我使用backgroundColor而不是color,只是因为它有一个更有趣的例子)

var container = document.getElementById('container');
var cellElements = container.getElementsByTagName('td');

function colorSimilar(event) {
  var className = event.target.className;
  for (var i = 0; i < cellElements.length; i++) {
    if (cellElements[i].className == className) {
      cellElements[i].style.backgroundColor = 'blue';
    } else {
      cellElements[i].style.backgroundColor = null;
    }
  }
}

for (var i = 0; i < cellElements.length; i++) {
  cellElements[i].addEventListener('mouseover', colorSimilar)
}
td {
  height: 40px;
  width: 40px;
  border: 1px solid black;
}
<table id="container">
  <tr>
    <td class="one" />
    <td class="two" />
    <td class="three" />
  </tr>
  <tr>
    <td class="three" />
    <td class="one" />
    <td class="two" />
  </tr>
  <tr>
    <td class="two" />
    <td class="three" />
    <td class="one" />
  </tr>
</table>