Bagaimana cara saya menggulir ke suatu elemen menggunakan JavaScript?

152

Saya mencoba untuk memindahkan halaman ke suatu <div>elemen.

Saya telah mencoba kode berikutnya tetapi tidak berhasil:

document.getElementById("divFirst").style.visibility = 'visible';
document.getElementById("divFirst").style.display = 'block';
C ..
sumber
1
visibilitydan displaydigunakan untuk membuat elemen (dalam) terlihat. Apakah Anda ingin menggulir div di layar?
Lekensteyn
Fokus seperti apa? Fokus yang sama dengan yang Anda miliki ketika menabrak elemen formulir atau fokus dalam arti menyorot elemen entah bagaimana? Satu-satunya hal yang Anda lakukan adalah melakukan menampilkan elemen, yang tidak berpengaruh jika sudah ditampilkan.
Felix Kling
Fokus saat menggulir ke tampilan?
epascarello
12
el.scrollIntoView(true)
Blazemonger

Jawaban:

123

Anda dapat menggunakan jangkar untuk "memfokuskan" div. Yaitu:

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

dan kemudian gunakan javascript berikut:

// the next line is required to work around a bug in WebKit (Chrome / Safari)
location.href = "#";
location.href = "#myDiv";
Nikoloff
sumber
9
Chrome (WebKit) memiliki bug yang menyebabkan halaman tidak menggulir begitu anchor diatur. Gunakan: location.href="#";location.href="#myDiv". Menggunakan id="myDiv"lebih disukai name="myDiv"dan berfungsi juga.
Lekensteyn
8
Saya punya masalah persis ini, tetapi "perbaikan" WebKit menyebabkan masalah bagi saya di FF 3.6.13. Ia bekerja tanpa baris "#", tetapi jika Anda menambahkannya, ia pergi ke "#" dan tidak pernah mencoba pergi ke "#myDiv". Saya akan tetap dengan solusi tanpa "#", yang berfungsi untuk saya ... woohoo!
TimFoolery
1
Ini tidak berfungsi dengan baik bagi saya karena menambahkan semua acara navigasi ini ke riwayat browser dan saya tidak dapat dengan mudah kembali ke halaman sebelumnya
bikeman868
Saya pikir 'AnhSirk Dasarp' di bawah ini adalah metode yang lebih baik untuk menggulir elemen yang diinginkan ke bagian atas layar yang terlihat.
Curious101
Bagaimana jika scroller berada di div bagian dalam?
Qian Chen
241

scrollIntoView berfungsi dengan baik:

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

referensi lengkap dalam dokumen MDN:
https://developer.mozilla.org/en-US/docs/Web/API/Element.scrollIntoView

schpet
sumber
11
@CameronMcCluskie hanya "scrollIntoViewOptions" yang aneh (scrolling mulus, dll) yang memiliki dukungan firefox eksklusif. penggunaan dasar yang saya miliki dalam jawaban saya harus bekerja pada hampir semua hal.
schpet
4
Saya mengkonfirmasi, pada 16 April, ia berfungsi di bawah Opera dan Chrome juga.
lvr123
2
Saat menggunakan solusi ini dan Anda memiliki navbar tetap di bagian atas, Anda perlu mempertimbangkan itu juga. Solusi yang berbeda mungkin lebih cocok seperti windows.scrollTo (posX, posY) dengan posY yang dihitung dengan benar.
Manfred
2
Bekerja di Firefox, Opera, dan Safari.
Jagdeep Singh
3
Berikut sumber lain (caniuse) untuk kompatibilitas browserscrollIntoView
The Red Pea
99

pertanyaan Anda dan jawabannya tampak berbeda. Saya tidak tahu apakah saya salah, tetapi bagi mereka yang googles dan sampai di sini jawaban saya adalah sebagai berikut:

  1. Jawaban saya di stackoverflow
  2. Pertanyaan serupa

Jawaban saya menjelaskan:

di sini adalah javascript sederhana untuk itu

panggil ini saat Anda perlu menggulir layar ke elemen yang memiliki id = "yourSpecificElementId"

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

yaitu. untuk pertanyaan di atas, jika tujuannya adalah menggulir layar ke div dengan id 'divFirst'

kodenya adalah: window.scroll(0,findPos(document.getElementById("divFirst")));

dan Anda memerlukan fungsi ini untuk bekerja:

//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];
    }
}

layar akan digulir ke elemen spesifik Anda.

