JavaScript/jQuery add class when element comes into viewport?

五迷三道 提交于 2019-12-24 08:04:10

问题


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


回答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.




回答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 :)



来源:https://stackoverflow.com/questions/41144113/javascript-jquery-add-class-when-element-comes-into-viewport

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!