javascript - jQuery:滚动过去 div 时添加/删除样式
问题描述
我有这个页面(https://www.datacoral.com/architecture/),它的左侧边栏有五个要点。我想要发生的是当用户滚动通过右侧列上的这五个 div 时,这些项目符号之一中的文本添加了一个名为“粗体”的类,并且文本变为 700 的字体权重以让用户知道他们在页面上的位置。当经过同一个 div 时,该类消失并在下一个要点中结束,因为您现在正在经过另一个 div。
我已经让它部分工作,但它根本没有达到 div 的正确点。似乎在传递 div 的底部而不是顶部时添加了类。
这是我目前正在使用的代码。任何人都知道我可能做错了什么,所以这可以正常工作吗?
注意:应该提到我基本上将这段代码复制了五次,只是换掉了数字。
jQuery(function(){
jQuery(window).scroll(function() {
var scroll = jQuery(window).scrollTop(); // how many pixels you've scrolled
var os = jQuery('#guide_body-0').offset().top; // pixels to the top of div1
var ht = jQuery('#guide_body-0').height(); // height of guide_body-0 in pixels
if(scroll > os + ht){
jQuery('.scroll-nav-0').addClass('bolder');
}
});
});
解决方案
I think firing a function on scroll like that gets a little bit crazy. I always delay the function until the scrolling has stopped.
As far as the catch point, i think your code is applying the classes when the element has moved out of view. i would use the bottom of the browser screen as a reference point.
Think about it like this:
$(window).scrollTop()
returns 0 at the top of the page.$('#guide_body-0').offset().top
returns 1000px.- So
$(window).scrollTop()
is equal to$('#guide_body-0').offset().top
when that element is at the top of the screen. - Add
$('#guide_body-0').height()
to the equation and that puts the scroll position (the top of the screen) at the bottom of the element.
What you need to do is check if the offset.top property of the element is in a scroll position which puts it above the bottom of the screen.
- UPDATE
The code here is for a custom solution. But if you are looking for a way to just add simple animations to elements as they scroll into view, check out wow.js and animate.css
https://wowjs.uk/ https://animate.style/
// Init variable for timer
let timer;
// Get target element
const el = $("#4");
// Get viewport height
const screen = window.innerHeight;
// Fire callback on window scroll
$(window).scroll(function() {
// Clear timeout just in case
clearTimeout(timer);
// Check if the element already has the class
if (!el.hasClass("active")) {
// Set a delay timer then run the function
timer = setTimeout(check_el_pos, 300);
}
});
function check_el_pos() {
// Clear the timer
clearTimeout(timer);
// Get current scroll position
let scroll_pos = $(window).scrollTop();
// This is the math here. Add scroll position to screen height and you get the bottom of the screen. When that value equals the top offset of the element, we are there.
if (scroll_pos + screen > el.offset().top) {
console.log(scroll_pos + screen);
console.log(el.offset().top);
// Add the classes to the element. Boom, we're done.
el.removeClass("active").addClass("active");
}
}
body,
html {
padding: 0;
margin: 0;
}
.example-grid {
list-style: none;
padding: 0;
margin: 0;
width: 100%;
display: grid;
grid-gap: 40px;
}
.example-grid>li {
list-style: none;
padding: 0;
margin: 0;
width: 100%;
height: 65vh;
background: slategray;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
color: #fff;
font-size: 2em;
line-height: 1em;
transition: background-color 1s;
transition-timing-function: ease-out;
}
.example-grid>li:nth-child(even) {
background: coral;
}
.example-grid>li.active {
background: aquamarine;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="example-grid">
<li id="1">1</li>
<li id="2">2</li>
<li id="3">3</li>
<li id="4">4</li>
<li id="5">5</li>
<li id="6">6</li>
<li id="7">7</li>
</ul>
推荐阅读
- javascript - 如何导入导出的函数
- reactjs - 如何启用提交按钮当我在表单的所有输入标签中输入数据时
- javascript - Gatsby 中样式和元素测量(scrollWidth / scrollWidth)的奇怪问题
- mysql - 将mysql查询输出拆分为变量
- git - 我可以更改推送到远程存储库的最后一次提交吗?
- sql - 在服务器之间移动数据 - 是否可以(好主意)遍历表
- android - 如何从 Fire Store 指定这些文档以获取特定的用户 RecyclerView 活动?
- ethereum - 获取 web3 元掩码中的注册资产
- swift - 如何在 Swift 中直接访问内部类
- vue.js - 使用 Vuex 以 toast 消息的形式向组件返回错误消息