เลื่อนไปยัง div เฉพาะเมื่อคลิก


94

สิ่งที่ฉันพยายามทำคือทำให้ถ้าคุณคลิกที่ปุ่มมันจะเลื่อนลง (อย่างราบรื่น) ไปยัง div เฉพาะบนหน้า

สิ่งที่ฉันต้องการคือถ้าคุณคลิกที่ปุ่มมันจะเลื่อนไปที่ div 'วินาที' อย่างราบรื่น

.first {
    width: 100%;
    height: 1000px;
    background: #ccc;
}

.second {
    width: 100%;
    height: 1000px;
    background: #999;
}
<div class="first"><button type="button">Click Me!</button></div>
<div class="second">Hi</div>


คุณสามารถลองใช้ปลั๊กอินนี้ได้แม้ว่าปลั๊กอินนี้จะใช้งานง่ายกว่ามาก คุณเพียงแค่ต้องเชื่อมโยงไฟล์ JS ในส่วนหัวและเปลี่ยนมาร์กอัปของคุณให้เหมาะสมเพื่อให้ใช้งานได้
joshrathke

1
สิ่งนี้น่าจะช่วยคุณได้ :: stackoverflow.com/questions/3432656/…
Sudhir Bastakoti

คำตอบ:


178

ทำ:

$("button").click(function() {
    $('html,body').animate({
        scrollTop: $(".second").offset().top},
        'slow');
});

อัปเดตJsfiddle


คุณใช้ javaScript ที่นี่หรือ jQuery?

1
@FahadUddin มัน jQuery
Sudhir Bastakoti

@SudhirBastakoti: ทำไม JsFiddle ไม่รวมไลบรารี jquery ไว้ในหน้านั้น?

@Sudhir Bastakoti แต่ผู้ใช้หลายคนบ่นว่าการเลื่อนไม่ราบรื่น
Maulik

40

มีตัวอย่างมากมายของการเลื่อนอย่างราบรื่นโดยใช้ไลบรารี JS เช่น jQuery, Mootools, Prototype และอื่น ๆ

ตัวอย่างต่อไปนี้ใช้ JavaScript ล้วนๆ หากคุณไม่มี jQuery / Mootools / Prototype บนเพจหรือคุณไม่ต้องการโอเวอร์โหลดเพจที่มีไลบรารี JS จำนวนมากตัวอย่างจะเป็นประโยชน์

http://jsfiddle.net/rjSfP/

ส่วน HTML:

<div class="first"><button type="button" onclick="smoothScroll(document.getElementById('second'))">Click Me!</button></div>
<div class="second" id="second">Hi</div>

ส่วน CSS:

.first {
    width: 100%;
    height: 1000px;
    background: #ccc;
}

.second {
    width: 100%;
    height: 1000px;
    background: #999;
}

ส่วน JS:

window.smoothScroll = function(target) {
    var scrollContainer = target;
    do { //find scroll container
        scrollContainer = scrollContainer.parentNode;
        if (!scrollContainer) return;
        scrollContainer.scrollTop += 1;
    } while (scrollContainer.scrollTop == 0);

    var targetY = 0;
    do { //find the top of target relatively to the container
        if (target == scrollContainer) break;
        targetY += target.offsetTop;
    } while (target = target.offsetParent);

    scroll = function(c, a, b, i) {
        i++; if (i > 30) return;
        c.scrollTop = a + (b - a) / 30 * i;
        setTimeout(function(){ scroll(c, a, b, i); }, 20);
    }
    // start scrolling
    scroll(scrollContainer, scrollContainer.scrollTop, targetY, 0);
}

ฉันใช้สิ่งนี้และได้ผลดี ฉันจะทำให้การเลื่อนช้าลงได้อย่างไร
jamescampbell

มีความคิดอย่างไรในการเพิ่ม offset สำหรับ navbar คงที่ในรหัสนี้ นี่คือตัวอย่างที่ฉันทำซอ
Plavookac

3
ยังคงเป็นประโยชน์หลังจาก 5 ปี
Owaiz Yusufi

9

ฉันเล่นกับคำตอบของ nico เล็กน้อยและมันก็ดูน่ากลัว ตรวจสอบและพบว่าwindow.requestAnimationFrameเป็นฟังก์ชันที่เรียกใช้ในแต่ละรอบการทาสีใหม่ ช่วยให้ได้ภาพเคลื่อนไหวที่ดูสะอาดตายิ่งขึ้น ยังคงพยายามใช้ค่าเริ่มต้นที่ดีสำหรับขนาดขั้นตอน แต่สำหรับตัวอย่างของฉันดูดีทีเดียวเมื่อใช้การใช้งานนี้

var smoothScroll = function(elementId) {
    var MIN_PIXELS_PER_STEP = 16;
    var MAX_SCROLL_STEPS = 30;
    var target = document.getElementById(elementId);
    var scrollContainer = target;
    do {
        scrollContainer = scrollContainer.parentNode;
        if (!scrollContainer) return;
        scrollContainer.scrollTop += 1;
    } while (scrollContainer.scrollTop == 0);

    var targetY = 0;
    do {
        if (target == scrollContainer) break;
        targetY += target.offsetTop;
    } while (target = target.offsetParent);

    var pixelsPerStep = Math.max(MIN_PIXELS_PER_STEP,
                                 (targetY - scrollContainer.scrollTop) / MAX_SCROLL_STEPS);

    var stepFunc = function() {
        scrollContainer.scrollTop =
            Math.min(targetY, pixelsPerStep + scrollContainer.scrollTop);

        if (scrollContainer.scrollTop >= targetY) {
            return;
        }

        window.requestAnimationFrame(stepFunc);
    };

    window.requestAnimationFrame(stepFunc);
}

