So I have a setup like this
<div class=“container”>
<div class=“segment1”></div>
<div class=“segment2”></div>
<div class=“segment3”></div>
.
.
.
<div class=“segmentN”></div>
</div>
Where N is an number defined by user so list is dynamical. For container I have applied styles to display it as grid, so EVERY time list has 3 items displayed, list is scrollable. My problem is, how can I via VanillaJS find element which is in the middle of container ? If there are 3 elements in the page, it should select 2nd one, when scrolling down it should select element which is in the middle of container every time to apply some styles to it in addition to grab it’s id. If there are 2 elements, it should select 2nd item as well. I was thinking about checking height of container, divide it by half and checking position of element if it’s in range. So far I was able to write this code in js
function findMiddleSegment() {
//selecting container
const segmentListContainer = document.querySelector(`.segmentListContainer`);
const rect = segmentListContainer.getBoundingClientRect();
//selecting all divs
const segments = document.querySelectorAll(`.segmentContainer`);
segments.forEach( (segment) => {
const location = segment.getBoundingClientRect();
if( (location.top >= rect.height / 2) ){
segment.classList.add(`midsegment`);
} else {
segment.classList.remove(`midsegment`);
}
});
}
But it doesn’t work. It finds element in the middle as should, but also applies style for every other element beneath middle segment. I’ve read some answers on stackoverflow, but couldn’t find any idea how to solve my problem
CodePudding user response:
If container has only a list of segments inside, it's easer to count the element's children and find the mid element.
const segmentListContainer = document.querySelector(`.segmentListContainer`);
const midSegmentIndex = Math.floor(segmentListContainer.children.length / 2) - 1;
let midSegment = segmentListContaner.children[midSegmentIndex];
midSegment.classList.add('midsegment');
P.S.
The reason why your code adds 'mdsegment' to each element's class name after the real midsegment element is because of this conditional statement line you wrote.
if(location.top >= rect.height / 2){
segment.classList.add(`midsegment`);
}
CodePudding user response:
Something like this. You can use Math.round, Math.ceil or Math.floor like I did. This works because querySelectorAll returns an array and you can use array.length to count the total number of items in the array then use a for loop to loop over all the segments and place the class based on the Math.(round, floor or ceil) based on your needs.
const container = document.querySelector(".container");
const segments = container.querySelectorAll(".segment");
const middleSegment = Math.floor(segments.length / 2);
for (let index = 0; index < segments.length; index ) {
segments[middleSegment].classList.add("middle-segment");
}
.middle-segment{
background-color: red;
}
<div class="container">
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
</div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>