Как объединить несколько прослушивателей событий прокрутки в один? - PullRequest
0 голосов
/ 26 мая 2020

У меня есть следующая функция, которая уменьшает масштаб изображений после того, как они попадают в область просмотра. Прямо сейчас он присоединяет столько слушателей событий, сколько элементов. По соображениям производительности я хотел бы объединить их в один прослушиватель событий для всех элементов, но я не знаю как. Вот мой код:

HTML

<div class="image-wrapper"> 
    <div class="image-container elem-1">
        <div class="zoom-images">
            <img class="zoom" src="test" alt="test">
        </div>
    </div>
    <div class="image-container elem-2">
        <div class="zoom-images">
            <img class="zoom" src="test" alt="test">
        </div>
    </div>
    <div class="image-container elem-3">
        <div class="zoom-images">
            <img class="zoom" src="test" alt="test">
        </div>
    </div>
</div>

JAVASCRIPT

$('.zoom').each(function() {
    var el = $(this);
    var inViewport = false;
    var isZooming = false;
    originY = 0;
    window.addEventListener('scroll', throttle(zoomImage, 250), {passive: true});
    function zoomImage() {
        originY = $(window).scrollTop();
        if (el.isInViewport()) {
            if (!inViewport) {
                inViewport = true; 
            }
        } else {
            if (inViewport) {
                inViewport = false;
            }
        }   
        if (inViewport) {
            if (!isZooming) {
                window.requestAnimationFrame(function () {
                    el.addClass('is-zooming');
                });
                isZooming = true;
            }
        } else {
            if (isZooming) {
                window.requestAnimationFrame(function () {
                    el.removeClass('is-zooming');
                });
                isZooming = false;
            }
        }
    };
    $.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;
    };
});

Любая помощь будет принята с благодарностью! Большое спасибо!

Ответы [ 2 ]

0 голосов
/ 28 мая 2020

Я нашел решение. Для всех кому интересно решил вот так:

window.addEventListener('scroll', throttle(check_if_in_view, 220), {
    capture: true,
    passive: true
});
var $animation_elements = $('.zoom-images');
var $window = $(window);
function check_if_in_view() {
    var window_height = $window.height();
    var window_top_position = $window.scrollTop();
    var window_bottom_position = (window_top_position + window_height);
    $.each($animation_elements, function() {
        var $element = $(this);
        var $zoom = $(this).children('img.zoom');
        var element_height = $element.outerHeight();
        var element_top_position = $element.offset().top;
        var element_bottom_position = (element_top_position + element_height);
        if ((element_bottom_position >= window_top_position) &&
            (element_top_position <= window_bottom_position)) {
            requestAnimationFrame( function() {
                $zoom.addClass('is-zooming');
            });
        } else {
            requestAnimationFrame( function() {
                $zoom.removeClass('is-zooming');
            });
        }
    });
};
0 голосов
/ 26 мая 2020

Прикрепите слушателей к контейнерам с интересными вещами, и события будут «всплывать» на них. (Вызов события скажет вам, какой объект был целью.)

...