【问题标题】:How to add class on div scroll top and remove on div scroll out?如何在 div 滚动顶部添加类并在 div 滚动时删除?
【发布时间】:2019-03-20 23:15:33
【问题描述】:

我希望添加 'opacity' 类来列出项目,因为 div 的顶部在视口中变得可见,并在 div 离开视口时删除该类,反之亦然

这是笔https://codepen.io/anon/pen/pYOrOV

我对 jquery 不是很熟悉,所以在这里可能会犯一些愚蠢的错误,但是,它是使用航点功能还是第二种选择?任何建议将不胜感激谢谢。

$('.wrapperright').scroll(function () {
    if(y >= s_body.top && y < e_body.top){
        $('#generationanxiety').addClass('opacity');
    }
    else 
    {
        $('#generationanxiety').removeClass('opacity');
    }
});

【问题讨论】:

  • 如果一个 div 滚动出视口,它是否可见有什么关系?有点像“如果一棵树倒在森林里,周围没有人,它还会发出声音吗?” 当然它会发出声音,但没有人在乎,就像没有人会在乎是否有看不见的东西一样div 超出视口。
  • 我的意思是,一旦 div 的底部离开视口,它就会触发一个函数从一个 div 中删除该类并将该类添加到下面的下一个 div

标签: jquery


【解决方案1】:

使用getBoundingClientRect() 最容易检查项目是否在视口中。因此,我将其与图像周围 div 上的 data 属性结合使用 - 以便将它们与相应 li 项目的 id 匹配。

Demo with explanatory comments

$(window).on('load', function() {

  var pouch = $('.wrapperright'),
  items = pouch.find('div'),
  gate, spot = {},
  zone = pouch.scrollTop(),
  haze = 'opacity';

  $(this).resize(collectInfo).resize();

  pouch.scroll(function() {

    items.each(function() {

      var aim = $('#' + $(this).data('target')),
      edges = this.getBoundingClientRect(),
      apex = Math.round(edges.top),
      nadir = Math.round(edges.bottom);

      if (apex < gate && nadir > 0) aim.removeClass(haze);
      else aim.addClass(haze);
    });

    var rise = $('.bio li').not('.' + haze),
    turf = pouch.scrollTop();

    if (rise.length > 1) {
      if (turf > zone) rise.eq(0).addClass(haze);
      else rise.eq(1).addClass(haze);
    }

    zone = turf;
  });

  $('.bio li').click(function() {

    if (zone == spot[this.id]) return;

    pouch.stop().animate({scrollTop: spot[this.id]}, 1500);
  });

function collectInfo() {

  gate = $(this).height();

  items.each(function() {

    spot[$(this).data('target')] = Math.round($(this).position().top+zone);
  });
}
});

$(window).on('load', function() {

  var pouch = $('.wrapperright'),
  items = pouch.find('div'),
  gate, spot = {},
  zone = pouch.scrollTop(),
  haze = 'opacity';

  $(this).resize(collectInfo).resize();

  pouch.scroll(function() {

    items.each(function() {

      var aim = $('#' + $(this).data('target')),
      edges = this.getBoundingClientRect(),
      apex = Math.round(edges.top),
      nadir = Math.round(edges.bottom);

      if (apex < gate && nadir > 0) aim.removeClass(haze);
      else aim.addClass(haze);
    });

    var rise = $('.bio li').not('.' + haze),
    turf = pouch.scrollTop();

    if (rise.length > 1) {
      if (turf > zone) rise.eq(0).addClass(haze);
      else rise.eq(1).addClass(haze);
    }

    zone = turf;
  });

  $('.bio li').click(function() {

    if (zone == spot[this.id]) return;

    pouch.stop().animate({scrollTop: spot[this.id]}, 1500);
  });

function collectInfo() {

  gate = $(this).height();

  items.each(function() {

    spot[$(this).data('target')] = Math.round($(this).position().top+zone);
  });
}
});
html, body {
  margin: 0;
  overflow-x: hidden;
  overflow-y: hidden;
}

.wrapper {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  height: 100vh;
  margin: 0;
  grid-gap: 0;
}

.wrapperleft {
  grid-column-start: 1;
  grid-column-end: 1;
  grid-template-rows: auto;
  width: 50vw;
  max-height: 100%;
  overflow: hidden;
  margin: 0;
}

.bio {
  margin: 20px;
}

.bio ul {
  margin-top: 20px;
  padding: 0;
}

.bio h1 {
  font-family: sans-serif;
  font-weight: 400;
  font-size: 3.2em;
  list-style: none;
  margin: 0;
  border-bottom: 2px solid #000;
  display: inline;
}

.bio ul li {
  font-family: sans-serif;
  font-weight: 400;
  font-size: 3.2em;
  list-style: none;
  padding-bottom: 10px;
  cursor: pointer;
  -webkit-transition: all 0.3s ease;
  transition: all 0.3s ease;
}

