Come scorrere fino a un elemento usando JavaScript?


153

Sto cercando di spostare la pagina su un <div>elemento.

Ho provato il codice successivo senza risultati:

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

1
visibilitye displaysono usati per rendere visibili gli elementi (in). Vuoi scorrere il div sullo schermo?
Lekensteyn,

Che tipo di attenzione? Lo stesso focus che hai quando fai una tabulazione tra gli elementi del modulo o lo stato attivo nel senso di evidenziare l'elemento in qualche modo? L'unica cosa da fare è visualizzare l'elemento, che non ha effetto se è già visualizzato.
Felix Kling,

Focus come scorrere in vista?
Epascarello,

Risposte:


124

Puoi usare un'ancora per "focalizzare" il div. Vale a dire:

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

e quindi utilizzare il seguente javascript:

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

9
Chrome (WebKit) presenta un bug che impedisce alla pagina di scorrere una volta impostato l'ancoraggio. Usa: location.href="#";location.href="#myDiv". L'uso id="myDiv"è preferito name="myDiv"e funziona anche.
Lekensteyn,

8
Ho avuto questo problema esatto, ma la "correzione" di WebKit mi causa un problema in FF 3.6.13. Funziona senza la linea "#", ma se lo aggiungi, va su "#" e non tenta mai di andare su "#miodiv". Continuerò con la soluzione senza il "#", che funziona per me ... woohoo!
TimFoolery,

1
Questo non funziona bene per me perché aggiunge tutti questi eventi di navigazione alla cronologia del browser e non riesco facilmente a tornare alla pagina precedente
bikeman868

Penso che 'AnhSirk Dasarp' di seguito sia un metodo migliore per scorrere l'elemento desiderato nella parte superiore dello schermo visibile.
Curious101

Cosa succede se lo scroller si trova in un div interno?
Qian Chen

240

scrollIntoView funziona bene:

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

riferimento completo nei documenti MDN:
https://developer.mozilla.org/en-US/docs/Web/API/Element.scrollIntoView


11
@CameronMcCluskie è solo lo strano "scrollIntoViewOptions" (scorrimento regolare, ecc.) Che ha il supporto esclusivo per Firefox. l'uso di base che ho nella mia risposta dovrebbe funzionare su quasi tutto.
schpet,

4
Confermo, a partire dal 16 aprile, funziona anche con Opera e Chrome.
lvr123,

2
Quando si utilizza questa soluzione e si dispone di una barra di navigazione fissa nella parte superiore, è necessario considerare anche quello. Una soluzione diversa potrebbe essere più adatta come windows.scrollTo (posX, posY) con posY calcolata correttamente.
Manfred,

2
Ha funzionato in Firefox, Opera e Safari.
Jagdeep Singh,

3
Ecco un'altra fonte (caniuse) per la compatibilità del browser discrollIntoView
Il pisello rosso

100

la tua domanda e le risposte sembrano diverse. Non so se sbaglio, ma per chi cerca su Google e raggiunge la mia risposta sarebbe la seguente:

  1. La mia risposta su StackOverflow
  2. Una domanda simile

La mia risposta ha spiegato:

ecco un semplice javascript per quello

chiamalo quando devi scorrere lo schermo fino a un elemento che ha id = "yourSpecificElementId"

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

vale a dire. per la domanda precedente, se l'intenzione è di scorrere lo schermo fino al div con ID 'divFirst'

il codice sarebbe: window.scroll(0,findPos(document.getElementById("divFirst")));

e hai bisogno di questa funzione per il funzionamento:

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

lo schermo verrà fatto scorrere fino al tuo elemento specifico.


12
Questa soluzione ha il vantaggio di non scherzare con l'URL visibile nella barra di navigazione del browser aggiungendo ancore MyID.
Renaud Bompuis,

2
Grazie, penso che questa dovrebbe essere la risposta accettata, è java-script, non HTML come la risposta attuale che non funzionerebbe per me, ma questo ha funzionato!
Steve Byrne,

Cioè, se si windowdesidera scorrere, non un'area di visualizzazione traboccante
WebWanderer,

1
Funziona dopo essere cambiato [curtop]alla curtopfine
goldylucks il

Se non vuoi che spinga questo elemento in cima alla pagina ma preferisci farlo scorrere in modo che l'elemento sia al centro dello schermo, sottrai (window.screen.height/2)da findPos
Albert Renshaw

47

Per Chrome e Firefox

Ho esaminato un po 'questo e ho capito questo che in qualche modo sembra il modo più naturale per farlo. Naturalmente, questa è la mia pergamena preferita personale ora. :)

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

Per i sostenitori di IE, Edge e Safari

Nota che window.scroll({ ...options })non è supportato su IE, Edge e Safari. In tal caso è probabilmente meglio usarlo element.scrollIntoView(). (Supportato su IE 6). Molto probabilmente (leggi: non testato) passare opzioni senza effetti collaterali.

Questi possono ovviamente essere racchiusi in una funzione che si comporta in base al browser utilizzato.


3
Funziona come un incantesimo :)
Midzer,

1
Questa è l'unica soluzione che ha funzionato per me con Chrome.
domenica