AnhSirk Dasarp
sumber
12
Solusi ini memiliki keuntungan tidak mengacaukan URL yang terlihat di bilah navigasi browser dengan menambahkan jangkar MyID.
Renaud Bompuis
2
Terima kasih, saya merasa ini seharusnya jawaban yang diterima karena itu adalah java-script, bukan HTML seperti jawaban saat ini yang tidak akan berfungsi untuk saya, tetapi ini berhasil!
Steve Byrne
Artinya, jika windowAnda ingin menggulir, bukan area tampilan yang meluap
WebWanderer
1
Bekerja setelah berganti [curtop]ke curtoppada akhirnya
goldylucks
Jika Anda tidak ingin mendorong elemen ini ke bagian paling atas halaman tetapi lebih suka untuk menggulir sehingga elemen berada di tengah layar, kurangi (window.screen.height/2)dari findPos
Albert Renshaw
47

Untuk Chrome dan Firefox

Saya telah melihat sedikit ke dalam ini dan saya menemukan ini yang entah bagaimana terasa seperti cara paling alami untuk melakukannya. Tentu saja, ini adalah gulir favorit pribadi saya sekarang. :)

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

Untuk pendukung IE, Edge dan Safari

Catatan yang window.scroll({ ...options })tidak didukung di IE, Edge dan Safari. Dalam hal ini kemungkinan besar yang terbaik untuk digunakan element.scrollIntoView(). (Didukung pada IE 6). Anda kemungkinan besar (baca: belum diuji) opsi lewat tanpa efek samping.

Ini tentu saja dapat dibungkus dengan fungsi yang berperilaku sesuai dengan browser yang sedang digunakan.

Manusia gua
sumber
3
Bekerja seperti pesona :)
midzer
1
Ini adalah satu-satunya solusi yang bekerja untuk saya dengan Chrome.
wkille
1
Saya ingin mengambil solusi Anda, karena dimungkinkan untuk menyesuaikan posisi (dalam kasus saya y-80). Tampaknya, sebagai var element = document.getElementById ("Div"); hilang dalam contoh Anda? Lebih lanjut itu tidak bekerja dengan IE11. IE11 tidak tahu window.scrollY - kita harus menggunakan window.pageYOffset sebagai gantinya untuk menerima nilai. Setelah saya mengubah itu, saya memiliki berbagai kesalahan jquery (tidak memahami) (tentu saja - karena kebanyakan - hanya di IE11. Karena itu, saya telah mengimplementasikan document.getElementById ("divFirst"). ScrollIntoView (); lalu $ (window) ) .scrollTop ($ (window) .scrollTop () - 80); yang berfungsi dengan semua Peramban.
FredyWenger
Tidak didukung di Safari (meneruskan opsi kewindow.scroll
goldylucks
Terima kasih atas komentarnya, saya memperbarui jawaban untuk menyertakan kompatibilitas browser.
Manusia
8

Coba ini:

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

misalnya @:

http://jsfiddle.net/Vgrey/

Chandu
sumber
Saya hanya ingin menekankan bahwa properti DOM adalah element.tabIndextetapi tidak element.tabindex; yang kedua berfungsi di Firefox tetapi tidak di Chrome (setidaknya ketika saya mencobanya beberapa waktu lalu). Tentu saja, digunakan sebagai atribut HTML baik tabIndexdan tabindexberfungsi (dan pada XHTML, tabindexharus digunakan)
Oriol
6

Untuk menggulir ke elemen yang diberikan, buat saja solusi javascript ini di bawah ini.

Penggunaan sederhana:

EPPZScrollTo.scrollVerticalToElementById('signup_form', 20);

Objek mesin (Anda dapat mengutak-atik filter, nilai 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);
    }
};
Geri Borbás
sumber
@codeWithMe Yap, ini lebih mirip kode seperti iOS, di mana kuantitas sebenarnya tidak masalah, jadi Anda bisa melanjutkan dan memberi nama semuanya setelah apa yang dikandungnya / mengandung. Saya lebih suka yang singkat.
Geri Borbás
5

Berikut adalah fungsi yang dapat menyertakan offset opsional untuk header tetap itu. Tidak diperlukan perpustakaan eksternal.

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

Anda bisa mengambil ketinggian elemen menggunakan JQuery dan gulir ke sana.

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

Pembaruan Maret 2018

Gulir ke jawaban ini tanpa menggunakan JQuery

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