.back {
  position: absolute;
  bottom: 0;
  margin-left: 20px;
}

.back h1 {
  font-family: sans-serif;
  font-weight: 400;
  font-size: 1.5em;
}

.wrapperright {
  grid-column-start: 2;
  grid-column-end: 2;
  grid-template-rows: 200px;
  border-left: 2px solid #000;
  width: 50vw;
  overflow-x: hidden;
  overflow-y: auto;
}

.wrapperright img {
  width: 50vw;
  max-height: 100%;
  display: block;
}

.opacity {
  opacity: 0.4;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="wrapper">
  <div class="wrapperleft">
    <div class="bio">
      <ul>
       <li id="generation" class="opacity">01 Generation Anxiety</li>
       <li id="lekhena" class="opacity">02 Lekhenaporter.com</li>
       <li id="bodys" class="opacity">03 Body(s) Under Negotiation</li>
       <li id="glitter" class="opacity">04 Glitter Boy Cosmetics</li>
       <li id="juice" class="opacity">05 Juice WRLD Cover Art</li>
      </ul>
    </div>
    <div class="back">
      <h1>← Back</h1>
    </div>
  </div>
  <div class="wrapperright">
    <img src="http://media-s3-us-east-1.ceros.com/vevo/images/2017/11/07/8d018e81643b41c3561b5ab4f5bf504b/iamddb-contact-sheet1.jpg" alt="image1">
    <div data-target="generation">
      <img src="https://dazedimg-dazedgroup.netdna-ssl.com/786/azure/dazed-prod/1180/0/1180791.jpg" alt="image2">
    </div>
    <div data-target="lekhena">
      <img src="http://kendrickbrinson.com/wp-content/uploads/2014/03/YoungThug_Portraits-029.jpg" alt="image3">
    </div>
    <div data-target="bodys">
      <img src="https://www.thunderstudios.com/wp-content/uploads/2016/03/Calvin-15.jpg" alt="image4">
    </div>
    <div data-target="glitter">
      <img src="https://4c79id2ej5i11apui01ll2wc-wpengine.netdna-ssl.com/wp-content/uploads/2018/01/IAMDDB-Gallery-3.jpg" alt="image5">
    </div>
    <div data-target="juice">
      <img src="https://www.thunderstudios.com/wp-content/uploads/2016/03/Calvin-15.jpg" alt="image6">
    </div>
  </div>
</div>

列表项的id与匹配data属性的关系相同,我也用过存储点击前图片的滚动位置,以修复锚点滚动部分。

在一些反馈之后,添加了额外的代码以确保一次仅突出显示一个列表项,具体取决于哪个图像“出现”(通过检查滚动方向)。

我也对 HTML 进行了一些更改,因为 div 不是 ul 的有效子代,而且包装元素在此处似乎是不必要的。最后,一个小的 CSS 修复来纠正右侧元素的溢出和一些修复水平溢出问题的创可贴(vw 与桌面浏览器的兼容性不是很普遍)。样式有点超出问题的范围,否则我只做了很小的改动。

【讨论】:

  • 我总是使用一个小小的 throlling and debounce 插件来处理可能会触发很多事件的事件。这将执行限制在设置的任何时间,in this case 仅每 100 毫秒。那是节流部分,最后的true 意味着它也会在之后触发和事件(去抖动)。您可能有兴趣将其与该优化一起使用。
  • 嘿,谢谢!这几乎可以完美地工作,除了它相反我希望列表项的不透明度为 0.4,直到您查看相应的 div。另一件事是,当您在两个 div 之间时,它会同时将不透明度类添加到两个列表项中
  • 好的,我想我已经解决了所有问题。在我编辑答案之前,您可以查看here(也许您还有其他反馈)。一开始我在理解这个问题时遇到了一些麻烦。我认为唯一模棱两可的是向上滚动到顶部图像时。
【解决方案2】:

也许这...

 var topofDiv = $("#generationanxiety").offset().top; //gets offset div
 var height = $("#generationanxiety").outerHeight(); //gets height of div

 $(window).scroll(function(){
     if($(window).scrollTop() > (topofDiv + height)){
       console.log('This is where the div bottom leaves the window.')
       $('#generationanxiety').removeClass('opacity');
       }
      else{
       $('#generationanxiety').addClass('opacity');
      }
});

为了平滑添加这个额外的 CSS 代码:

#WrapperDiv{
     -webkit-transition: all 0.5s ease;
     -moz-transition: all 0.5s ease;
     -o-transition: all 0.5s ease;
     transition: all 0.5s ease;
 }

到父 div

【讨论】:

  • 这似乎不起作用,它没有删除类,因为 div 离开了视口
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-17
相关资源
最近更新 更多