Làm cách nào để cuộn đến một phần tử bằng JavaScript?


152

Tôi đang cố gắng di chuyển trang đến một <div>yếu tố.

Tôi đã thử mã tiếp theo nhưng không có kết quả:

document.getElementById("divFirst").style.visibility = 'visible';
document.getElementById("divFirst").style.display = 'block';

1
visibilitydisplayđược sử dụng để làm cho các phần tử (trong) hiển thị. Bạn có muốn cuộn div trong màn hình?
Lekensteyn

Những loại trọng tâm? Sự tập trung giống như bạn có khi lập bảng thông qua các yếu tố hình thức hoặc tập trung theo nghĩa làm nổi bật yếu tố nào đó? Điều duy nhất bạn làm là hiển thị phần tử, không có hiệu lực nếu nó đã được hiển thị.
Felix Kling

Tập trung như cuộn vào xem?
eprebello

Câu trả lời:


123

Bạn có thể sử dụng một neo để "tập trung" div. I E:

<div id="myDiv"></div>

và sau đó sử dụng javascript sau:

// the next line is required to work around a bug in WebKit (Chrome / Safari)
location.href = "#";
location.href = "#myDiv";

9
Chrome (WebKit) có một lỗi khiến trang không thể cuộn khi neo được đặt. Sử dụng : location.href="#";location.href="#myDiv". Sử dụng id="myDiv"được ưa thích hơn name="myDiv"và hoạt động quá.
Lekensteyn

8
Tôi đã có vấn đề chính xác này, nhưng "sửa lỗi" WebKit gây ra sự cố cho tôi trong FF 3.6.13. Nó hoạt động mà không có dòng "#", nhưng nếu bạn thêm nó, nó sẽ chuyển sang "#" và không bao giờ thử chuyển sang "#myDiv". Tôi sẽ gắn bó với giải pháp mà không có "#", thứ đang hoạt động với tôi ... woohoo!
TimFoolery

1
Điều này không hoạt động tốt với tôi vì nó thêm tất cả các sự kiện điều hướng này vào lịch sử trình duyệt và tôi không thể dễ dàng quay lại trang trước
bikeman868

Tôi nghĩ rằng 'AnhSirk Dasarp' bên dưới là một phương pháp tốt hơn để cuộn phần tử mong muốn lên trên cùng của màn hình hiển thị.
Tò mò 101

Điều gì xảy ra nếu thanh cuộn nằm trong div bên trong?
Qian Chen

241

scrollIntoView hoạt động tốt:

document.getElementById("divFirst").scrollIntoView();

tham khảo đầy đủ trong các tài liệu MDN:
https://developer.mozilla.org/en-US/docs/Web/API/Euity.scrollIntoView


11
@CameronMcCluskie chỉ là "scrollIntoViewOptions" kỳ lạ (cuộn mượt mà, v.v.) có hỗ trợ firefox độc quyền. sử dụng cơ bản tôi có trong câu trả lời của tôi nên hoạt động trên hầu hết mọi thứ.
schpet

4
Tôi xác nhận, kể từ ngày 16 tháng 4, nó cũng hoạt động theo Opera và Chrome.
lvr123

2
Khi sử dụng giải pháp này và bạn có một thanh điều hướng cố định ở trên cùng, bạn cũng cần phải xem xét điều đó. Một giải pháp khác có thể phù hợp hơn như windows.scrollTo (posX, posY) với posY được tính toán chính xác.
Manfred

2
Đã làm việc trong Firefox, Opera và Safari.
Jagdeep Singh

3
Đây là một nguồn khác (caniuse) để tương thích trình duyệt củascrollIntoView
The Red Pea

99

câu hỏi của bạn và câu trả lời trông khác nhau. Tôi không biết nếu tôi nhầm, nhưng đối với những người googles và đến đây, câu trả lời của tôi sẽ là như sau:

  1. Câu trả lời của tôi về stackoverflow
  2. Một câu hỏi tương tự

Câu trả lời của tôi đã giải thích:

