繁体   English   中英

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

[英]How to scroll to the next section/div (of choice) when a button is clicked using only Vanilla JavaScript?

过去几个月我一直在学习 Js,我决定不学习任何 Jquery,直到我对纯 js 感到非常舒服为止。

我想要一些与此代码完全相同的效果,而无需使用 Jquery。 如果可能,请包括注释以供解释

// --------- 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');
   }                   
}

});

更新

“除非我使用鼠标手动滚动到不同的 div 然后尝试点击下一个/上一个按钮,否则这很好用。有什么解决方案吗?谢谢”

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

Demo 的特定部分已被评论为“已更新”


有一个完美的方法叫做scrollIntoView()

  x.scrollIntoView({ 
     behavior: 'smooth' 
  });

它内置了类似 jQuery 的选项。

Demo中评论的详细信息

演示

 // 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' }); }
 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; }
 <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>

干得好:

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 )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM