Home > Software design >  alternative way of providing index to querySelectorAll by :even and :odd
alternative way of providing index to querySelectorAll by :even and :odd

Time:06-30

I am trying to get even (div)elements and give them different class Names compared to odd (div) elements in which they will have different class names also, I want to write inside querySelectorAll() function to get even (.project) class and to get odd (.project) class without providing index like [0], [1],...etc. is there a way to do something like that? here is there code for explanation.

here is the original code:

document.querySelectorAll('.project')[0].classList.add('EvenProject');
document.querySelectorAll('.project')[1].classList.add('OddProject');
document.querySelectorAll('.project')[2].classList.add('EvenProject');

here is what I want to implement:

document.querySelectorAll('.project:even').classList.add('EvenProject');
document.querySelectorAll('.project:odd').classList.add('OddProject');

I also tried this code, by querySelector(), but It doesn't work.

 document.querySelector('.project:even').classList.add('EvenProject');

thanks for you help.

CodePudding user response:

NOTE: This answer assumes all .project elements are all children of the same parent.

You can use document.querySelectorAll('.project:nth-child(even)'), check out EVEN AND ODD RULES but, you can do the same thing purely in CSS:

.project {
  width: 100%;
  height: 1em;
  background-color: black;
}

.project:nth-child(even) {
  background-color: blue;
}

.project:nth-child(odd) {
  background-color: green;
}
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>

CodePudding user response:

const projects = document.querySelectorAll('.project');

projects.forEach((el, i) => {
    if (i % 2 === 0) {
        el.classList.add('red')
    } else {
        el.classList.add('yellow')
    }
})
.project {
    width: 40px;
    height: 40px;
    background: gray;
    display: inline-block;
    margin: 5px;
}

.red {
    background: red;
}
.yellow {
    background: yellow;
}
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>

CodePudding user response:

It'd only be possible if there's a parent component for all .projects whose children can be selected with nth-child(even) or nth-child(odd) - for example, with

<div>
  <div ></div>
  <div ></div>
  <div ></div>
  <div ></div>
</div>

you could then do

for (const project of document.querySelectorAll('.project:nth-child(even)') {
  project.classList.add('EvenProject');
}
for (const project of document.querySelectorAll('.project:nth-child(odd)') {
  project.classList.add('OddProject');
}

Or if the HTML is like

<div>
  <div>
    <div ></div>
  </div>
  <div>
    <div ></div>
  </div>
  <div>
    <div ></div>
  </div>
  <div>
    <div ></div>
  </div>
</div>

you could do the same sort of thing with the selector :nth-child(even) > .project. But not all possible layouts of the .projects could be selected with a single selector string like you want - you may have to iterate over the odd and even indicies of the collection manually and add the appropriate index to each.

CodePudding user response:

Details are commented in example

// .forEach() tag of NodeList... 
document.querySelectorAll('.project').forEach((tag, idx) =>
  // If the index is even...
  idx % 2 === 0 ?
  // ... add .black and .even index classes...
  tag.classList.add('black', 'even'   idx) :
  // ... otherwise, add .white and .odd index classes
  tag.classList.add('white', 'odd'   idx)
);
html {
  font: 300 2ch/1 'Segoe UI'
}

body {
  background-color: grey;
}

.project {
  height: 1.2rem;
  margin: 10px auto;
  padding: 7px;
  outline-width: 3px;
  outline-offset: -4px;
  outline-style: outset;
  text-transform: capitalize;
  text-align: center;
}

.black {
  outline-color: white;
  background-color: black;
  color: white;
}

.white {
  outline-color: black;
  background-color: white;
}

.black::before,
.white::before {
  content: attr(class);
}
<section class='project'></section>
<section class='project'></section>
<section class='project'></section>
<section class='project'></section>
<section class='project'></section>
<section class='project'></section>
<section class='project'></section>
<section class='project'></section>
<section class='project'></section>
<section class='project'></section>

  • Related