Функция jQuery перестает работать, когда я прокручиваю страницу - PullRequest
0 голосов
/ 10 октября 2019

У меня есть несколько индикаторов выполнения, и мне нужно, чтобы они начали загружаться при прокрутке. Однако функция jQuery работает только тогда, когда страница загружается только в этом разделе, и когда я слегка прокручиваю страницу (пока она все еще находится в порту просмотра), функция перестает работать. Если страница загружается сверху, а я прокручиваю вниз, чтобы добраться до этого раздела, она не работает вообще.

Я пробовал разные подходы, чтобы заставить его работать, когда он находится в поле зрения, все из которых привели к одной и той же проблеме. Я также пробовал $ (window) .on ("прокрутка изменения размера", 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>

Ответы [ 2 ]

0 голосов
/ 12 октября 2019

Вот как это все-таки работает:

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); }
0 голосов
/ 10 октября 2019

Вы должны использовать Intersection Observer вместо прослушивания события прокрутки, особенно если вы хотите наблюдать несколько элементов.

Этот фрагмент должен помочь вам начать, но помните следующее: я просто переключаю «анимированный» класс, когда элемент появляется в поле зрения. Этот класс анимирует только ширину от 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...