首页 > 解决方案 > 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');
             }
         });
    });

标签: javascriptjquery

解决方案


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:

  1. $(window).scrollTop() returns 0 at the top of the page.
  2. $('#guide_body-0').offset().top returns 1000px.
  3. So $(window).scrollTop() is equal to $('#guide_body-0').offset().top when that element is at the top of the screen.
  4. 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>


推荐阅读