我正在构建一个包含多个部分的网站,我希望每次该部分都在视口中时为该部分提供一个活动状态。我的HTML结构看起来像这样:
<header></header>
<section id="intro"></section>
<section id="schools"></section>
<section id="quotes"></section>
<section id="projects"></section>
依旧......
在CSS中,我的部分由VH单位定义。为了使用定义的垂直断点,我计算了它们并得出了一个我在Js中用作数组的序列。
// Cache the Window object
var windowScroll, $h, pos;
$window = $(window);
// Cache the height of the window for future reference
// as section height = 100vh, 2nd section = h * 2, 3rd = h * 3, and so on
$h = window.innerHeight;
// pos[0] is the end of the header,
// pos[1] is the end of the 1st section
pos = [$h * 1, $h * 2.1, $h * 3.2, $h * 4.7];
// Cache the sections in an array
sections = document.getElementsByTagName("section");
如果我写这篇文章,它会工作:
if ((!$(sections[0]).hasClass('active')) && (windowScroll <= pos[0]) && (windowScroll <= pos[1])) {
console.log("Scroll is contained between " + pos[0] + " and " + pos[1]);
$(sections[0]).addClass('active'); //
}
但是我想避免为每个部分编写它。如果我尝试使用 for 或每个循环,它会立即将类添加到每个部分,而不会在视口中定位该部分。
// This is not working
$(sections).each(function(i) {
if(!$(this).hasClass('active')){
if ((windowScroll <= pos[i]) && (windowScroll <= pos[i+1])) {
console.log("Scroll is contained between " + pos[i] + " and " + pos[i+1]);
$('section').eq(i).addClass('active');
}
}
});
我错过了什么?
答案 0 :(得分:0)
以下是解决方案:https://jsfiddle.net/xtpqwjur/
代码:
// Cache the Window object
var windowScroll, $h, pos;
$window = $(window);
// Cache the height of the window for future reference
// as section height = 100vh, 2nd section = h * 2, 3rd = h * 3, and so on
$h = window.innerHeight;
// pos[0] is the end of the header,
// pos[1] is the end of the 1st section
pos = [$h * 1, $h * 2.1, $h * 3.2, $h * 4.7, $h * 6.2];
// Cache the sections in an array
sections = document.getElementsByTagName("section");
// Avoid loop on scroll function
var scroll_timeout, scroll_trigger_time, userScrolled; // Cache variables
var userScrolled = false; // The scroll is false by default
var scroll_trigger_time = 100; // Trigger after x ms of scroll
function on_window_scroll() {
if (userScrolled) {
userScrolled = false;
$('section.active').removeClass('active');
$(sections).each(function (i, value) {
if ( !$(this).hasClass('active') && (windowScroll >= pos[i] && windowScroll <= pos[i+1]) ) {
console.log('scroll between ' + pos[i] + ' and ' + pos[i+1]);
$('section.active').removeClass('active');
$(sections[i]).addClass('active');
}
});
}
}
window.addEventListener("scroll", function () {
userScrolled = true;
if(scroll_timeout !== null) clearTimeout(scroll_timeout); // Clear the scroll cache at if time is out
scroll_timeout = setTimeout(on_window_scroll, scroll_trigger_time); // Trigger a function within the scroll
windowScroll = Math.floor(window.pageYOffset); // Listen to the scroll position
});
主要问题是您的比较运算符 - 您正在执行
(windowScroll <= pos[i]) && (windowScroll <= pos[i+1])
表示,“如果滚动位置比(部分)少,而且比(部分+ 1)少。
我改为:
(windowScroll >= pos[i] && windowScroll <= pos[i+1]
表示,“如果滚动位置等于或大于(部分),则小于或等于(部分+ 1)。
您可以将上限(<=pos[i+1]
)更改为小于(而不是小于或等于)以防止重叠条件。