đây là một javascript đơn giản cho điều đó

gọi cái này khi bạn cần cuộn màn hình đến một phần tử có id = "yourSpecificEuityId"

window.scroll(0,findPos(document.getElementById("yourSpecificElementId")));

I E. đối với câu hỏi trên, nếu có ý định cuộn màn hình sang div với id 'divFirst'

mã sẽ là: window.scroll(0,findPos(document.getElementById("divFirst")));

và bạn cần chức năng này để làm việc:

//Finds y value of given object
function findPos(obj) {
    var curtop = 0;
    if (obj.offsetParent) {
        do {
            curtop += obj.offsetTop;
        } while (obj = obj.offsetParent);
    return [curtop];
    }
}

màn hình sẽ được cuộn đến phần tử cụ thể của bạn.


12
Giải pháp này có ưu điểm là không gây rối với URL hiển thị trong thanh điều hướng của trình duyệt bằng cách thêm các neo MyID.
Renaud Bompuis

2
Cảm ơn bạn, tôi cảm thấy như đây phải là câu trả lời được chấp nhận, đó là java-script, không phải HTML như câu trả lời hiện tại không phù hợp với tôi, nhưng điều này đã làm!
Steve Byrne

Đó là, nếu đó là thứ windowbạn muốn cuộn, không phải là khu vực xem tràn
WebWanderer

1
Hoạt động sau khi đổi [curtop]thành curtopcuối
goldylucks 21/07/19

Nếu bạn không muốn nó đẩy phần tử này lên đầu trang mà thay vào đó, nó thích cuộn nó để phần tử nằm ở giữa màn hình, hãy trừ (window.screen.height/2)findPos
Albert Renshaw

47

Dành cho Chrome và Firefox

Tôi đã xem xét một chút về điều này và tôi đã tìm ra điều này bằng cách nào đó cảm thấy giống như cách tự nhiên nhất để làm điều đó. Tất nhiên, đây là cuộn yêu thích cá nhân của tôi bây giờ. :)

const y = element.getBoundingClientRect().top + window.scrollY;
window.scroll({
  top: y,
  behavior: 'smooth'
});

Dành cho những người ủng hộ IE, Edge và Safari

Lưu ý rằng window.scroll({ ...options })không được hỗ trợ trên IE, Edge và Safari. Trong trường hợp đó, nó có khả năng tốt nhất để sử dụng element.scrollIntoView(). (Được hỗ trợ trên IE 6). Bạn rất có thể (đọc: chưa được kiểm tra) vượt qua trong các tùy chọn mà không có bất kỳ tác dụng phụ nào.

Chúng tất nhiên có thể được bọc trong một chức năng hoạt động theo trình duyệt nào đang được sử dụng.


3
Làm việc như say mê :)
midzer

1
Đây là giải pháp duy nhất phù hợp với tôi với Chrome.
wkille

1
Tôi muốn đưa ra giải pháp của bạn, vì có thể tinh chỉnh vị trí (trong trường hợp của tôi là y-80). Có vẻ như, var Element = document.getEuityById ("Div"); thiếu trong ví dụ của bạn? Hơn nữa, nó không hoạt động với IE11. IE11 không biết window.scrollY - thay vào đó chúng ta phải sử dụng window.pageY Offerset để nhận giá trị. Sau khi tôi đã thay đổi điều đó, tôi đã có nhiều lỗi jquery (không hiểu) (tất nhiên - như chủ yếu - chỉ trong IE11. Do đó, tôi đã triển khai document.getEuityById ("divFirst"). ScrollIntoView (); ) .scrollTop ($ (window) .scrollTop () - 80); những gì hoạt động với tất cả các Trình duyệt.
FredyWenger

