如何为一个scrollspy位置指定不同的scrollTop值?

时间:2018-11-19 17:42:58

标签: javascript jquery html web

我有指示菜单中当前位置并在其上设置活动类的脚本。但是我需要ID contact_form的特定规则。我需要在该ID位置的scrollTop值中添加1000px。

这是我的代码:

var lastId,
    topMenu = $(".nav"),
    topMenuHeight = topMenu.outerHeight()+15,
    menuItems = topMenu.find("a"),
    scrollItems = menuItems.map(function(){
      var item = $($(this).attr("href"));
      if (item.length) { return item; }
    });
menuItems.click(function(e){
  var href = $(this).attr("href"),
      offsetTop = href === "#" ? 0 : $(href).offset().top-topMenuHeight-80+1;
  $('html, body').stop().animate({
      scrollTop: offsetTop
  }, 300);
  e.preventDefault();
});
$(window).scroll(function(){
   var fromTop = $(this).scrollTop()+topMenuHeight+80;
   var cur = scrollItems.map(function(){
     if ($(this).offset().top < fromTop)
       return this;
   });
   cur = cur[cur.length-1];
   var id = cur && cur.length ? cur[0].id : "";

   if (lastId !== id) {
       lastId = id;
       menuItems
         .parent().removeClass("active")
         .end().filter("[href='#"+id+"']").parent().addClass("active");
   }
});

1 个答案:

答案 0 :(得分:0)

我将使用jQuery的data方法将所需的额外像素嵌入到HTML元素中。您可以在in this fiddle或下面的代码段中看到这个想法。

您可以使用此想法来控制将任何元素视为“活动”的点,而不仅仅是联系表单。

var lastId,
    topMenu = $(".nav"),
    topMenuHeight = topMenu.outerHeight()+15,
    menuItems = topMenu.find("a"),
    scrollItems = menuItems.map(function(){
      var id = $(this).attr("href");
      var item = $(id);
      if (item.length) {
        if (id === "#contact_form") { // Here we embed the desired extra fromTop value
          item.data("extraTop", 1000);
        }
        return item;
      }
    });
menuItems.click(function(e){
  var href = $(this).attr("href"),
      offsetTop = href === "#" ? 0 : $(href).offset().top-topMenuHeight-80+1;
  $('html, body').stop().animate({
      scrollTop: offsetTop
  }, 300);
  e.preventDefault();
});
$(window).scroll(function(){
   var $window = $(this);
   var fromTop = $window.scrollTop()+topMenuHeight+80;
   var cur = scrollItems.map(function(){
     var $el = $(this);
     var top = $el.offset().top;
     var extra = $el.data("extraTop"); // Here we read the "extraTop" data attribute
     if (!extra) // If this doesn't exist, we force it to be numeric 0
       extra = 0;
     if (top < fromTop + extra) // Now we compare to the old fromTop plus our extra top value
       return this;
   });
   cur = cur[cur.length-1];
   var id = cur && cur.length ? cur[0].id : "";

   if (lastId !== id) {
       lastId = id;
       menuItems
         .parent().removeClass("active")
         .end().filter("[href='#"+id+"']").parent().addClass("active");
   }
});
.active {
  background: black;
  color: white;
}

div {
  height: 1300px;
}

.nav {
  position: fixed;
  top: 0;
  height: auto;
}

.red {
  background: #ff2a2a;
}

.green {
  background: #33a033;
}

.blue {
  background: #0080ff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="nav">
  <li><a href="#stuff1">Stuff</a></li>
  <li><a href="#stuff2">Stuff</a></li>
  <li><a href="#stuff3">Stuff</a></li>
  <li><a href="#contact_form">Contact Form</a></li>
  <li><a href="#stuff4">Stuff</a></li>
  <li><a href="#stuff5">Stuff</a></li>
  <li><a href="#other">Other</a></li>
</ul>
<div id="stuff1" class="red">
Stuff
</div>
<div id="stuff2" class="red">
Stuff
</div>
<div id="stuff3" class="red">
Stuff
</div>
<div id="contact_form" class="green">
The contact: <input type="text" value="what?"/>
</div>
<div id="stuff4" class="red">
Stuff
</div>
<div id="stuff5" class="red">
Stuff
</div>
<div id="other" class="blue">
Other
</div>