首页 > 解决方案 > 通过 JavaScript 更新类时 nth-child 选择器未正确应用

问题描述

我正在尝试跟踪轮播的中心,在循环时可以动态地完全替换元素。考虑到完整的元素替换,简单地观察索引的变化并添加一个active类会导致片刻的卡顿,而样式和转换在轮播已经移动后应用,产生的效果很差。

为了克服这个问题,我决定使用 CSS 来定位 3 个元素中的第 2 个,这样无论变化如何发生,这三个元素的中心都应该始终通过 css 定位。但是,这并没有按预期工作,因为当我通过 JavaScript 更改目标元素集时,第 n 个子项似乎没有重新计算。

我已经简化了示例,发现在使用 JavaScriptnth-child更改元素集时,我正在使用的 css 规则似乎没有被重新计算。active

例如:

五个元素的集合,其中三个具有附加active类。始终瞄准nth-child(3n+2)三个活跃班的中间。

在按下按钮时,javascript 函数会删除第一个活动类并将其应用于下一个非活动元素。

预期:新的中心元素应该由nth-childcss 选择器选择实际:css 规则仍然适用于相同的元素,并且不会更新应该是新位置的位置。

从视觉上看,效果是这样的:

按键前:

选择正确的第 n 个孩子的初始状态(红色)

按下按钮后:

第一次按下按钮后,第一个活动类已被删除,并且 avtive 已添加到下一个非活动元素。 期望 nth-child 选择新三重奏的中间

这是我的测试用例代码,它很简单,因为我可以得到它并准确地复制我在真实案例中看到的行为。

// extremely crude but always have 3 active blocks and shift them by 1 on each button press, n.b. it doesn't wrap so it'll just break if you go off the end.
nav = e => {
  var active = document.querySelectorAll('.stuff.active');

  var first = active[0];
  var last = active[2];
  first.classList.remove('active');

  document.querySelector('.active + :not(.active)').classList.add('active');

}
.list-of-stuff {
  height: 450px;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: center;
}

.stuff {
  flex-grow: 1;
  background-color: blue;
}

.active {
  background-color: green;
}

.active:nth-child(3n+2) {
  background-color: red;
}

button {
  display: block;
  background: orange;
  color: white;
  border: 0;
  outline: 0;
  padding: 10px 15px;
  margin-bottom: 10px;
}
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>

<body>
  <button onclick="nav()">go</button>

  <div class="list-of-stuff">
    <div class="stuff active"></div>
    <div class="stuff active"></div>
    <div class="stuff active"></div>
    <div class="stuff"></div>
    <div class="stuff"></div>
    <div class="stuff"></div>
    <div class="stuff"></div>
    <div class="stuff"></div>
    <div class="stuff"></div>
    <div class="stuff"></div>
  </div>

</body>

</html>

现场示例:

https://jsbin.com/qeyoyux/edit?html,css,js,console,output

标签: javascriptcss-selectors

解决方案


推荐阅读