Không được hỗ trợ trên Safari (chuyển tùy chọn sangwindow.scroll
goldylucks

Cảm ơn các ý kiến, tôi cập nhật câu trả lời để bao gồm khả năng tương thích trình duyệt.
Caveman

8

Thử cái này:

var divFirst = document.getElementById("divFirst");
divFirst.style.visibility = 'visible'; 
divFirst.style.display = 'block';  
divFirst.tabIndex = "-1";  
divFirst.focus();

ví dụ @:

http://jsfiddle.net/Vgrey/


Tôi chỉ muốn nhấn mạnh rằng thuộc tính DOM là element.tabIndexnhưng không element.tabindex; cái thứ hai hoạt động trên Firefox nhưng không phải trên Chrome (ít nhất là khi tôi đã thử nó cách đây một thời gian). Tất nhiên, được sử dụng như một thuộc tính HTML cả tabIndextabindexhoạt động (và trên XHTML, tabindexphải được sử dụng)
Oriol

6

Để cuộn đến một phần tử nhất định, chỉ cần thực hiện giải pháp javascript này bên dưới.

Cách sử dụng đơn giản:

EPPZScrollTo.scrollVerticalToElementById('signup_form', 20);

Đối tượng công cụ (bạn có thể sử dụng bộ lọc, giá trị fps):

/**
 *
 * Created by Borbás Geri on 12/17/13
 * Copyright (c) 2013 eppz! development, LLC.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */


var EPPZScrollTo =
{
    /**
     * Helpers.
     */
    documentVerticalScrollPosition: function()
    {
        if (self.pageYOffset) return self.pageYOffset; // Firefox, Chrome, Opera, Safari.
        if (document.documentElement && document.documentElement.scrollTop) return document.documentElement.scrollTop; // Internet Explorer 6 (standards mode).
        if (document.body.scrollTop) return document.body.scrollTop; // Internet Explorer 6, 7 and 8.
        return 0; // None of the above.
    },

    viewportHeight: function()
    { return (document.compatMode === "CSS1Compat") ? document.documentElement.clientHeight : document.body.clientHeight; },

    documentHeight: function()
    { return (document.height !== undefined) ? document.height : document.body.offsetHeight; },

    documentMaximumScrollPosition: function()
    { return this.documentHeight() - this.viewportHeight(); },

    elementVerticalClientPositionById: function(id)
    {
        var element = document.getElementById(id);
        var rectangle = element.getBoundingClientRect();
        return rectangle.top;
    },

    /**
     * Animation tick.
     */
    scrollVerticalTickToPosition: function(currentPosition, targetPosition)
    {
        var filter = 0.2;
        var fps = 60;
        var difference = parseFloat(targetPosition) - parseFloat(currentPosition);

        // Snap, then stop if arrived.
        var arrived = (Math.abs(difference) <= 0.5);
        if (arrived)
        {
            // Apply target.
            scrollTo(0.0, targetPosition);
            return;
        }

        // Filtered position.
        currentPosition = (parseFloat(currentPosition) * (1.0 - filter)) + (parseFloat(targetPosition) * filter);

        // Apply target.
        scrollTo(0.0, Math.round(currentPosition));

        // Schedule next tick.
        setTimeout("EPPZScrollTo.scrollVerticalTickToPosition("+currentPosition+", "+targetPosition+")", (1000 / fps));
    },

    /**
     * For public use.
     *
     * @param id The id of the element to scroll to.
     * @param padding Top padding to apply above element.
     */
    scrollVerticalToElementById: function(id, padding)
    {
        var element = document.getElementById(id);
        if (element == null)
        {
            console.warn('Cannot find element with id \''+id+'\'.');
            return;
        }

        var targetPosition = this.documentVerticalScrollPosition() + this.elementVerticalClientPositionById(id) - padding;
        var currentPosition = this.documentVerticalScrollPosition();

        // Clamp.
        var maximumScrollPosition = this.documentMaximumScrollPosition();
        if (targetPosition > maximumScrollPosition) targetPosition = maximumScrollPosition;

        // Start animation.
        this.scrollVerticalTickToPosition(currentPosition, targetPosition);
    }
};

@codeWithMe Yap, nó giống như một mã giống như iOS, trong đó số lượng thực tế không quan trọng, vì vậy bạn có thể tiếp tục và đặt tên cho mọi thứ theo những gì nó chứa / chứa. Tôi thích điều đó hơn sự ngắn ngủi.
Geri Borbás

5

Đây là một chức năng có thể bao gồm một phần bù tùy chọn cho các tiêu đề cố định đó. Không cần thư viện bên ngoài.

function scrollIntoView(selector, offset = 0) {
  window.scroll(0, document.querySelector(selector).offsetTop - offset);
}

Bạn có thể lấy chiều cao của một phần tử bằng JQuery và cuộn đến phần tử đó.

var headerHeight = $('.navbar-fixed-top').height();
scrollIntoView('#some-element', headerHeight)

Cập nhật tháng 3 năm 2018

Di chuyển đến câu trả lời này mà không sử dụng JQuery

scrollIntoView('#answer-44786637', document.querySelector('.top-bar').offsetHeight)

5

Bạn có thể đặt tiêu điểm thành phần tử. Nó hoạt động tốt hơnscrollIntoView

node.setAttribute('tabindex', '-1')

node.focus()

node.removeAttribute('tabindex')


Người đàn ông, bạn đã cứu ngày của tôi. Đã thử nghiệm rất nhiều thứ nhưng đây là thứ duy nhất phù hợp với tôi và nó hỗ trợ tất cả các trình duyệt. Btw Tôi đã tạo một đầu vào và cho chiều cao và chiều rộng 1px và tập trung vào input.it hoạt động rất tốt. Cảm ơn
Martian.titan

5

Câu trả lời tốt nhất, ngắn nhất mà những gì hoạt động ngay cả với hiệu ứng hoạt hình:

var scrollDiv = document.getElementById("myDiv").offsetTop;
window.scrollTo({ top: scrollDiv, behavior: 'smooth'});

Nếu bạn có một thanh điều hướng cố định, chỉ cần trừ chiều cao của nó khỏi giá trị trên cùng, vì vậy nếu chiều cao thanh cố định của bạn là 70px, dòng 2 sẽ như sau:

window.scrollTo({ top: scrollDiv-70, behavior: 'smooth'});

Giải thích: Dòng 1 lấy vị trí phần tử Cuộn 2 đến vị trí phần tử; behaviortài sản thêm một hiệu ứng hoạt hình mượt mà


Thực sự tuyệt vời, nhưng chưa hoạt động trên Safari và một số trình duyệt khác. Không hoạt động với github.com/iamdustan/smoothscroll này . ;)
Íhor Mé

