当仅使用Vanilla JavaScript单击按钮时,如何滚动到下一部分/ div(选择)?

时间:2018-02-28 06:42:08

标签: javascript

过去几个月我一直在学习Js,在我对纯粹的js感到非常自在之前,我一直不去学习任何Jquery。

我希望在不使用Jquery的情况下使用与This code here具有完全相同效果的内容。如果可能,请附上注释以供解释

// --------- Jquery ---------


$(function(){

var pagePositon = 0,
    sectionsSeclector = 'section',
    $scrollItems = $(sectionsSeclector),
    offsetTolorence = 30,
    pageMaxPosition = $scrollItems.length - 1;

//Map the sections:
$scrollItems.each(function(index,ele) { $(ele).attr("debog",index).data("pos",index); });

// Bind to scroll
$(window).bind('scroll',upPos);

//Move on click:
$('#arrow a').click(function(e){
    if ($(this).hasClass('next') && pagePositon+1 <= pageMaxPosition) {
        pagePositon++;
        $('html, body').stop().animate({ 
              scrollTop: $scrollItems.eq(pagePositon).offset().top
        }, 300);
    }
    if ($(this).hasClass('previous') && pagePositon-1 >= 0) {
        pagePositon--;
        $('html, body').stop().animate({ 
              scrollTop: $scrollItems.eq(pagePositon).offset().top
          }, 300);
        return false;
    }
});

//Update position func:
function upPos(){
   var fromTop = $(this).scrollTop();
   var $cur = null;
    $scrollItems.each(function(index,ele){
        if ($(ele).offset().top < fromTop + offsetTolorence) $cur = $(ele);
    });
   if ($cur != null && pagePositon != $cur.data('pos')) {
       pagePositon = $cur.data('pos');
   }                   
}

});

2 个答案:

答案 0 :(得分:1)

更新

  

&#34;除非我使用鼠标手动滚动到不同的div然后尝试点击下一个/上一个按钮,否则这个效果很好。任何解决方案?谢谢你&#34;

每个<section>动态地赋予data-id属性,其值与其索引相对应。如果单击<section>,则它将成为当前活动的<section>,因此当单击箭头时,滚动将从那里开始。

演示的特定部分已被评论为&#34;更新&#34;

这是一种称为 scrollIntoView()

的完美方法
  x.scrollIntoView({ 
     behavior: 'smooth' 
  });

它内置了类似jQuery的选项。

在演示中评论的详细信息

演示

&#13;
&#13;
// Reference counter outside of function
var idx = 0;
// Collect all sections in a NodeList
var sxn = document.querySelectorAll('section');
// UPDATED
/* Loop through the NodeList sxn
|| Assign a data-id attribute to each section 
|| Set data-id value to current index of each
|| section
*/
for (let i = 0; i < sxn.length; i++) {
  sxn[i].setAttribute('data-id', i);
}
// Reference nav
var nav = document.querySelector('nav');
// Collect all anchors into a HTMLCollection
var lnx = document.links;
// UPDATED
// Register document on click event callback is move()
document.addEventListener('click', move, false);
// UPDATED
/* move() determines the direction of scroll by idx
|| If a section is clicked instead of the arrows,
|| then the data-id value of said section is now idx.
|| So when a section is clicked, nothing happens until an 
|| arrow is clicked. Once that happens, scrolling starts
|| from the last section clicked.
*/
function move(e) {
  if (e.target == lnx[0]) {
    idx--;
    if (idx < 0) {
      idx = sxn.length - 1;
    }
  } else if (e.target.tagName === 'SECTION') {
    idx = e.target.getAttribute('data-id');
  } else {
    idx++;
    if (idx > sxn.length - 1) {
      idx = 0;
    }
  }
  return idxScroll(idx);
}

// Pass idx thru idxScroll
function idxScroll(idx) {
  // Reference current active section
  var act = document.querySelector('.active');
  // Determine which section becomes active
  var x = sxn[idx];
  // Remove active class from current section
  act.classList.remove('active');
  // Add active class to new section
  x.classList.add('active');
  /* scrollIntoView method has a behavior option that animates
  || scrolling
  */
  x.scrollIntoView({
    behavior: 'smooth'
  });
}
&#13;
main {
  width: 100vw;
  height: auto;
}

nav {
  position: fixed;
  z-index: 1;
  width: 20%;
  right: 0;
  top: 0
}

a {
  width: 48px;
  height: 48px;
  font-size: 48px;
  text-decoration: none;
}

section {
  width: 100vw;
  height: 100vh;
}
&#13;
<main>
  <nav>
    <a href='#/'>◀</a>
    <a href='#/'>▶</a>
  </nav>
  <div>
    <section style='background:red' class='active'></section>

    <section style='background:blue'></section>

    <section style='background:yellow'></section>

    <section style='background:black'></section>

    <section style='background:green'></section>

    <section style='background:purple'></section>

    <section style='background:deeppink'></section>

    <section style='background:cyan'></section>

    <section style='background:tomato'></section>

    <section style='background:brown'></section>

    <section style='background:orchid'></section>
  </div>
</main>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

你走了:

var secs = document.querySelectorAll('section');
var currentSection = 0;
document.querySelector('#arrow').addEventListener('click', move);

function move(e) {
  if (e.target.classList.contains('next') && currentSection < secs.length) {
    window.scroll({
      top: secs[++currentSection].offsetTop,
      left: 0,
      behavior: 'smooth'
    });
    //    secs[++currentSection].scrollIntoView({ behavior: 'smooth' });
  } else if (currentSection > 0) {
    window.scroll({
      top: secs[--currentSection].offsetTop,
      left: 0,
      behavior: 'smooth'
    });

  }
}

这是jsFiddle解决方案。我使用了smoothscroll API polyfill。对于动画,如果您的浏览器不支持API(https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior)。