【问题标题】:jQuery function stops working when I scroll the page当我滚动页面时,jQuery 函数停止工作
【发布时间】:2019-10-10 10:03:28
【问题描述】:

我有一些进度条,我需要它们在滚动时开始加载。但是,jQuery 函数仅在页面仅加载到该部分时才起作用,并且当我稍微滚动页面时(当它仍在视口中时)该函数停止工作。如果页面从顶部加载并且我向下滚动到此部分,则它根本不起作用。

我尝试了不同的方法让它在视口中工作,所有这些都导致了同样的问题。 我也试过 $(window).on("resize scroll", function ()).

关于如何修复它的任何想法?

$.fn.isInViewport = function() {
  var elementTop = $(this).offset().top;
  var elementBottom = elementTop + $(this).outerHeight();

  var viewportTop = $(window).scrollTop();
  var viewportBottom = viewportTop + $(window).height();

  return elementBottom > viewportTop && elementTop < viewportBottom;
};


$(window).on("scroll", function() {

  $(".radialbar").each(function() {

    var $bar = $(this).find(".radialbar--bar");
    var $val = $(this).find(".radialbar__value-int");
    var perc = parseInt($val.text(), 10);

    if ($(this).isInViewport()) {
      $({
        p: 0
      }).animate({
        p: perc
      }, {
        duration: 3000,
        easing: "swing",
        step: function(p) {
          $bar.css({
            transform: "rotate(" + (45 + (p * 1.8)) + "deg)", // 100%=180° so: ° = % * 1.8
            // 45 is to add the needed rotation to have the green borders at the bottom
          });
          $val.text(p | 0);
        }
      });
    }
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="radialbar">
  <div class="radialbar--base">
    <div class="radialbar--bar"></div>
  </div>
  <div class="radialbar__value">
    <span class="radialbar__value-int">100</span>
    <span class="radialbar__value-perc">%</span>
  </div>
  <div class="radialbar__title">
    Title
  </div>
</div>

【问题讨论】:

    标签: javascript jquery function scroll


    【解决方案1】:

    你应该使用 Intersection Observer 而不是监听滚动事件,尤其是当你想观察多个元素时。

    这个 sn-p 应该让你开始,但请记住以下几点:当元素出现时,我只是切换一个“动画”类。此类仅将宽度从 0 设置为 100%。在这里,您必须添加您的逻辑来确定应该动画多少条。你当然也可以使用 jquery。我也不会观察元素,一旦它被动画就不会再次触发动画。也许你也想改变它,让它每次都有动画。

    const SELECTOR = '.radialbar';
    const ANIMATE_CLASS_NAME = 'animated';
    
    const animate = element => (
      element.classList.add(ANIMATE_CLASS_NAME)
    );
    
    const isAnimated = element => (
      element.classList.contains(ANIMATE_CLASS_NAME)
    );
    
    const intersectionObserver = new IntersectionObserver((entries, observer) => {
      entries.forEach((entry) => {
        
        // when element's is in viewport,
        // animate it!
        if (entry.intersectionRatio > 0) {
        console.log(entry.target);
          animate(entry.target.querySelector('.radialbar--bar'));
          // remove observer after animation
          observer.unobserve(entry.target);
        }
      });
    });
    
    // get only these elements,
    // which are not animated yet
    const elements = [].filter.call(
      document.querySelectorAll(SELECTOR),
      element => !isAnimated(element, ANIMATE_CLASS_NAME)
    );
    
    // start observing your elements
    elements.forEach((element) => intersectionObserver.observe(element));
    .h100 {
    height: 100vh;
    }
    
    .watched {
     opacity: 0;
     transition: opacity .5s;
    }
    
    .radialbar--bar {
    width: 0;
    height: 10px;
    background-color: green;
    transition: all 1s linear;
    }
    
    .radialbar--bar.animated {
    width: 100%;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class="h100">
    scroll ?
    </div>
    <div class="radialbar">
      <div class="radialbar--base">
        <div class="radialbar--bar"></div>
      </div>
      <div class="radialbar__value">
        <span class="radialbar__value-int">100</span>
        <span class="radialbar__value-perc">%</span>
      </div>
      <div class="radialbar__title">
        Title
      </div>
    </div>

    【讨论】:

    • 谢谢,这很有帮助。但同样,它只是在我加载页面时才起作用。也许我的脚本中存在一些冲突!
    【解决方案2】:

    毕竟它是这样工作的:

    var animationStarted = false;
    function startAnimation() {
      animationStarted = true;
      for (var i = 0; i < 10 && animationStarted; i++) {
    
        /* > My function  */
        $(".radialbar").each(function () {
    
          var $bar = $(this).find(".radialbar--bar");
          var $val = $(this).find(".radialbar__value-int");
          var perc = parseInt($val.text(), 10);
    
          $({ p: 0 }).animate({ p: perc }, {
            duration: 2000,
            easing: "swing",
            step: function (p) {
              $bar.css({
                transform: "rotate(" + (45 + (p * 1.8)) + "deg)", // 100%=180° so: ° = % * 1.8
                // 45 is to add the needed rotation to have the green borders at the bottom
              });
              $val.text(p | 0);
            }
          });
        });
        /* x My function */
      }
    }
    /* Uncomment below to call the function every time it is scrolled on */
    // function stopAnimation() {
    //   animationStarted = false;
    //   $(".radialbar").stop();
    // }
    
    $.fn.isOnScreen = function () {
    
      var win = $(window);
    
      var viewport = {
        top: win.scrollTop(),
        left: win.scrollLeft()
      };
      viewport.right = viewport.left + win.width();
      viewport.bottom = viewport.top + win.height();
    
      var bounds = this.offset();
      bounds.right = bounds.left + this.outerWidth();
      bounds.bottom = bounds.top + this.outerHeight();
    
      return (!(viewport.right < bounds.left || viewport.left > bounds.right || viewport.bottom < bounds.top || viewport.top > bounds.bottom));
    
    };
    
    
    
    function randomColor() { return '#' + Math.floor(Math.random() * 16777215).toString(16); }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多