Sibling item in vanilla JS which doesnt have a particular class among it siblings

<section class="theme-width">
	<article class="pic-text-slide">
		<p>Sibling 1</p>
	</article>
	<article class="pic-text-slide none">
		<p>Sibling 2</p>
	</article>
	<article class="pic-text-slide none">
		<p>Sibling 3</p>
	</article>
	<article class="pic-text-slide none">
		<p>Sibling 4</p>
	</article>
	<button class="eventclick">Next</button>
</section>

I will add a click add event listener, but what I am trying to achieve is this:

when the button is clicked I want to search the article HTML tang which doesn’t have a "none’ class. In a later situation, the article will be the first among its siblings, which will not have a class any, but it is dynamic later in the script. which JS API should I follow to get that sibling node where we do not have a none class?

This could be helpful in my case or may be JS is vast something else could be there →

var r4 = el.closest(":not(div)");

I dont know if I can modify this to make sure that I get an article tag, which deosnt have none class.

Poorly defined tree traversal.

From where in your tree are you starting, and where are you trying to go, and what parts of it will be dynamic.

From button to first sibling in the list that doesnt have class ‘none’? button.parentElement.querySelector("article:not(.none)");

1 Like

Hi, @m_hutley,

Thanks for the feedback, how will you design the tree traversal. Please help me with your version, Thanks.

So when it comes to ‘ill-defined’ (read as: not a specific motion; not “move to next”, or “move 3 siblings”, but “move somewhere”) tree traversal, most of your tools are going to be looking up or down, rather than sideways.

So it’s easier in these cases to go up (parentNode), and then search downward.

1 Like

Hi there @m_hutley
I completely didn’t understand what you were saying, but I came with a version that is working →

const buttonClick = document.querySelector(".eventclick");
buttonClick.addEventListener('click', event => {
	var traverse = buttonClick.parentElement.querySelector("article:not(.none)");
	console.log(traverse);
	traverse.classList.add("none");
	var nSibling = traverse.nextElementSibling.classList.remove("none");
});

If you can spend some minutes to give feedback and is there any alternative precise method, which will exert less gravity on DOM manipulation in this case.

But there is adead ened in the script both ways, when the script reaches the bottom of the list of last sibling, next button should be dismissed or atleast deactivated, and same goes for top most sibling, when the traversal reaches the top most sibling previoous should be disabled or dismissed, but I do not have any logical clarity how to move forward from this point.

When you’re at the last article, what is true of traverse.nextElementSibling ? (or perhaps, traverse.nextElementSibling.nextElementSibling?)

1 Like

button

so.

You’ve got a unique trigger, and you know what actions to execute. What am I missing here?

1 Like

Trust me in terms of logic I pondered all these, but I do not know how to execute in terms of syntax.

I made certain ammendments: It worked.

const nextClick = document.querySelector(".next");
nextClick.addEventListener('click', event => {
	var traverse = nextClick.parentElement.querySelector("article:not(.none)");
	console.log(traverse);	
	var nSibling = traverse.nextElementSibling;
	if (nSibling.classList.contains("pic-text-slide")) {
		nSibling.classList.remove("none");
	traverse.classList.add("none");		
	}
});

This finally is addressing the issue:

const nextClick = document.querySelector(".next");
nextClick.addEventListener('click', event => {
	var traverse = nextClick.parentElement.querySelector("article:not(.none)");
	var nSibling = traverse.nextElementSibling;
	if (nSibling.classList.contains("pic-text-slide")) {
		nSibling.classList.remove("none");
		traverse.classList.add("none");		
	}
});

const previousClick = document.querySelector(".previous");
previousClick.addEventListener('click', event => {
	var traverse = previousClick.parentElement.querySelector("article:not(.none)");
	var pSibling = traverse.previousElementSibling;
	if (pSibling.classList.contains("pic-text-slide")) {
		pSibling.classList.remove("none");
		traverse.classList.add("none");	
	}
});

Hi @codeispoetry, I don’t think such DOM manipulations would be an issue but you don’t need to traverse the siblings on each click – just query for the slides initially and store the currently active index.

You can then set the button disabled states depending on that index like so:

const nextClick = document.querySelector('.next')
const previousClick = document.querySelector('.previous')
const slides = document.querySelectorAll('.pic-text-slide')
let active = 0

function switchSlide (next) {
  active = Math.max(0, Math.min(slides.length - 1, next))

  nextClick.disabled = active === slides.length - 1
  previousClick.disabled = active === 0

  slides.forEach((slide, index) => {
    slide.classList.toggle('none', index !== active)
  })
}

nextClick.addEventListener('click', () => switchSlide(active + 1))
previousClick.addEventListener('click', () => switchSlide(active - 1))

Alternatively, make the slides loop infinitely:

function switchSlide (next) {
  active = (next + slides.length) % slides.length

  slides.forEach((slide, index) => {
    slide.classList.toggle('none', index !== active)
  })
}

Hi there @m3g4p0p
Thank you so much for your input.

Is there any quantitative reason such as browser memory consumption, overload on some browser performance etc?

class none, in some real example, will be replaced by class with name = holidayclass

This holidayclass will be used on many inside elements such as .holidayclass .picture img {css here such as translateX} , in those articles or div tag for animation and image slides later so the class was needed. I will take a closer look at your code.

No, such DOM queries (especially if only on click) certainly wouldn’t be an issue… it’s just not necessary either, so I was merely sketching out another structural approach. :-)

1 Like

Ok, Thanks, I will analyze your code in detail and will come back in case I need any help.

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.