1
@Alfonso ดูด้านบน นี่เป็นเพียงโค้ดของ nico เวอร์ชันที่ปรับให้เหมาะสมแล้วในคำตอบก่อนหน้านี้
Ned Rockson

@NedRockson ไม่ได้ผลสำหรับฉันให้ข้อความคอนโซล "Uncaught TypeError: ไม่สามารถอ่านคุณสมบัติ 'parentNode' ของ null" แต่โค้ดของ nico ใช้งานได้ฉันควรทำอย่างไรจึงจะใช้แอนิเมชั่นที่สะอาดได้
Kartik Watwani

@KartikWatwani นั่นหมายความว่าในการอ่านบรรทัดscrollContainer = scrollContainer.parentNodescrollContainer เป็นโมฆะ ซึ่งอาจหมายความว่าคุณไม่ได้ส่งผ่านสิ่งที่ถูกต้องelementIdเมื่อเรียกใช้ฟังก์ชันนี้ อาจเป็นไปได้ว่าคุณกำลังเรียกใช้สคริปต์นี้บนหน้าที่ไม่มี elementId นั้น
Ned Rockson

@NedRockson ถ้าelementIdจะผิดฉันจะได้รับข้อผิดพลาดเดียวกันในกรณีของตัวอย่างของ @nico แต่ในกรณีนั้นการเลื่อนใช้งานได้ แต่ไม่ราบรื่น
Kartik Watwani

การใช้requestAnimationFrameแทนsetTimeoutคือวิธีที่จะไป setTimeoutไม่ควรใช้สำหรับภาพเคลื่อนไหว
tsnkff


2

ฉันเอาเวอร์ชันของNed Rocksonและปรับให้เลื่อนขึ้นได้เช่นกัน

var smoothScroll = function(elementId) {
  var MIN_PIXELS_PER_STEP = 16;
  var MAX_SCROLL_STEPS = 30;
  var target = document.getElementById(elementId);
  var scrollContainer = target;
  do {
    scrollContainer = scrollContainer.parentNode;
    if (!scrollContainer) return;
    scrollContainer.scrollTop += 1;
  } while (scrollContainer.scrollTop === 0);

  var targetY = 0;
  do {
    if (target === scrollContainer) break;
    targetY += target.offsetTop;
  } while (target = target.offsetParent);

  var pixelsPerStep = Math.max(MIN_PIXELS_PER_STEP,
    Math.abs(targetY - scrollContainer.scrollTop) / MAX_SCROLL_STEPS);

  var isUp = targetY < scrollContainer.scrollTop;

  var stepFunc = function() {
    if (isUp) {
      scrollContainer.scrollTop = Math.max(targetY, scrollContainer.scrollTop - pixelsPerStep);
      if (scrollContainer.scrollTop <= targetY) {
        return;
      }
    } else {
        scrollContainer.scrollTop = Math.min(targetY, scrollContainer.scrollTop + pixelsPerStep);

      if (scrollContainer.scrollTop >= targetY) {
        return;
      }
    }

    window.requestAnimationFrame(stepFunc);
  };

  window.requestAnimationFrame(stepFunc);
};


0

Ned Rockson ตอบคำถามนี้โดยทั่วไป อย่างไรก็ตามมีข้อบกพร่องร้ายแรงในการแก้ปัญหาของเขา เมื่อองค์ประกอบเป้าหมายอยู่ใกล้ด้านล่างของหน้ามากกว่าความสูงของวิวพอร์ตฟังก์ชันจะไม่ถึงคำสั่ง exit และดักจับผู้ใช้ที่ด้านล่างของหน้า แก้ไขได้ง่ายๆโดยการ จำกัด จำนวนการวนซ้ำ

var smoothScroll = function(elementId) {
    var MIN_PIXELS_PER_STEP = 16;
    var MAX_SCROLL_STEPS = 30;
    var target = document.getElementById(elementId);
    var scrollContainer = target;
    do {
        scrollContainer = scrollContainer.parentNode;
        if (!scrollContainer) return;
        scrollContainer.scrollTop += 1;
    } while (scrollContainer.scrollTop == 0);

    var targetY = 0;
    do {
        if (target == scrollContainer) break;
        targetY += target.offsetTop;
    } while (target = target.offsetParent);

    var pixelsPerStep = Math.max(MIN_PIXELS_PER_STEP,
                                 (targetY - scrollContainer.scrollTop) / MAX_SCROLL_STEPS);

    var iterations = 0;
    var stepFunc = function() {
        if(iterations > MAX_SCROLL_STEPS){
            return;
        }
        scrollContainer.scrollTop =
            Math.min(targetY, pixelsPerStep + scrollContainer.scrollTop);

        if (scrollContainer.scrollTop >= targetY) {
            return;
        }

        window.requestAnimationFrame(stepFunc);
    };

    window.requestAnimationFrame(stepFunc);
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.