Cuộn mượt mà đến div cụ thể khi nhấp chuột


94

Những gì tôi đang cố gắng làm là làm cho nó sao cho nếu bạn nhấp vào một nút, nó sẽ cuộn xuống (trơn tru) đến một div cụ thể trên trang.

Những gì tôi cần là nếu bạn nhấp vào nút, nó sẽ cuộn mượt mà đến div 'thứ hai'.

.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>


Bạn có thể thử plugin này Mặc dù, plugin này thân thiện hơn với người dùng. Bạn chỉ cần liên kết tệp JS trong tiêu đề và thay đổi đánh dấu của bạn một cách thích hợp để nó hoạt động.
joshrathke

1
điều này sẽ giúp bạn :: stackoverflow.com/questions/3432656/…
Sudhir Bastakoti

Câu trả lời:


178

làm:

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

Cập nhật Jsfiddle


Bạn đang sử dụng javaScript ở đây hay jQuery?

1
@FahadUddin jQuery của nó.
Sudhir Bastakoti,

@SudhirBastakoti: Tại sao JsFiddle không bao gồm thư viện jquery cho nó trên trang đó?

@Sudhir Bastakoti nhưng nhiều người dùng phàn nàn rằng nó cuộn không mượt.
Maulik

40

Có rất nhiều ví dụ về việc cuộn trơn tru bằng các thư viện JS như jQuery, Mootools, Prototype, v.v.

Ví dụ sau đây là trên JavaScript thuần túy. Nếu bạn không có jQuery / Mootools / Prototype trên trang hoặc bạn không muốn trang quá tải với các thư viện JS nặng, ví dụ này sẽ hữu ích.

http://jsfiddle.net/rjSfP/

Phần HTML:

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

Phần CSS:

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

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

Phần 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);
}

Tôi đang sử dụng cái này và nó hoạt động rất tốt. Làm cách nào để làm cho cuộn chậm hơn?
jamescampbell

Bất kỳ ý tưởng nào về cách thêm bù đắp cho thanh điều hướng cố định trong mã này? Dưới đây là ví dụ tôi làm fiddle
Plavookac

3
Vẫn hữu ích sau 5 năm
Owaiz Yusufi

9

Tôi đã xem xét câu trả lời của nico một chút và nó cảm thấy rất kinh ngạc. Đã điều tra một chút và tìm thấy window.requestAnimationFrameđó là một hàm được gọi trong mỗi chu kỳ sơn lại. Điều này cho phép tạo ra một hình ảnh động trông sạch sẽ hơn. Vẫn đang cố gắng trau dồi các giá trị mặc định tốt cho kích thước bước nhưng đối với ví dụ của tôi, mọi thứ trông khá ổn khi sử dụng triển khai này.

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 Xem ở trên. Đây chỉ đơn giản là một phiên bản tối ưu hóa của mã nico trong câu trả lời trước.
Ned Rockson

@NedRockson Không hoạt động cho tôi đưa ra thông báo trên bảng điều khiển "Uncaught TypeError: Không thể đọc thuộc tính 'parentNode' của null" nhưng mã của nico đang hoạt động, Tôi nên làm gì để có thể áp dụng hoạt ảnh rõ ràng?
Kartik Watwani

@KartikWatwani Điều đó có nghĩa là trên dòng đọc scrollContainer = scrollContainer.parentNode, scrollContainer là null. Điều này có thể có nghĩa là bạn không chuyển đúng elementIdkhi gọi hàm này. Cũng có thể bạn đang chạy tập lệnh này trên một trang mà elementId đó không tồn tại.
Ned Rockson

@NedRockson Nếu elementIdcó thể là sai, tôi sẽ nhận được lỗi tương tự trong trường hợp ví dụ của @nico nhưng trong trường hợp đó, việc cuộn hoạt động nhưng không trơn tru.
Kartik Watwani

Sử dụng requestAnimationFramethay vì setTimeoutlà cách để đi. setTimeoutkhông nên sử dụng cho hình ảnh động.
tsnkff


2

Tôi đã lấy phiên bản của Ned Rockson và điều chỉnh nó để cho phép cuộn lên.

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

2

Bạn có thể sử dụng css cơ bản để cuộn mượt mà

html {
  scroll-behavior: smooth;
}

0

Ned Rockson về cơ bản trả lời câu hỏi này. Tuy nhiên, có một lỗ hổng chết người trong giải pháp của anh ấy. Khi phần tử được nhắm mục tiêu gần cuối trang hơn chiều cao khung nhìn, hàm không đạt được câu lệnh thoát và giữ người dùng ở cuối trang. Điều này được giải quyết đơn giản bằng cách giới hạn số lần lặp lại.

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);
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.