Wie scrolle ich eine HTML-Seite zum angegebenen Anker?

264

Ich möchte den Browser dazu bringen, die Seite mit JavaScript zu einem bestimmten Anker zu scrollen.

Ich habe in meinem HTML-Code ein nameoder idAttribut angegeben :

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

oder

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

Ich möchte den gleichen Effekt erzielen, den Sie durch Navigieren erzielen würden http://server.com/path#anchorName. Die Seite sollte so gescrollt werden, dass sich der Anker oben im sichtbaren Teil der Seite befindet.

Juha Syrjälä
quelle

Antworten:

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

Keine jQuery erforderlich!

Dean Harding
quelle
91
Das scrollt aber nicht wirklich, es springt nur. An diesem Punkt können Sie auch einfach auf den Anker verlinken<a href="#anchorName">link</a>
Ryan
52
Beachten Sie, dass dies nur einmal funktioniert. Sobald der Hash festgelegt ist, wird die Seite nicht mehr zum selben Hash gescrollt, es sei denn, Sie ändern ihn in einen Dummy und setzen ihn dann erneut.
Cristian Vrabie
13
Sie sollten scrollTo nicht verwenden, da es bereits vom globalen Fensterobjekt verwendet wird. Außerdem sollte der Parameter nicht als Hash bezeichnet werden, da auch location.hash definiert ist. Sie können diesen Code verwenden:function scrollToHash(hashName) { location.hash = "#" + hashName; }
Markus Zeller
3
@ MarkusZeller, warum sollte der Parameter nicht Hash heißen? Es kollidiert nicht mit dem Ort, oder?
Gherman
3
Dies führt einen Bildlauf durch, wenn Sie "Bildlaufverhalten: glatt" einstellen. auf dem HTML-Element
Stapler
225

Viel einfacher:

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();
Armando Pérez Marqués
quelle
22
Ich dachte zuerst, Mandx trolle, dann habe ich es versucht und es hat funktioniert. Über mich hinaus, wie ich noch nie auf diese Methode gestoßen bin. Mozilla Docs für diese Methode . Es scheint auch, dass dies in Browsern sehr gut unterstützt wird.
Jonathan Dumaine
2
Ich hatte viele Probleme mit jquery-Lösungen, die nicht gescrollt wurden. Das hat mir viel Frust erspart.
NuclearPeon
1
WARNUNG! Diese Methode kann Probleme haben, wenn ein Div darüber schwebende Elemente enthält und seine Größe nicht einfach bestimmen kann.
Vogomatix
5
Dies ist eine saubere Lösung, die jedoch derzeit keine Optimierungen zulässt, sondern einen harten Bildlauf durchführt. Es gibt einen experimentellen Parameter scrollIntoViewOptions, für den eine behavior: "smooth"Option verfügbar ist, der derzeit jedoch nur mit Firefox kompatibel ist.
Rocha
Wie animiere ich das?
SkuraZZ
124

Sie können jQuerys .animate () , .offset () und verwenden scrollTop. Mögen

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

Beispiellink: http://jsbin.com/unasi3/edit

Wenn Sie nicht animieren möchten, verwenden Sie .scrollTop () wie

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

oder Javascripts native location.hashwie

