如何使用jquery添加活动类只有一个li?

时间:2017-03-11 11:15:16

标签: javascript jquery

https://plnkr.co/edit/9oAmucEO0yvYDJJi8tGK?p=preview

您好 我在滚动时在页脚上添加活动类。实际上当用户滚动它时,检查div来是视口是否在页脚中添加活动类。但是在某个时候两个div在视口中选择了两个项目。但是我只需要选择一个项目。在任何事件will check div 在视口中输入in viewport or exit`。如果我得到了这个,那么我只能在页脚中选择一个项目< / p>

$(function () {
    $("#container").scroll(function () {
      console.log('scrolling');
      $('#container > div').each(function (i, left) {
        console.log(this)
        console.log($(this))
        var md = $(this).attr('data-msid');
        console.log($(this).isOnScreen())
        if($(this).isOnScreen()){
            $('.fC li[data-msidatrr='+md+']').addClass('active');
        }else {
          $('.fC li[data-msidatrr='+md+']').removeClass('active');
        }
      })
    });
    $.fn.isOnScreen = function () {

      var win = $(window);

      var viewport = {
        top: win.scrollTop(),
        left: win.scrollLeft()
      };
      viewport.right = viewport.left + win.width();
      viewport.bottom = viewport.top + win.height();

      var bounds = this.offset();
      bounds.right = bounds.left + this.outerWidth();
      bounds.bottom = bounds.top + this.outerHeight();

      return (!(viewport.right < bounds.left || viewport.left > bounds.right || viewport.bottom < bounds.top || viewport.top > bounds.bottom));


    }
  })

2 个答案:

答案 0 :(得分:1)

您可以添加此行

$('.item').removeClass('active');

if语句中的结果代码将是:

if($(this).isOnScreen()){
        $('.item').removeClass('active');
        $('.fC li[data-msidatrr='+md+']').addClass('active');
    }

说明: 首先从所有列表中删除活动类,然后仅为所需列表添加。

答案 1 :(得分:0)

我想我找到了一个解决方案。

首先,您需要将$("#container").scroll回调更改为:

  var elActive = null;
  $('.fC li').removeClass('active');
  $('#container > div').each(function (i, left) {
    var md = $(this).attr('data-msid');
    if($(this).isOnScreen()){
        elActive = $('.fC li[data-msidatrr='+md+']');
        //return false; // uncomment to get the first of the list
    }
  });
  if( elActive ) elActive.addClass('active');  

这将从所有active项中移除类li,并将遍历所有div,检查屏幕上的 并放置变量li上该元素的elActive 之后,将cass添加到elActive元素。

但是这种变化的行为仍然很奇怪,我认为你也可以将$.fn.isOnScreen函数更改为:

  var win = this.closest('[scrollable]') || $(window);

  var viewport = {
    top: win.scrollTop(),
    left: win.scrollLeft()
  };
  viewport.right = viewport.left + win.width();
  viewport.bottom = viewport.top + win.height();

  var bounds = this.offset();
  bounds.right = bounds.left + this.outerWidth();
  bounds.bottom = bounds.top + this.outerHeight();

  return (
        !(viewport.right < bounds.left 
          || viewport.left > bounds.right 
          || viewport.bottom < bounds.top 
          || viewport.top > bounds.bottom));

这将不再检查scrollTop,现在检查可滚动区域的偏移范围(我们的新&#34;视口&#34; )以及其中元素的偏移量(函数内的this引用)告诉我们该元素是否在屏幕上 将scrollable属性添加到#container元素以查看此工作。

我认为这些变化将为您提供您期望的行为。

这是你的例子的一个分支,我说的更改:
https://plnkr.co/edit/bK1h0YF2tabiWPpjQUNh?p=preview