如何将多个滚动事件侦听器合并为一个?
How can I combine multiple scroll event listeners into one?
我有以下功能可以在图像进入视口后缩小图像。现在它附加了与元素一样多的事件监听器。出于性能原因,我想将这些组合到所有元素的一个事件侦听器中,但我不知道该怎么做。这是我的代码:
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;
};
});
如有任何帮助,我们将不胜感激!非常感谢!
将侦听器附加到容器 感兴趣的事物和事件将"bubble up" 到它们。 (事件调用会告诉您哪个对象是目标。)
我找到了解决方案。对于任何有兴趣的人,我是这样解决的:
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');
});
}
});
};
我有以下功能可以在图像进入视口后缩小图像。现在它附加了与元素一样多的事件监听器。出于性能原因,我想将这些组合到所有元素的一个事件侦听器中,但我不知道该怎么做。这是我的代码:
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;
};
});
如有任何帮助,我们将不胜感激!非常感谢!
将侦听器附加到容器 感兴趣的事物和事件将"bubble up" 到它们。 (事件调用会告诉您哪个对象是目标。)
我找到了解决方案。对于任何有兴趣的人,我是这样解决的:
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');
});
}
});
};