簡體   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