location.hash = '#' + anchorid;
jAndy
quelle
1
Wenn Sie einen Selektor erstellen, um das <h1 id="anchorName">oder ein zu finden <a name="anchorName">, verwenden Sie $('#'+hash+',a[name='+hash+']')oder wählen Sie leicht optimiert $(document.getElementById(hash) || 'a[name='+hash+']'), um das Element zuerst anhand der ID zu suchen, und greifen Sie nur dann auf die Suche nach dem a zurück, wenn eines nicht gefunden wird.
Gnarf
@gnarf - Die '#' - Selektoren in jQuery müssen nicht optimiert werden - sie sind bereits für Sie optimiert. Es ist ziemlich leicht zu erkennen, ob Sie den jQuery-Quellcode gelesen haben.
CodeJoust
3
@CodeJoust - Ich bin im jQuery-Team, habe es oft gelesen und ja, $("#selector")ist optimiert, $("#selector,a[name='selector']")wird aber nicht so schnell dieselben Optimierungen durchlaufen. Ich nehme an, mein 2,5 Jahre alter Kommentar klingt etwas seltsam. Die "Optimierung" vermeidet die a[name='selector']Suche, wenn sie die ID findet, und optimiert nicht die Suche nach der ID.
Gnarf
1
Ich hatte etwas Glück mit diesem Ansatz: <a data-hash="about"> About </a> <script> $ ("[data-hash]"). Click (function () {var data = $ (this) .attr ("Daten-Hash"); $ (document.body) .animate ({'scrollTop': $ ("#" + Daten) .offset (). top}, 500);}); </ script>
Jazzy
32

Tolle Lösung von jAndy, aber die glatte Schriftrolle scheint Probleme mit Firefox zu haben.

Das Schreiben auf diese Weise funktioniert auch in Firefox.

(function($) {
    $(document).ready(function() {
         $('html, body').animate({
           'scrollTop':   $('#anchorName2').offset().top
         }, 2000);
    });
})(jQuery);
5hahiL
quelle
In der neuesten Chrome-Version ist dies die einzige Methode, die konsistent funktioniert. Danke für den Tipp!
gaborous
32

2018-2020 Pure js:

Es gibt eine sehr bequeme Möglichkeit, zum Element zu scrollen:

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

Aber soweit ich weiß, hat er keine so gute Unterstützung wie die folgenden Optionen.

Geben Sie hier die Bildbeschreibung ein

Erfahren Sie mehr über die Methode.


Wenn es notwendig ist, dass sich das Element oben befindet:

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

Demonstrationsbeispiel für Codepen


Wenn Sie möchten, dass sich das Element in der Mitte befindet:

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

Demonstrationsbeispiel für Codepen


Unterstützung:

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

Sie schreiben, dass dies scrolldie gleiche Methode ist wie scrollTo, aber die Unterstützung zeigt sich besser in scrollTo.

Mehr zur Methode

Илья Зеленько
quelle
Diese Lösung funktioniert sehr sehr gut! Danke für das Teilen!
gaborous
29

Eine reine Javascript-Lösung ohne JQuery. Getestet auf Chrome & Ie, nicht getestet auf 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/

Michael Whinfrey
quelle
1
Entschuldigung für das Kommentieren eines alten Themas, aber das funktioniert am besten für mich, da mein Projekt JQuery nicht verwendet. Das einzige Problem, das mir aufgefallen ist, ist, dass etwa 5 Pixel fehlen, wenn Sie ganz nach oben scrollen.
AntBirch
Sehr erfrischend, eine reine JS-Version zu sehen. Ich bringe den Schülern bei, immer unter die Haube zu schauen und zu verstehen, was JQuery für sie tut. Dies ist also ein schönes Beispiel.
Dave Everitt
2
Dies sollte die akzeptierte Antwort sein: Es ist ein reines js-Beispiel UND es erzielt den gewünschten Scrolling-Animationseffekt. Ich habe den Timeout-Wert auf 20 eingestellt und er funktioniert einwandfrei.
Mark Barrasso
Vielen Dank, ich liebe reine Javascript-Lösungen
R01010010
2
Funktioniert unter IOS und hat es gerade getestet.
Debbie Kurth
23

Im Jahr 2018 benötigen Sie jQuery für so etwas Einfaches nicht. Die integrierte scrollIntoView()Methode unterstützt eine " behavior" -Eigenschaft, mit der Sie problemlos zu einem beliebigen Element auf der Seite scrollen können. Sie können die Browser-URL sogar mit einem Hash aktualisieren, um sie als Lesezeichen zu speichern.