2

Chỉ có thể đặt tiêu điểm cho các yếu tố tương tác ... Div chỉ đại diện cho một phần logic của trang.

Có lẽ bạn có thể đặt đường viền xung quanh div hoặc thay đổi màu của nó để mô phỏng tiêu điểm. Và vâng, Visiblity không tập trung.


1

Tôi nghĩ rằng nếu bạn thêm một tabindex vào div của mình, nó sẽ có thể lấy nét:

<div class="divFirst" tabindex="-1">
</div>

Tôi không nghĩ rằng nó hợp lệ mặc dù, tabindex chỉ có thể được áp dụng cho một, khu vực, nút, đầu vào, đối tượng, chọn và textarea. Nhưng hãy thử xem.


1
Trong HTML5 tabindexlà "thuộc tính cốt lõi", là "thuộc tính toàn cầu" (thuộc tính chung cho tất cả các thành phần trong ngôn ngữ HTML). Xem w3.org/TR/2011/WD-html-markup-20110113/global-attribut.html
Oriol

1

Tương tự như giải pháp của @ caveman

const element = document.getElementById('theelementsid');

if (element) {
    window.scroll({
        top: element.scrollTop,
        behavior: 'smooth',
    }) 
}


0

Sau khi nhìn xung quanh rất nhiều, đây là những gì cuối cùng đã làm việc cho tôi:

  1. Tìm / định vị div trong dom của bạn có thanh cuộn. Đối với tôi, nó trông như thế này: "div class =" table_body table_body_div "scroll_top =" 0 "scroll_left =" 0 "style =" width: 1263px; chiều cao: 499px; "

  2. Tôi đã định vị nó bằng xpath này: // div [@ class = 'table_body table_body_div']

  3. Đã sử dụng JavaScript để thực thi cuộn như thế này: trình điều khiển (JavascriptExecutor)) .executeScript ("argument [0] .scrollLeft = argument [1];", Element, 2000);

