简体   繁体   English

有没有办法将类添加到所有元素

[英]Is there a way to add class to all elements

I browsed thru various similar questions, but I found nowhere real help on my problem. 我浏览了各种类似的问题,但我发现我的问题没有真正的帮助。 There are some Jquery examples, but none of them weren't applicable, since I want to do it by vanilla JavaScript only. 有一些Jquery示例,但它们都不适用,因为我只想通过vanilla JavaScript来实现。

The Problem 问题

I have rating widget which I want to build like every time I click on "p" element, eventListener adds class "good" on all p elements before and on the clicked one, and remove class good on all that are coming after the clicked one. 我有想要构建的评级小部件,就像每次点击“p”元素一样, eventListener在点击的元素之前和之后的所有p元素上添加类“good”,并删除所有在点击后的所有元素上的类。

My Thoughts 我的想法

I tried to select all the "p" elements and iterate over them by using a for loop to add class before and on clicked element, and to leave it unchanged or remove after, but somewhere I am doing it wrong, and it adds class only on clicked element not on all previous ones. 我试图选择所有的“p”元素并通过使用for循环在它们之前和之后添加类来迭代它们,并保持不变或删除之后,但是某处我做错了,它只添加了类点击元素不在以前的所有元素上。

My Code 我的守则

function rating () {
var paragraph = document.getElementsByTagName('p');
for (var i = 0; i < paragraph.length; i++) {
    paragraph[i].addEventListener('click', function(e) {
        e.target.className='good';
        })
      }
    } 

rating();

Result 结果

Expected result is that every p element before the clicked one, including clicked one should be having class good after click and all the ones that are after the clicked one, should have no classes. 预期的结果是点击之前的每个p元素,包括点击的一个元素在点击后应该具有良好的类,并且在点击的元素之后的所有元素应该没有类。

Actual Result: Only clicked element is having class good. 实际结果:只有点击的元素具有良好的类。

Using Array#forEach , Element#nextElementSibling and Element#previousElementSibling 使用Array#forEach, Element#nextElementSiblingElement#previousElementSibling

General logic behind this is to loop through all the previous and next sibling elements. 这背后的一般逻辑是遍历所有前一个和下一个兄弟元素。 For each element, add or remove the class .good until there are no more siblings to handle. 对于每个元素,添加或删除类.good直到没有更多的兄弟要处理。

 const ps = document.querySelectorAll('p'); ps.forEach(p => { p.addEventListener("click", function() { let next = this.nextElementSibling; let prev = this; while(prev !== null){ prev.classList.add("good"); prev = prev.previousElementSibling; } while(next !== null){ next.classList.remove("good"); next = next.nextElementSibling; } }) }) 
 p.good { background-color: red; } p.good::after { content: ".good" } p { background-color: lightgrey; } 
 <div id='rating'> <p>*</p> <p>*</p> <p>*</p> <p>*</p> <p>*</p> </div> 

Alternative: 替代方案:

Using Array#slice to get the previous and next group of p's. 使用Array#slice获取上一组和下一组p。

 const ps = document.querySelectorAll('p'); ps.forEach((p,i,list) => { p.addEventListener("click", function() { const arr = [...list]; const previous = arr.slice(0,i+1); const next = arr.slice(i+1); previous.forEach(pre=>{ pre.classList.add("good"); }) next.forEach(nex=>{ nex.classList.remove("good"); }); }) }) 
 p.good { background-color: red; } p.good::after { content: ".good" } p { background-color: lightgrey; } 
 <div id='rating'> <p>*</p> <p>*</p> <p>*</p> <p>*</p> <p>*</p> </div> 

The key ingredient is to use Node.compareDocumentPosition() to find out if an element precedes or follows another element: 关键因素是使用Node.compareDocumentPosition()来查明元素是否在另一个元素之前或之后:

 var paragraphs; function handleParagraphClick(e) { this.classList.add('good'); paragraphs.forEach((paragraph) => { if (paragraph === this) { return; } const bitmask = this.compareDocumentPosition(paragraph); if (bitmask & Node.DOCUMENT_POSITION_FOLLOWING) { paragraph.classList.remove('good'); } if (bitmask & Node.DOCUMENT_POSITION_PRECEDING) { paragraph.classList.add('good'); } }); } function setup() { paragraphs = [...document.getElementsByTagName('p')]; paragraphs.forEach((paragraph) => { paragraph.addEventListener('click', handleParagraphClick); }); } setup(); 
 #rating { display: flex; } p { font-size: 32px; cursor: default; } p:hover { background-color: #f0f0f0; } .good { color: orange; } 
 <div id='rating'> <p>*</p> <p>*</p> <p>*</p> <p>*</p> <p>*</p> </div>` 

 function setup() { var paragraph = document.querySelectorAll("p"); for (p of paragraph) { p.onclick = (event) => { let index = Array.from(paragraph).indexOf(event.target); [].forEach.call(paragraph, function(el) { el.classList.remove("good"); }); for (let i = 0; i <= index; i++) { paragraph[i].classList.add("good"); } } } } //Example case document.body.innerHTML = ` <div id='rating'> <p>*</p> <p>*</p> <p>*</p> <p>*</p> <p>*</p> </div>`; setup(); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM