Непоследовательное поведение с API IntersectionObserver - PullRequest
2 голосов
/ 30 мая 2019

У меня есть требование отображать несколько анимированных счетчиков на веб-странице, где анимация запускается при пересечении элемента на основе IntersectionObserver API return.

Что я заметил, так это то, что несмотря на то, что API возвращает true для всех счетчиков, большую часть времени выполняется только первая анимация, а для остальных анимаций мне нужно прокручивать страницу вверх / вниз для остальных счетчиков для анимации.

Это противоречивое поведение сохраняется, даже если мне просто нужно заменить внутренний текст значением из атрибута data (сделал это, чтобы проверить, что сценарий анимации не является виновником).

Ниже приведен код и снимок экрана с 3 счетчиками на одной веб-странице, из трех только первый работает, даже если все три счетчика находятся в первом сгибе экрана.

HTML:

<div class="counter-value" data-count="10000">0</div>
<div class="counter-value" data-count="183.4">0</div>
<div class="counter-value" data-count="270">0</div>

JS:

var config = {
    root: null,
    rootMargin: '0px',
    threshold: 0.5
};

function callback(entry, observer){
    console.log(entry);
    if (entry[0].isIntersecting) {

        var $this = $(entry[0].target),
            countTo = $this.attr('data-count');

        $this.prop({
            countNum: $this.text()
        }).animate({
            countNum: countTo
        },
        {
            duration: 1000,
            easing: 'swing',
            step: function () {
                $this.text(Math.floor(this.countNum));
            },
            complete: function () {
                var localNum = this.countNum.toLocaleString()
                $this.text(localNum);
                console.log(localNum);
            }
        });
        observer.unobserve(entry[0].target);
    };
};

var observer = new IntersectionObserver(callback,config);
var counters = document.querySelectorAll('.counter-value'); //make this an array if more than one item
counters.forEach(counter => {
    observer.observe(counter);
});

Screenshot of counters and console

Есть ли какие-либо указатели на это, если вы когда-либо сталкивались с такой проблемой раньше?

1 Ответ

2 голосов

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

function callback(entries, observer){
  entries.forEach(entry => {
    if (entry.isIntersecting) {

        var $this = $(entry.target),
            countTo = $this.attr('data-count');

        $this.prop({
            countNum: $this.text()
        }).animate({
            countNum: countTo
        },
        {
            duration: 1000,
            easing: 'swing',
            step: function () {
                $this.text(Math.floor(this.countNum));
            },
            complete: function () {
                var localNum = this.countNum.toLocaleString()
                $this.text(localNum);
                console.log(localNum);
            }
        });
        observer.unobserve(entry.target);
    }
  }
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...