Home > OS >  IsInView and each
IsInView and each

Time:12-16

Is there a way to set IsInView to wait for each element with the same class, so I don't have to call them one by one?

For example if I have three sections, I just want to call them like this:

$(".section").on('inview', function(event, isInView) {
  if (isInView) {
    $(this).show();
  }
});

So that all three section appear one by one:

<div id="section-1" >
</div>
<div id="section-2" >
</div>
<div id="section-3" >
</div>

EDIT: I've also tried with each but that doesn't work either:

$('.section').each(function() {
  $(this).on('inview', function(event, isInView) {
    if (isInView) {
      $(this).show();
    }
  });
});

CodePudding user response:

Nowadays jQuery is considered an overhead.
In pure, vanilla JavaScript the IntersectionObserver API is a good tool for the task:

const inViewport = (entries, observer) => {
  entries.forEach(entry => {
    entry.target.classList.toggle("is-inviewport", entry.isIntersecting);
  });
};

document.querySelectorAll('[data-inviewport]').forEach(EL => {
  new IntersectionObserver(inViewport).observe(EL, { /*options*/ });
});
.section { /* THIS DEMO ONLY */
  height:100px; background:#0bf; margin: 150vh 0; 
}


/* inViewport */

[data-inviewport="fadein"] { 
  transition: 2s;
  opacity: 0;
}
[data-inviewport="fadein"].is-inviewport {
  opacity: 1;
}
<div  data-inviewport="fadein">1</div>
<div  data-inviewport="fadein">2</div>
<div  data-inviewport="fadein">3</div>

For more observer options read: https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#Intersection_observer_options

CodePudding user response:

You could put them in promises and wait until they're all finished with:

Promise.all([
      promise1(),
      promise2(),
      promise3()
    ])
.then(showThem)

But I think your issue is not with async behaivour, but with the selector, cause I believe JQuery just gets one element when you do $('section'), so doing a forEach loop on that makes no sense. I am not sure how to do it with jquery, but I would do it like this

document.getElementsByClassName("section").forEach(sectionElement => {
  sectionElement.on('inview', function(event, isInView) {
    if (isInView) {
      sectionElement.show();
    }
  });
});
  • Related