我有一些进度条,当它们滚动时,我需要它们开始加载。但是,仅当页面仅在该部分上加载时,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>
答案 0 :(得分:0)
您应该使用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>
答案 1 :(得分:0)
毕竟这是它的工作方式:
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); }