In diesem Tutorial zum Scrollen von HTML-Lesezeichen finden Sie eine native Methode, um allen Ankerlinks auf Ihrer Seite automatisch einen reibungslosen Bildlauf hinzuzufügen:

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()
    })
}
Coco Puffs
quelle
2
Ausgezeichnete Antwort, die die Abhängigkeit von jQuery beseitigt
zai chang
Beeindruckend! Funktioniert super!
Alexandru Trandafir Catalin
14

Scrollen Sie sanft zur richtigen Position (2019)

Holen Sie sich die richtige y Koordinate und verwendenwindow.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'});

Mit Versatz

scrollIntoViewist auch eine gute Option, funktioniert aber in einigen Fällen möglicherweise nicht perfekt. Zum Beispiel, wenn Sie zusätzlichen Versatz benötigen . Mit müssen scrollToSie nur diesen Offset wie folgt hinzufügen:

const yOffset = -10; 

window.scrollTo({top: y + yOffset, behavior: 'smooth'});
Arseniy-II
quelle
Ich denke, Sie sollten Folgendes zur CSS-Style-Datei hinzufügen: css html { scroll-behavior: smooth; }
parismiguel
5
$(document).ready ->
  $("a[href^='#']").click ->
    $(document.body).animate
      scrollTop: $($(this).attr("href")).offset().top, 1000
Kakteen
quelle
5

Die Lösung von CSS-Tricks funktioniert in jQuery 2.2.0 nicht mehr. Es wird ein Auswahlfehler ausgegeben:

JavaScript-Laufzeitfehler: Syntaxfehler, nicht erkannter Ausdruck: a [href * = #]: not ([href = #])

Ich habe es durch Ändern des Selektors behoben. Das vollständige Snippet lautet:

$(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;
    }
  }
 });
});
Bill Shihara
quelle
4

Die meisten Antworten sind unnötig kompliziert.

Wenn Sie nur zum Zielelement springen möchten, benötigen Sie kein JavaScript:

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

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

Wenn Sie animiert zum Ziel scrollen möchten, lesen Sie bitte die Antwort von @ Shahil.

Brian
quelle
Manchmal müssen Sie dies jedoch dynamisch tun. dh durch keine direkte Handlung des Benutzers. Ich glaube, das will das OP.
Jpaugh
1
Ja, das OP war sich der Ankerverbindungsfunktionalität bereits bewusst.
Isherwood
4

Das funktioniert:

$('.scroll').on("click", function(e) {

  e.preventDefault();

  var dest = $(this).attr("href");

  $("html, body").animate({

    'scrollTop':   $(dest).offset().top

  }, 2000);

});

https://jsfiddle.net/68pnkfgd/

Fügen Sie einfach die Klasse 'scroll' zu allen Links hinzu, die Sie animieren möchten

Chuck Le Butt
quelle
Schöne, einfach zu bedienende Lösung. Vielen Dank!
Smitty-Werben-Jäger-Manjenson
3

Dies ist ein funktionierendes Skript, mit dem die Seite zum Anker gescrollt wird. Zum Einrichten geben Sie dem Ankerlink einfach eine ID, die dem Namensattribut des Ankers entspricht, zu dem Sie einen Bildlauf durchführen möchten.

<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>
Rudy Lister
quelle
2

Ich weiß, dass diese Frage wirklich alt ist, aber ich habe in CSS-Tricks eine einfache und einfache jQuery-Lösung gefunden . Das ist der, den ich jetzt benutze.

$(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;
      }
    }
  });
});
Horacio
quelle
1
Der Selektor löst in jquery 2.2.0 eine Ausnahme aus. 0x800a139e - JavaScript-Laufzeitfehler: Syntaxfehler, nicht erkannter Ausdruck: a [href * = #]: nicht ([href = #])
Bill Shihara
2

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

Adam Pery
quelle
2

eine vue2-Lösung ... fügen Sie eine einfache Dateneigenschaft hinzu, um die Aktualisierung einfach zu erzwingen

  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;
 }
Yordan Georgiev
quelle