2000 là không có pixel nào tôi muốn cuộn sang phải. Sử dụng scrollTop thay vì scrollLeft nếu bạn muốn cuộn div xuống.

Lưu ý: Tôi đã thử sử dụng scrollIntoView nhưng nó không hoạt động chính xác vì trang web của tôi có nhiều div. Nó sẽ hoạt động nếu bạn chỉ có một cửa sổ chính nơi tập trung nằm. Đây là giải pháp tốt nhất tôi gặp phải nếu bạn không muốn sử dụng jQuery mà tôi không muốn.


0

Một phương pháp tôi thường sử dụng để cuộn một container đến nội dung của nó.

/**
@param {HTMLElement} container : element scrolled.
@param {HTMLElement} target : element where to scroll.
@param {number} [offset] : scroll back by offset
*/
var scrollAt=function(container,target,offset){
    if(container.contains(target)){
        var ofs=[0,0];
        var tmp=target;
        while (tmp!==container) {
            ofs[0]+=tmp.offsetWidth;
            ofs[1]+=tmp.offsetHeight;
            tmp=tmp.parentNode;
        }
        container.scrollTop = Math.max(0,ofs[1]-(typeof(offset)==='number'?offset:0));
    }else{
        throw('scrollAt Error: target not found in container');
    }
};

nếu bạn muốn ghi đè toàn cầu, bạn cũng có thể làm:

HTMLElement.prototype.scrollAt=function(target,offset){
    if(this.contains(target)){
        var ofs=[0,0];
        var tmp=target;
        while (tmp!==this) {
            ofs[0]+=tmp.offsetWidth;
            ofs[1]+=tmp.offsetHeight;
            tmp=tmp.parentNode;
        }
        container.scrollTop = Math.max(0,ofs[1]-(typeof(offset)==='number'?offset:0));
    }else{
        throw('scrollAt Error: target not found in container');
    }
};

0

Do hành vi "trơn tru" không hoạt động trong Safari, Safari ios, Explorer. Tôi thường viết một hàm đơn giản sử dụng requestAnimationFrame

(function(){
    var start;
    var startPos = 0;

    //Navigation scroll page to element
    function scrollTo(timestamp, targetTop){
      if(!start) start = timestamp
      var runtime = timestamp - start
      var progress = Math.min(runtime / 700, 1)

      window.scroll(0, startPos + (targetTop * progress) )

      if(progress >= 1){
        return;
      }else {
        requestAnimationFrame(function(timestamp){
            scrollTo(timestamp, targetTop)
        })
      }
   };

  navElement.addEventListener('click', function(e){

    var target = e.target  //or this 
    var targetTop = _(target).getBoundingClientRect().top
    startPos = window.scrollY

    requestAnimationFrame(function(timestamp){
        scrollTo(timestamp, targetTop)
    })
  }

})();

-1

Trong trường hợp bạn muốn sử dụng html, bạn chỉ có thể sử dụng:

a href="samplewebsite.com/subdivision.html#id

và làm cho nó một liên kết html đến id phần tử cụ thể. getElementByIdPhiên bản html cơ bản của nó .


-3

thử chức năng này

function navigate(divId) {
$j('html, body').animate({ scrollTop: $j("#"+divId).offset().top }, 1500);
}

Truyền id id làm tham số nó sẽ hoạt động Tôi đang sử dụng nó


thư viện $jđến từ đâu
EoghanM

Tôi giả sử $ j tham khảo jQuery - câu hỏi cho biết nó cần Javascript.
Cameron W.
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.