Anda dapat mengatur fokus ke elemen. Ini bekerja lebih baik daripadascrollIntoView

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

node.focus()

node.removeAttribute('tabindex')

ZhenyaUsenko
sumber
Oh man, kamu menyelamatkan hariku. Telah diuji banyak hal tetapi yang ini adalah satu-satunya hal yang bekerja untuk saya dan mendukung semua browser. Btw saya membuat input dan memberikan tinggi dan lebar 1px dan memang fokus pada input.it berfungsi dengan baik. Terima kasih
Martian.titan
5

Jawaban terbaik dan terpendek yang berfungsi bahkan dengan efek animasi:

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

Jika Anda memiliki bilah nav tetap, kurangi saja tingginya dari nilai teratas, jadi jika tinggi bilah tetap Anda adalah 70px, baris 2 akan terlihat seperti:

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

Penjelasan: Baris 1 mendapatkan posisi elemen Baris 2 gulir ke posisi elemen; behaviorproperti menambahkan efek animasi yang halus

DAVID AJAYI
sumber
Sangat keren, tetapi belum berfungsi di Safari dan beberapa browser lain. Apakah berfungsi dengan polyfill ini github.com/iamdustan/smoothscroll . ;)
Íhor Mé
2

Fokus dapat ditetapkan hanya pada elemen interaktif ... Div hanya mewakili bagian logis dari halaman.

Mungkin Anda dapat mengatur batas di sekitar div atau mengubah warnanya untuk mensimulasikan fokus. Dan ya Visiblity tidak fokus.

SM Kamran
sumber
1

Saya pikir jika Anda menambahkan tabindex ke div Anda, itu akan bisa mendapatkan fokus:

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

Saya tidak berpikir itu valid, tabindex hanya dapat diterapkan ke, area, tombol, input, objek, pilih, dan textarea. Tapi cobalah.

Robin
sumber
1
Dalam HTML5 tabindexadalah "atribut inti", yang merupakan "atribut global" (atribut yang umum untuk semua elemen dalam bahasa HTML). Lihat w3.org/TR/2011/WD-html-markup-20110113/global-attributes.html
Oriol
1

Mirip dengan solusi @ manusia gua

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

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

Setelah banyak melihat-lihat, inilah yang akhirnya berhasil untuk saya:

  1. Temukan / temukan div di dom Anda yang memiliki bilah gulir. Bagi saya, itu tampak seperti ini: "div class =" table_body table_body_div "scroll_top =" 0 "scroll_left =" 0 "style =" width: 1263px; tinggi: 499px; "

  2. Saya menemukannya dengan xpath ini: // div [@ class = 'table_body table_body_div']

  3. Digunakan JavaScript untuk menjalankan pengguliran seperti ini: driver (JavascriptExecutor)) .executeScript ("argumen [0] .scrollLeft = argumen [1];", elemen, 2000);

2000 adalah jumlah piksel yang ingin saya gulir ke kanan. Gunakan scrollTop bukan scrollLeft jika Anda ingin menggulir div Anda ke bawah.

Catatan: Saya mencoba menggunakan scrollIntoView tetapi tidak berfungsi dengan baik karena halaman web saya memiliki beberapa div. Ini akan berfungsi jika Anda hanya memiliki satu jendela utama di mana fokus berada. Ini adalah solusi terbaik yang saya temui jika Anda tidak ingin menggunakan jQuery yang saya tidak mau.

Anchal Agrawal
sumber
0

Metode yang sering saya gunakan untuk menggulir wadah ke isinya.

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

jika keinginan Anda untuk menimpa secara global, Anda juga dapat melakukan:

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');
    }
};
yorg
sumber
0

Karena perilaku "smooth" tidak berfungsi di Safari, Safari ios, Explorer. Saya biasanya menulis fungsi sederhana menggunakan 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)
    })
  }

})();
Brad Vanderbush
sumber
-1

Jika Anda ingin menggunakan html, Anda bisa menggunakan ini:

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

dan menjadikannya tautan html ke id elemen spesifik. Pada dasarnya getElementByIdversi html.

suryansh
sumber
-3

coba fungsi ini

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

Lulus id id sebagai parameter itu akan berfungsi saya sudah menggunakannya

virendra rastogi
sumber
dari perpustakaan mana $j?
EoghanM
Saya mengasumsikan referensi $ j jQuery - pertanyaannya menyatakan perlu Javascript.
Cameron W.