[英]Implement siblings() in vanilla javascript
我正在尝试在 vanilla js 中做兄弟姐妹()在 jQuery 中所做的事情。 我在这里看到了很多有用的解释,但是在我的代码中实现它们时遇到了麻烦。
我有一个 div,里面有 4 个按钮。 每次我单击一个按钮时,都会将 class (.btn-anim) 添加到该按钮(到目前为止这工作正常)。 我想要做的是当我单击其中一个按钮(已经没有 class)以删除任何其他按钮的 class 并将其添加到单击的按钮。
我的 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');
}
};
这是我添加 class 的代码
highlight.classList.add('btn-anim'); //
在 vanilla 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');
您可以使用previousElementSibling
和nextElementSibling
元素。
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>
jQuery 中的 .siblings() 还允许您使用选择器参数来定位特定的兄弟姐妹,我认为这没有得到解决。
const getSiblings = (el, sel) => {
let siblings = [];
let targets;
if (sel)
targets = el.parentNode.querySelector(':scope > ' + sel)
else
targets = el.parentNode.children;
for (let target of targets) {
if (target !== el)
siblings.push(target);
}
return siblings;
}
然后这可以像这样用于OP的用例......
const removeAnimClass = (ev) => {
let siblings = getSiblings(ev.currentTarget, '.btn-anim');
for (let sibling of siblings) {
sibling.classList.remove('btn-anim');
}
const colorsDiv = document.getElementById('js-colors-div');
const colorBtns = colorsDiv.getElementsByTagName("button");
for (let colorBtn of colorBtns) {
colorBtn.onclick = removeAnimClass;
}
试试这个:- 给所有 btns 相同的 class(例如检查)然后循环它们,一旦进入循环,您将创建另一个循环,它将从所有 btns 中删除 class(检查),然后它只会添加到你的那个点击
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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.