将页面滚动到某个元素后,我需要为该元素添加一个类。问题是,错误的元素获取类,因为完成的函数在完成滚动动画之前触发。我知道因为如果我将完整的函数包装在setTimeout()
中就可以了。
为什么完成功能会在完成之前触发?这是一个已知的问题吗?什么是解决这个问题最可靠的方法?
我的代码:
$('html, body').animate({
scrollTop: current_element_position + 'px'
}, 'fast', function(){
current_element.addClass('current_element');
});
答案 0 :(得分:2)
您正在对2个元素调用动画效果:html
和body
。这意味着动画实际上运行了两次,完整的函数也会被调用两次。
通常这样做的原因是某些浏览器仅支持滚动html
而其他浏览器仅支持滚动body
。这个选择器将同时作为目标,解决了这个问题,但也会导致这个双动画调用。
实际滚动的动画完成得更快,因此在完成另一个元素上的真实动画之前触发完整的调用。
知道这一点你可以通过设置一个额外的变量来解决它,所以你的代码只能在最后一次调用时执行。
var isComplete = false;
$('html, body').animate({
scrollTop: current_element_position + 'px'
}, 'fast', function() {
if (isComplete) {
current_element.addClass('current_element');
isComplete = false;
}
else {
isComplete = true;
}
});
甚至更简单,使用承诺。
$('html, body')
.animate({ scrollTop: current_element_position + 'px' }, 'fast')
.promise()
.then(function() {
current_element.addClass('current_element');
});
答案 1 :(得分:0)
我不知道您的HTML是怎样的。尽管如此,我希望我有了你的意图并尝试了另一种没有jQuery和动画的方法。它基本上检查页面滚动时元素的顶部是否在特定范围内。也许它有帮助...
var divs = document.querySelectorAll('.testdiv');
window.onscroll = function() {
divs.forEach(function(item) {
var top = item.getBoundingClientRect().top;
item.style.background = 'transparent';
if (top >= 70 && top <= 140) {
item.style.background = 'red';
}
});
}
.testdiv{
width: 200px;
height: 70px;
border: 1px solid black;
}
.testdiv:first-of-type{
margin-top: 100px;
}
<div class="testdiv"></div>
<div class="testdiv"></div>
<div class="testdiv"></div>
<div class="testdiv"></div>
<div class="testdiv"></div>
<div class="testdiv"></div>
<div class="testdiv"></div>
<div class="testdiv"></div>
<div class="testdiv"></div>
<div class="testdiv"></div>
<div class="testdiv"></div>
<div class="testdiv"></div>
<div class="testdiv"></div>
<div class="testdiv"></div>
<div class="testdiv"></div>
<div class="testdiv"></div>
<div class="testdiv"></div>
答案 2 :(得分:0)
如果您打算在滚动到视图中的元素时添加Class,请尝试以下代码。
$(function() {
/**
jQuery Custom method to find if element is in View
*/
$.fn.isInView = function() {
if (!this.length) return false;
var rect = this.get(0).getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
);
};
/**
Window Scroll Event:
*/
$(window).on('scroll', function(e) {
var $this = $(this);
/**
Trigger Custom Event on timeout if Scroll is stopped else clear the timeout
*/
clearTimeout($this.data('scrollTimeout'));
$this.data('scrollTimeout', setTimeout(function() {
$(window).trigger('scrollStop')
}, 50, e));
});
/**
On ScrollStop Loop Through Each Element and check if it is in view, If yes add Class else remove Class
*/
$(window).on('scrollStop', function(ev) {
$('div').each(function() {
var $div = $(this)
if ($div.isInView()) {
$div.addClass('color');
} else {
$div.removeClass('color');
}
});
}).trigger('scrollStop');
});
div {
width: 100%;
height: 170px;
border: 1px solid black;
}
.color {
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
答案 3 :(得分:0)
**您可以使用窗口滚动属性** 试试这个它应该工作。当你滚动到div然后添加类,当你再次移动到顶部然后类删除。 你可以在这里查看https://jsfiddle.net/surendra786/qnhw5ov7/
html --
<p class="new"></div>
script ---
$('document').ready(function(){
var current_element=$('.new');
var current_element_position = $('.new').position().top;
$(window).scroll(function() {
var scroll = $(window).scrollTop();
current_element.toggleClass('current_element',
scroll >= current_element_position
);
});
});