Come scorrere la pagina HTML in un determinato ancoraggio?


264

Vorrei che il browser facesse scorrere la pagina fino a un determinato punto di ancoraggio, semplicemente usando JavaScript.

Ho specificato un attributo nameo idnel mio codice HTML:

 <a name="anchorName">..</a>

o

 <h1 id="anchorName2">..</h1>

Mi piacerebbe ottenere lo stesso effetto che avresti navigando http://server.com/path#anchorName. La pagina deve essere fatta scorrere in modo che l'ancoraggio sia vicino alla parte superiore della parte visibile della pagina.

Risposte:


349
function scrollTo(hash) {
    location.hash = "#" + hash;
}

Nessun jQuery richiesto affatto!


92
In realtà non scorre, ma salta. A quel punto potresti anche collegarti all'ancora<a href="#anchorName">link</a>
Ryan

52
Nota che funzionerà solo una volta. Una volta impostato l'hash, la pagina non scorrerà sullo stesso hash a meno che non lo si cambi in uno fittizio, quindi lo si imposti nuovamente.
Cristian Vrabie,

13
Non dovresti usare scrollTo, perché è già utilizzato dall'oggetto finestra globale. Inoltre, il parametro non deve essere chiamato hash, perché è definito anche location.hash. È possibile utilizzare questo codice:function scrollToHash(hashName) { location.hash = "#" + hashName; }
Markus Zeller

3
@MarkusZeller, perché il parametro non dovrebbe essere chiamato hash? Non si scontra con la posizione, vero?
Gherman,

3
questo scorre se si imposta "scroll-behavior: smooth;" sull'elemento html
stacker

225

Molto più semplice:

var element_to_scroll_to = document.getElementById('anchorName2');
// Or:
var element_to_scroll_to = document.querySelectorAll('.my-element-class')[0];
// Or:
var element_to_scroll_to = $('.my-element-class')[0];
// Basically `element_to_scroll_to` just have to be a reference
// to any DOM element present on the page
// Then:
element_to_scroll_to.scrollIntoView();

22
All'inizio ho pensato che Mandx stesse pescando a traina, poi ho provato a farlo e ha funzionato. Al di là di me come non ho mai incontrato questo metodo prima. Mozilla Docs per questo metodo . Inoltre, sembra che questo sarà molto ben supportato nei browser.
Jonathan Dumaine,

2
Ho avuto molti problemi con le soluzioni jquery che non scorrevano. Questo mi ha risparmiato molta frustrazione.
NuclearPeon,

1
AVVERTIMENTO! Questo metodo può avere problemi se un div sopra contiene elementi fluttuanti e non può determinarne facilmente le dimensioni.
Vogomatix,

5
Questa è una soluzione pulita, tuttavia al momento non consente alcun ritocco, ma esegue un hard scroll. C'è un parametro sperimentale scrollIntoViewOptionsche ha behavior: "smooth"un'opzione, ma attualmente è compatibile solo con Firefox.
Rocha,

Come animarlo?
SkuraZZ,

124

È possibile utilizzare jQuerys .animate () , .offset () e scrollTop. Piace

$(document.body).animate({
    'scrollTop':   $('#anchorName2').offset().top
}, 2000);

link di esempio: http://jsbin.com/unasi3/edit

Se non vuoi animare, usa .scrollTop () come

$(document.body).scrollTop($('#anchorName2').offset().top);

o javascripts nativo location.hashcome

location.hash = '#' + anchorid;

1
Per quanto riguarda la creazione di un selettore per trovare <h1 id="anchorName">o <a name="anchorName">, utilizzare $('#'+hash+',a[name='+hash+']')o leggermente ottimizzato $(document.getElementById(hash) || 'a[name='+hash+']')che cercherà prima l'elemento per id, e ricorrere alla ricerca di a solo se non ne viene trovato uno.
Gnarf,

@gnarf - Non è necessario ottimizzare i selettori '#' in jQuery: sono già ottimizzati per te. È abbastanza facile vedere se hai letto il codice sorgente di jQuery.
CodeJoust

3
@CodeJoust - Sono nel team di jQuery, l'ho letto molte volte e sì $("#selector")è ottimizzato ma $("#selector,a[name='selector']")non passerà attraverso le stesse ottimizzazioni con la stessa rapidità. Suppongo che il mio commento di 2,5 anni sia un po 'strano. L '"ottimizzazione" evita la a[name='selector']ricerca se trova l'id, non ottimizzando la ricerca dell'id.
Gnarf,

1
Ho avuto un po 'di fortuna con questo approccio: <a data-hash="about"> Informazioni </a> <script> $ ("[data-hash]"). Click (function () {var data = $ (this) .attr ("data-hash"); $ (document.body) .animate ({'scrollTop': $ ("#" + data) .offset (). top}, 500);}); </script>
Jazzy,

