针对所有儿童,而不只是一个

时间:2018-11-14 14:48:13

标签: javascript jquery html

这是小提琴:https://jsfiddle.net/c1d3tfnL/

这是一个很大的HTML代码,但唯一重要的是节名称和顶部的侧面导航。有了这个jQuery代码:

$(window).scroll(function(){

  var cutoff = $(window).scrollTop();

  panel.each(function(){
    if($(this).offset().top + $(this).height() > cutoff){
      panel.removeClass('current');
      $(this).addClass('current');
      return false;
    }
  })

  var aChildren = $('.side ul').children();
  var aArray = [];
  for (var i=0; i < aChildren.length; i++) {
    var aChild = aChildren[i];
    var ahref = $(aChild).attr('id');
    aArray.push(ahref);
  }

  for (var i=0; i < aArray.length; i++) {
    var theID = aArray[i];

    if (panel.hasClass('current')) {
      $("a[href='#" + theID + "']").addClass('greens');

  } else {
      $("a[href='#" + theID + "']").removeClass('greens');
  }
}

我应该将greens类添加到具有current类的部分中。但是类greens出现在每个部分上。我也不知道问题出在哪里。 我添加了这个:

if (panel.hasClass('current')) {
      $("a[href='#" + theID + "']").addClass('greens');

  } else {
      $("a[href='#" + theID + "']").removeClass('greens');
  }

但是它只是忽略了代码。有什么想法吗? 我知道小提琴有点混乱,但是由于私有服务器上有很多部件,因此我无法将所有内容发送到这里。

1 个答案:

答案 0 :(得分:1)

让我知道我是否在您需要帮助的地方附近-主要目标是尝试复制您所描述的内容。但是,此代码不是循环浏览面板的子元素,而是依靠CSS为我们定位子元素。 (因此,实际上,可以在代码段的CSS部分中找到此响应的内容)。

如果您知道您的面板具有类.current;使用CSS,您可以通过编写以下内容来定位子锚标签:

.panel.current a{
   background-color: green;
}

避免尝试捕获和循环遍历子元素的每个块,从而节省了代码(和健全性)。

(很抱歉,我的代码示例使用的是Vanilla JavaScript,距离我使用jQuery已经很长时间了)

  // get all of the elements with the class .panel
const panelNodeList = document.getElementsByClassName('panel');
  // convert the NodeList of panels into a proper array
const panels = [...panelNodeList];

  // assign the classname .current to the first panel (on load)
panels[0].classList.add('current');

  // since the position of the .panel elements won't change,
  // saving the top position(s) in an array just to save a
  // a little processing time
let offsets = panels.map( panel => panel.getBoundingClientRect().top );


  // listen to the scroll event on the window element
window.addEventListener('scroll', function(e){
    // get the scrollY position of the window (and add 10px to 
    // give the elements some breathing room)
  let pos = window.scrollY + 10;
  
    // remove the .current class from all the panels
  panels.forEach( panel => panel.classList.remove('current') );
  
    // compare the scroll position of the window vs. the 
    // panel element(s) top offset
    // go through the array list in reverse to stop execution 
    // when the first match is found (instead of trying to
    // compare against the next element in the array)
  for( let i=offsets.length, x=0; i>=x; i-- ){
    if( pos > offsets[i] ){
        // if the scroll position is greater than the 
        // offset, then it's the most top element visible
        // add the class .current
      panels[i].classList.add('current');
        // break -- to stop the loop
      break;
    }
  }
  
});
.panel{
  padding: 10px;
  margin: 5px;
  border: solid 1px black;
}
.panel a{
  display: block;
}

.panel.current{
  background-color: #333333;
}
.panel.current a{
  color: green;
}
<div class="panel">
  <a href="#">lorem</a>
  <a href="#">ipsum</a>
  <a href="#">lorem</a>
  <a href="#">ipsum</a>
  <a href="#">lorem</a>
  <a href="#">ipsum</a>
</div>

<div class="panel">
  <a href="#">lorem</a>
  <a href="#">ipsum</a>
  <a href="#">lorem</a>
  <a href="#">ipsum</a>
</div>

<div class="panel">
  <a href="#">lorem</a>
  <a href="#">ipsum</a>
</div>

<div class="panel">
  <a href="#">lorem</a>
  <a href="#">ipsum</a>
  <a href="#">lorem</a>
  <a href="#">ipsum</a>
</div>

<div class="panel">
  <a href="#">lorem</a>
  <a href="#">ipsum</a>
  <a href="#">lorem</a>
  <a href="#">ipsum</a>
  <a href="#">lorem</a>
  <a href="#">ipsum</a>
</div>

<div class="panel">
  <a href="#">lorem</a>
  <a href="#">ipsum</a>
  <a href="#">lorem</a>
  <a href="#">ipsum</a>
</div>

<div class="panel">
  <a href="#">lorem</a>
  <a href="#">ipsum</a>
</div>

<div class="panel" style="height: 3000px;"></div>