1
Volevo prendere la tua soluzione, poiché è possibile ottimizzare la posizione (nel mio caso y-80). Sembra, come var element = document.getElementById ("Div"); manca nel tuo esempio? Inoltre non funziona con IE11. IE11 non conosce window.scrollY - dobbiamo invece usare window.pageYOffset per ricevere un valore. Dopo averlo modificato, ho avuto vari (non da comprendere) errori jquery (ovviamente - come per lo più - solo in IE11. Pertanto, ho implementato document.getElementById ("divFirst"). ScrollIntoView (); e quindi $ (finestra ) .scrollTop ($ (window) .scrollTop () - 80); cosa funziona con tutti i browser.
FredyWenger,

Non supportato su Safari (passando awindow.scroll
goldylucks il

Grazie per i commenti, aggiorno la risposta per includere la compatibilità del browser.
Caveman,

8

Prova questo:

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

per esempio @:

http://jsfiddle.net/Vgrey/


Voglio solo sottolineare che la proprietà DOM è element.tabIndexma non element.tabindex; il secondo funziona su Firefox ma non su Chrome (almeno quando l'ho provato qualche tempo fa). Naturalmente, usato sia come attributo HTML sia tabIndexcome tabindexwork (e su XHTML, tabindexdeve essere usato)
Oriol

6

Per scorrere fino a un determinato elemento, ho appena reso questa soluzione javascript solo di seguito.

Semplice utilizzo:

EPPZScrollTo.scrollVerticalToElementById('signup_form', 20);

Oggetto motore (puoi giocherellare con i valori filtro, 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, è più simile a un codice simile a iOS, in cui la quantità effettiva non ha importanza, quindi puoi andare avanti e nominare tutto dopo quello che fa / contiene. Preferisco questo a corto.
Geri Borbás,

5

Ecco una funzione che può includere un offset opzionale per quelle intestazioni fisse. Non sono necessarie librerie esterne.

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

Puoi prendere l'altezza di un elemento usando JQuery e scorrere fino ad esso.

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

Aggiornamento marzo 2018

Scorri fino a questa risposta senza usare JQuery

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

5

È possibile impostare lo stato attivo sull'elemento. Funziona meglio discrollIntoView

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

node.focus()

node.removeAttribute('tabindex')


Oh amico, mi hai salvato la giornata. Ho testato molte cose, ma questa è stata l'unica cosa che ha funzionato per me ed è supportata da tutti i browser. Tra l'altro ho creato un input e dato 1px di altezza e larghezza e mi sono concentrato su input.it funziona alla grande. Grazie
Martian.titan il

5

La risposta migliore e più breve a ciò che funziona anche con effetti di animazione:

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

Se hai una barra di navigazione fissa, basta sottrarre la sua altezza dal valore più alto, quindi se l'altezza della barra fissa è 70px, la linea 2 apparirà come:

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

Spiegazione: La linea 1 ottiene la posizione dell'elemento La linea 2 scorre fino alla posizione dell'elemento; behaviorla proprietà aggiunge un effetto animato uniforme


Davvero fantastico, ma non funziona ancora su Safari e altri browser. Funziona con questo polyfill github.com/iamdustan/smoothscroll . ;)
Íhor Mé,

2

Il focus può essere impostato solo su elementi interattivi ... Div rappresenta solo una sezione logica della pagina.

Forse puoi impostare i bordi attorno al div o cambiarne il colore per simulare un focus. E sì, la visibilità non è messa a fuoco.


1

Penso che se aggiungi un tabindex al tuo div, sarà in grado di ottenere il focus:

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

Non credo che sia valido, tabindex può essere applicato solo a, area, pulsante, input, oggetto, selezione e area di testo. Ma provalo.


1
In HTML5 tabindexè un "attributo principale", che sono "attributi globali" (attributi comuni a tutti gli elementi nel linguaggio HTML). Vedi w3.org/TR/2011/WD-html-markup-20110113/global-attributes.html
Oriol

1

Simile alla soluzione di @ caveman

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

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


0

Dopo aver guardato molto in giro, questo è quello che alla fine ha funzionato per me:

  1. Trova / trova div nella tua dom che ha la barra di scorrimento. Per me, sembrava così: "div class =" table_body table_body_div "scroll_top =" 0 "scroll_left =" 0 "style =" larghezza: 1263px; altezza: 499px; "

  2. L'ho trovato con questo xpath: // div [@ class = 'table_body table_body_div']

  3. Ha usato JavaScript per eseguire lo scorrimento in questo modo: (JavascriptExecutor) driver) .executeScript ("argomenti [0] .scrollLeft = argomenti [1];", elemento, 2000);

2000 è il numero di pixel che volevo scorrere verso destra. Usa scrollTop invece di scrollLeft se vuoi scorrere il div in giù.

Nota: ho provato a usare scrollIntoView ma non ha funzionato correttamente perché la mia pagina web aveva più div. Funzionerà se hai solo una finestra principale in cui si trova lo stato attivo. Questa è la migliore soluzione che ho trovato se non volevi usare jQuery che non volevo.


0

Un metodo che uso spesso per scorrere un contenitore fino al suo contenuto.

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

se desideri superare a livello globale, puoi anche fare:

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

A causa del comportamento "liscio" non funziona in Safari, Safari iOS, Explorer. Di solito scrivo una semplice funzione utilizzando 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

Nel caso in cui desideri utilizzare html, puoi semplicemente usare questo:

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

e renderlo un collegamento html all'ID elemento specifico. È sostanzialmente una getElementByIdversione html.


-3

prova questa funzione

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

Passa il div id come parametro funzionerà Lo sto già usando


da quale biblioteca viene $j?
EoghanM,

Presumo i riferimenti a $ j jQuery - la domanda afferma che ha bisogno di Javascript.
Cameron W.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.