33

Ottima soluzione di jAndy, ma lo scorrimento regolare sembra avere problemi di funzionamento in Firefox.

Scriverlo in questo modo funziona anche su Firefox.

(function($) {
    $(document).ready(function() {
         $('html, body').animate({
           'scrollTop':   $('#anchorName2').offset().top
         }, 2000);
    });
})(jQuery);

Nell'ultima versione di Chrome questo è l'unico metodo che ho scoperto che funziona costantemente. Grazie per il consiglio!
gaborous il

32

2018-2020 Pure js:

C'è un modo molto conveniente per scorrere fino all'elemento:

el.scrollIntoView({
  behavior: 'smooth', // smooth scroll
  block: 'start' // the upper border of the element will be aligned at the top of the visible part of the window of the scrollable area.
})

Ma per quanto ho capito, non ha un buon supporto come le opzioni qui sotto.

inserisci qui la descrizione dell'immagine

Ulteriori informazioni sul metodo.


Se è necessario che l'elemento sia in alto:

const element = document.querySelector('#element')
const topPos = element.getBoundingClientRect().top + window.pageYOffset

window.scrollTo({
  top: topPos, // scroll so that the element is at the top of the view
  behavior: 'smooth' // smooth scroll
})

Esempio di dimostrazione su Codepen


Se vuoi che l'elemento sia al centro:

const element = document.querySelector('#element')
const rect = element.getBoundingClientRect() // get rects(width, height, top, etc)
const viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);

window.scroll({
  top: rect.top + rect.height / 2 - viewHeight / 2,
  behavior: 'smooth' // smooth scroll
});

Esempio di dimostrazione su Codepen


Supporto:

введите сюда описание изображения

Scrivono che scrollè lo stesso metodo di scrollTo, ma il supporto mostra meglio in scrollTo.

Maggiori informazioni sul metodo


Questa soluzione funziona molto bene! Grazie per la condivisione!
gaborous il

29

Una soluzione javascript pura senza JQuery. Testato su Chrome e Ie, non testato su IOS

function ScrollTo(name) {
  ScrollToResolver(document.getElementById(name));
}

function ScrollToResolver(elem) {
  var jump = parseInt(elem.getBoundingClientRect().top * .2);
  document.body.scrollTop += jump;
  document.documentElement.scrollTop += jump;
  if (!elem.lastjump || elem.lastjump > Math.abs(jump)) {
    elem.lastjump = Math.abs(jump);
    setTimeout(function() { ScrollToResolver(elem);}, "100");
  } else {
    elem.lastjump = null;
  }
}

demo: https://jsfiddle.net/jd7q25hg/12/


1
Ci scusiamo per commentare un vecchio argomento, ma questo funziona meglio per me poiché il mio progetto non utilizza JQuery. L'unico problema che ho notato è che perde circa 5 pixel o giù di lì se si scorre verso l'alto.
AntBirch,

Molto rinfrescante vedere una versione js pura. Insegno agli studenti a guardare sempre sotto il cofano e capire cosa fa JQuery per loro, quindi questo è un buon esempio.
Dave Everitt,

2
Questa dovrebbe essere la risposta accettata: è un puro esempio js E ottiene l'effetto di animazione a scorrimento desiderato. Ho regolato il valore di timeout su 20 e funziona perfettamente.
Mark Barrasso,

Grazie adoro le soluzioni javascript pure
R01010010

2
Funziona in IOS appena testato.
Debbie Kurth,

23

Nel 2018, non hai bisogno di jQuery per qualcosa di semplice come questo. Il scrollIntoView()metodo integrato supporta una " behavior" proprietà per scorrere agevolmente verso qualsiasi elemento della pagina. Puoi persino aggiornare l'URL del browser con un hash per renderlo tra i preferiti.

Da questo tutorial sullo scorrimento dei segnalibri HTML , ecco un modo nativo per aggiungere lo scorrimento regolare a tutti i collegamenti di ancoraggio sulla tua pagina automaticamente:

let anchorlinks = document.querySelectorAll('a[href^="#"]')
 
for (let item of anchorlinks) { // relitere 
    item.addEventListener('click', (e)=> {
        let hashval = item.getAttribute('href')
        let target = document.querySelector(hashval)
        target.scrollIntoView({
            behavior: 'smooth',
            block: 'start'
        })
        history.pushState(null, null, hashval)
        e.preventDefault()
    })
}

2
Risposta eccellente che rimuove la dipendenza da jQuery
zai chang

Wow! Funziona alla grande!
Alexandru Trandafir Catalin,

14

Scorri senza problemi fino alla posizione corretta (2019)

