JavaScript/jQuery add class when element comes into viewport?

19,318

Solution 1

You could do something like this: (See CodePen for implementation)

Function taken from here: Check if element is visible after scrolling

CodePen

$(window).on('scroll', function() {
  $(".graph").each(function() {
    if (isScrolledIntoView($(this))) {
      $(this).find(".graph-line").addClass("graph-75");
      $(this).find(".graph-line-2").addClass("opacity");
    }
  });
});

function isScrolledIntoView(elem) {
  var docViewTop = $(window).scrollTop();
  var docViewBottom = docViewTop + $(window).height();

  var elemTop = $(elem).offset().top;
  var elemBottom = elemTop + $(elem).height();

  return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}

Altough this is not perfect, it should point you into the right direction.

Solution 2

You're on the right track, I think if you use the scroll event with a function such as the answer to this similar question:

Check if element is visible after scrolling

Hope that helps :)

Share:
19,318

Related videos on Youtube

mrseanbaines
Author by

mrseanbaines

Updated on June 04, 2022

Comments

  • mrseanbaines
    mrseanbaines over 1 year

    Is there a way to add a class when the element that I want to apply the class to comes into the viewport? Or when the bottom of the screen is a certain distance past the top of the element?

    Right now I have the effect that I want using something like this:

    if ($(document).scrollTop() > 100) {
                        $(".graph-line.two").addClass("graph-75");
    

    The problem with this is that it's relative to the document height, so when I shrink the page (or view on mobile) and the elements stack on top of each other, the page becomes taller and the class (animations) don't start when the element comes into view.

    I've seen other people asking similar questions and I tried to implement the answers they got but I couldn't get anything working so any help would be greatly appreciated.

    This is what I have:

    $(document).ready(function() {
      $(".graph-line.one").addClass("graph-75");
      $(".graph-line-2.one").addClass("opacity");
      $(window).scroll(function() {
    
        if ($(document).scrollTop() > 100) {
          $(".graph-line.two").addClass("graph-75");
          $(".graph-line-2.two").addClass("opacity");
        }
    
        if ($(document).scrollTop() > 450) {
          $(".graph-line.three").addClass("graph-75");
          $(".graph-line-2.three").addClass("opacity");
        }
    
        if ($(document).scrollTop() > 800) {
          $(".graph-line.four").addClass("graph-75");
          $(".graph-line-2.four").addClass("opacity");
        }
    
        if ($(document).scrollTop() > 1150) {
          $(".graph-line.five").addClass("graph-75");
          $(".graph-line-2.five").addClass("opacity");
        }
    
        if ($(document).scrollTop() > 1500) {
          $(".graph-line.six").addClass("graph-75");
          $(".graph-line-2.six").addClass("opacity");
        }
      });
    });
    .graph {
      display: block;
      margin: 100px auto;
      transform: rotate(-90deg);
      will-change: transform;
    }
    .graph-line {
      stroke-dasharray: 628px;
      stroke-dashoffset: -628px;
      transform-origin: center;
    }
    .graph-75 {
      animation: graph-75 1200ms ease forwards;
    }
    @keyframes graph-75 {
      0% {
        stroke-dashoffset: 0;
        transform: rotate(360deg);
      }
      100% {
        stroke-dashoffset: 471;
        transform: rotate(0deg);
      }
    }
    .graph-line-2 {
      transition: opacity 700ms;
      opacity: 0.1;
    }
    .opacity {
      opacity: 1;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
    
    <h1>Scroll Down</h2>
    
    <svg width="250" height="250" class="graph photoshop">
    						<circle class="graph-line-2 one" cx="50%" cy="50%" r="100" stroke-width="20" fill="none" stroke="#2ECBE4" />
    						<circle class="graph-line one" cx="50%" cy="50%" r="100" stroke-width="22" fill="none" stroke="#fff" opacity="0.92" />
    						<text class="graph-text" text-anchor="middle" x="50%" y="-46%" fill="#fff">Photoshop</text>
    					</svg>
    
    
    
    <svg width="250" height="250" class="graph photoshop">
    						<circle class="graph-line-2 two" cx="50%" cy="50%" r="100" stroke-width="20" fill="none" stroke="#2ECBE4" />
    						<circle class="graph-line two" cx="50%" cy="50%" r="100" stroke-width="22" fill="none" stroke="#fff" opacity="0.92" />
    						<text class="graph-text" text-anchor="middle" x="50%" y="-46%" fill="#fff">Photoshop</text>
    					</svg>
    
    
    
    <svg width="250" height="250" class="graph photoshop">
    						<circle class="graph-line-2 three" cx="50%" cy="50%" r="100" stroke-width="20" fill="none" stroke="#2ECBE4" />
    						<circle class="graph-line three" cx="50%" cy="50%" r="100" stroke-width="22" fill="none" stroke="#fff" opacity="0.92" />
    						<text class="graph-text" text-anchor="middle" x="50%" y="-46%" fill="#fff">Photoshop</text>
    					</svg>
    
    
    
    <svg width="250" height="250" class="graph photoshop">
    						<circle class="graph-line-2 four" cx="50%" cy="50%" r="100" stroke-width="20" fill="none" stroke="#2ECBE4" />
    						<circle class="graph-line four" cx="50%" cy="50%" r="100" stroke-width="22" fill="none" stroke="#fff" opacity="0.92" />
    						<text class="graph-text" text-anchor="middle" x="50%" y="-46%" fill="#fff">Photoshop</text>
    					</svg>
    
    
    
    <svg width="250" height="250" class="graph photoshop">
    						<circle class="graph-line-2 five" cx="50%" cy="50%" r="100" stroke-width="20" fill="none" stroke="#2ECBE4" />
    						<circle class="graph-line five" cx="50%" cy="50%" r="100" stroke-width="22" fill="none" stroke="#fff" opacity="0.92" />
    						<text class="graph-text" text-anchor="middle" x="50%" y="-46%" fill="#fff">Photoshop</text>
    					</svg>
    
    
    
    <svg width="250" height="250" class="graph photoshop">
    						<circle class="graph-line-2 six" cx="50%" cy="50%" r="100" stroke-width="20" fill="none" stroke="#2ECBE4" />
    						<circle class="graph-line six" cx="50%" cy="50%" r="100" stroke-width="22" fill="none" stroke="#fff" opacity="0.92" />
    						<text class="graph-text" text-anchor="middle" x="50%" y="-46%" fill="#fff">Photoshop</text>
    					</svg>

    Here's the codepen if you prefer

  • Craig
    Craig almost 7 years
    You literally just copy + pasted the answer from the link I provided?
  • Founded1898
    Founded1898 almost 7 years
    Haven't seen your answer when i wrote mine. Researched it by myself, we just ended on the same SO Question... Also note that i created a CodePen where i tested the solution, so its not just copy + pasting.
  • Craig
    Craig almost 7 years
    Fair enough, it was just 20 minutes after mine! I guess a quick google is really all it takes.
  • mrseanbaines
    mrseanbaines almost 7 years
    @Founded1898 Thanks, both of you! That worked perfectly. I'm just wondering now if I can adjust the size of the gap between when the element comes into view and when the class is added. ie. I would like the class added at an earlier stage of scrolling, say, when the element is half in view.
  • mrseanbaines
    mrseanbaines almost 7 years
    Thanks for the help :)
  • Founded1898
    Founded1898 almost 7 years
    @Sean well, you could change the return statement of the function so that it checks the elemTop & elemBottom minus half the height of your svg. Maybe something like this: return ((elemBottom - circleHeight <= docViewBottom) && (elemTop - circleHeight >= docViewTop)); whereas circleHeight is elem.height() / 2