Liam
Liam

Reputation: 9855

Run function on each element not once

I have a page with 5 panels on it. When each panel comes into view I want 2 of it's child elements to decrease in size dependant on the users scroll amount.

I have written a function that manages to shrink the DIV somewhat but It occurs on all of them and not when each element comes into view, does this make sense?

https://jsfiddle.net/n7vmaz9s/

$(window).scroll(function () {
  var scrollTop = $(window).scrollTop();
  if (scrollTop < 200) {
    newWidth = 15;
  } else if (scrollTop > 400) {
    newWidth = 7.5;
  } else {
    newWidth = 15 - 7.5 * ((scrollTop - 200)) / 200;
  }
  $('.before').css({
    'width': newWidth + "%"
  });
  $('.after').css({
    'width': newWidth + "%"
  });
})

How can I get each 'before' and 'after' div to work when that elements parent comes into view?


I've also tried using .each as so...

$(window).scroll(function () {
  $(".service-image").each(function(){
      elementOffset = $(this).offset().top
    var scrollTop = $(window).scrollTop();
    elemDist = elementOffset - scrollTop;
      console.log(elementOffset - scrollTop);
      if (elemDist < 0) {
          newWidth = 15;
      } else if (elemDist > 400) {
          newWidth = 7.5;
      } else {
          newWidth = 15 - 7.5 * ((scrollTop - 200)) / 200;
      }
      $('.before').css({
          'width': newWidth + "%"
      });
       $('.after').css({
          'width': newWidth + "%"
      });
    });
})

Upvotes: 2

Views: 61

Answers (1)

Andrew Leedham
Andrew Leedham

Reputation: 718

Not sure if I fully understand the desired effect. But I wrote a fiddle that imitates the way each panel animates, but for individual panels when they are "in view": https://jsfiddle.net/zd0p8jfu/

$(window).scroll(function () {
    var scrollTop = $(window).scrollTop();
    $(".service-image").each(function(){
        var relativeScroll = scrollTop - $(this).offset().top;
      if (scrollTop < $(this).offset().top + 200) {
          newWidth = 15;
      } else if (scrollTop > $(this).offset().top + 400) {
          newWidth = 7.5;
      } else {
          newWidth = 15 - 7.5 * ((relativeScroll - 200)) / 200;
      }
      $(this).find('.before').css({
          'width': newWidth + "%"
      });
       $(this).find('.after').css({
          'width': newWidth + "%"
      });
    });
});

To reverse the direction you just need to swap the maths like so:

$(window).scroll(function () {
    var scrollTop = $(window).scrollTop();
    $(".service-image").each(function(){
        var relativeScroll = scrollTop - $(this).offset().top;
      if (scrollTop < $(this).offset().top + 200) {
          newWidth = 7.5;
      } else if (scrollTop > $(this).offset().top + 400) {
          newWidth = 15;
      } else {
          newWidth = 7.5 * ((relativeScroll - 200) / 200) + 7.5;
      }
      $(this).find('.before').css({
          'width': newWidth + "%"
      });
       $(this).find('.after').css({
          'width': newWidth + "%"
      });
    });
});

Upvotes: 2

Related Questions