Ottieni le y coordinate e l'uso correttiwindow.scrollTo({top: y, behavior: 'smooth'})

const id = 'anchorName2';
const yourElement = document.getElementById(id);
const y = yourElement.getBoundingClientRect().top + window.pageYOffset;

window.scrollTo({top: y, behavior: 'smooth'});

Con offset

scrollIntoViewè anche una buona opzione ma in alcuni casi potrebbe non funzionare perfettamente. Ad esempio quando è necessario un offset aggiuntivo . Con scrollTosolo bisogno di aggiungere che compensare in questo modo:

const yOffset = -10; 

window.scrollTo({top: y + yOffset, behavior: 'smooth'});

Penso che dovresti aggiungere quanto segue al file di stile CSS: css html { scroll-behavior: smooth; }
parismiguel

5
$(document).ready ->
  $("a[href^='#']").click ->
    $(document.body).animate
      scrollTop: $($(this).attr("href")).offset().top, 1000

5

La soluzione di CSS-Tricks non funziona più in jQuery 2.2.0. Emetterà un errore di selezione:

Errore di runtime JavaScript: errore di sintassi, espressione non riconosciuta: a [href * = #]: not ([href = #])

L'ho risolto cambiando il selettore. Lo snippet completo è questo:

$(function() {
  $("a[href*='#']:not([href='#'])").click(function() {
    if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
    var target = $(this.hash);
    target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
    if (target.length) {
      $('html,body').animate({
        scrollTop: target.offset().top
      }, 1000);
      return false;
    }
  }
 });
});

4

Molte risposte sono inutilmente complicate.

Se vuoi solo saltare all'elemento target, non hai bisogno di JavaScript:

# the link:
<a href="#target">Click here to jump.</a>

# target element:
<div id="target">Any kind of element.</div>

Se vuoi scorrere animatamente verso il bersaglio , fai riferimento alla risposta di @ Shahil.


A volte, però, devi farlo in modo dinamico; cioè, senza alcuna azione diretta dell'utente. Credo sia quello che vuole l'OP.
jpaugh,

1
Sì, chiaramente l'OP era già a conoscenza della funzionalità del collegamento di ancoraggio.
Isherwood,


3

Questo è uno script funzionante che farà scorrere la pagina fino all'ancoraggio. Per impostare basta dare al collegamento di ancoraggio un ID che corrisponda all'attributo name dell'ancora che si desidera scorrere.

<script>
jQuery(document).ready(function ($){ 
 $('a').click(function (){ 
  var id = $(this).attr('id');
  console.log(id);
  if ( id == 'cet' || id == 'protein' ) {
   $('html, body').animate({ scrollTop: $('[name="' + id + '"]').offset().top}, 'slow'); 
  }
 }); 
});
</script>

2

So che questa domanda è davvero vecchia, ma ho trovato una soluzione jQuery facile e semplice in css-tricks . Questo è quello che sto usando ora.

$(function() {
  $('a[href*=#]:not([href=#])').click(function() {
    if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
      var target = $(this.hash);
      target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
      if (target.length) {
        $('html,body').animate({
          scrollTop: target.offset().top
        }, 1000);
        return false;
      }
    }
  });
});

1
Il selettore sta generando un'eccezione in jquery 2.2.0. 0x800a139e - Errore di runtime JavaScript: errore di sintassi, espressione non riconosciuta: a [href * = #]: not ([href = #])
Bill Shihara,

2

jQuery("a[href^='#']").click(function(){
    jQuery('html, body').animate({
        scrollTop: jQuery( jQuery(this).attr('href') ).offset().top
    }, 1000);
    return false;
});


2

una soluzione vue2 ... aggiungi semplici proprietà dei dati per forzare semplicemente l'aggiornamento

  const app = new Vue({ 
  ... 

  , updated: function() {
           this.$nextTick(function() {
           var uri = window.location.href
           var anchor = ( uri.indexOf('#') === -1 ) ? '' : uri.split('#')[1]
           if ( String(anchor).length > 0 && this.updater === 'page_load' ) {
              this.updater = "" // only on page-load !
              location.href = "#"+String(anchor)
           }
         })
        }
     });
     app.updater = "page_load"

 /* smooth scrolling in css - works in html5 only */
 html, body {
     scroll-behavior: smooth;
 }

0

il modo più semplice per fare in modo che il browser scorra la pagina fino a un determinato punto di ancoraggio è digitare style.css * {scroll-behavior: smooth;} e nella navigazione html usare #NameOfTheSection

*{scroll-behavior: smooth;}
<a href="#scroll-to">Home<a/>

<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>
<p>other sections</p>

<section id="scroll-to">
<p>it will scroll down to this section</p>
</section>

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.