在香草JavaScript中实现兄弟姐妹()



我正在尝试在vanilla js中执行兄弟姐妹((在jQuery中的作用。我在这里看到了很多有用的解释,但是在我的代码上实施它们很难。

我有一个内部有4个按钮的DIV。每次我单击一个按钮时,将添加到该按钮的类(.btn-anim((到目前为止,这还可以(。我要做的是,当我单击一个按钮(还没有类(以删除任何其他按钮的类并将其添加到单击一个按钮时。

我的html标记:

<div id="js-colors-div">
  <button class="yellow"></button>
  <button class="green"></button>
  <button class="blue"></button>
  <button class="pink"></button>
</div>

和JS:

var colorsDiv = document.getElementById('js-colors-div'); 
var colors = colorsDiv.getElementsByTagName("button");
for (var i = 0; i < colors.length; i++) {                   
    colors[i].onclick = function(e) {                                
    var highlight = e.target;
    //trying to achieve this         
    $(this).addClass('btn-anim').siblings().removeClass('btn-anim');          
    }
};

这是我添加类的代码

highlight.classList.add('btn-anim'); // 

在香草JS中,您可以循环循环,然后跳过元素本身。您可以使用classList方法添加/删除类:

    this.classList.add('btn-anim');
    for (let sibling of this.parentNode.children) {
        if (sibling !== this) sibling.classList.remove('btn-anim');
    }

请注意,您可以(也可以在jQuery中(简化一点:只需从所有按钮中删除类,然后将其添加到当前一个按钮:

    for (let sibling of this.parentNode.children) {
        sibling.classList.remove('btn-anim');
    }
    this.classList.add('btn-anim');

您可以使用previousElementSiblingnextElementSibling元素。

var colorsDiv = document.getElementById('js-colors-div');
var colors = colorsDiv.getElementsByTagName("button");
for (var i = 0; i < colors.length; i++) {
  colors[i].addEventListener('click', function(e) {
    var highlight = e.target;
    //trying to achieve this         
    this.classList.add('btn-anim');
    addClassSiblings.bind(this, 'btn-anim')();
  });
}
function addClassSiblings(classNames) {
  var cs = this.nextElementSibling;
  while(cs) {
    cs.classList.remove(classNames);
    cs = cs.nextElementSibling;
  }
  
  cs = this.previousElementSibling;
  while(cs) {
    cs.classList.remove(classNames);
    cs = cs.previousElementSibling;
  }
}
.yellow {
  color: yellow
}
.pink {
  color: pink
}
.green {
  color: green
}
.blue {
  color: blue
}
.btn-anim {
  color: black
}
<div id="js-colors-div">
  <button class="yellow">yellow</button>
  <button class="green">green</button>
  <button class="blue">blue</button>
  <button class="pink">pink</button>
</div>

const colorsDiv = document.getElementById('js-colors-div');
const children = [...colorsDiv.children];
children.forEach((el) => {
  el.addEventListener('click', (e) => {
    children.forEach((btn) => {
      btn.classList.remove('active');
    })
    e.target.classList.add('active');
  });
});
button {
  color: white
}
.yellow {
  background: #ffaf00
}
.pink {
  background: pink
}
.green {
  background: green
}
.blue {
  background: blue
}
.active {
  background: black
}
<div id="js-colors-div">
  <button class="yellow">yellow</button>
  <button class="green">green</button>
  <button class="blue">blue</button>
  <button class="pink">pink</button>
</div>

.siblings((在jQuery中还允许您使用选择器参数来定位特定的兄弟姐妹,我认为这没有解决。

const getSiblings = (el, sel) => {
    const siblings = [];
    let targets;
    if (sel)
        targets = el.parentNode.querySelectorAll(':scope > ' + sel)
    else
        targets = el.parentNode.children;
    for (const target of targets) {
        if (target !== el)
            siblings.push(target);
    }
    return siblings;
};

然后可以像OP的用例一样使用它...

const removeAnimClass = (ev) => {
    const siblings = getSiblings(ev.currentTarget, '.btn-anim');
    for (const sibling of siblings) {
        sibling.classList.remove('btn-anim');
};
const colorsDiv = document.getElementById('js-colors-div'); 
const colorBtns = colorsDiv.getElementsByTagName("button");
for (const colorBtn of colorBtns) {                   
    colorBtn.onclick = removeAnimClass;
}

也许尝试一下,给所有buttons相同的class (i.e .checked)

接下来,在每个li DOM Element上创建一个循环并迭代。进入循环后,创建另一个循环,然后将所有元素从所有元素中删除.checked,然后将其仅添加到您的clicked

const rates = document.querySelectorAll(".rate");
for (const rate of rates) 
{
  rate.addEventListener("click", function () 
  {
    for (const i of rates) 
    {
      i.classList.remove("checked");
    }
    rate.classList.add("checked");
  });
}
<ul class="rating-box">
 <li><button class="rate rate-1">1</button></li>
 <li><button class="rate rate-2">2</button></li>
 <li><button class="rate rate-3">3</button></li>
 <li><button class="rate rate-4">4</button></li>
 <li><button class="rate rate-5">5</button></li>
</ul>

最新更新