Wie scrolle ich mit JavaScript zu einem Element?

152

Ich versuche, die Seite in ein <div>Element zu verschieben.

Ich habe den nächsten Code ohne Erfolg ausprobiert:

document.getElementById("divFirst").style.visibility = 'visible';
document.getElementById("divFirst").style.display = 'block';
C ..
quelle
1
visibilityund displaywerden verwendet, um Elemente (in) sichtbar zu machen. Möchten Sie das Div auf dem Bildschirm scrollen?
Lekensteyn
Was für ein Fokus? Der gleiche Fokus wie beim Durchblättern von Formularelementen oder beim Fokussieren im Sinne einer Hervorhebung des Elements? Sie müssen lediglich das Element anzeigen, was keine Auswirkung hat, wenn es bereits angezeigt wird.
Felix Kling
Fokus als Bildlauf in die Ansicht?
Epascarello
12
el.scrollIntoView(true)
Blazemonger

Antworten:

123

Sie können einen Anker verwenden, um das Div zu "fokussieren". Dh:

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

und verwenden Sie dann das folgende Javascript:

// the next line is required to work around a bug in WebKit (Chrome / Safari)
location.href = "#";
location.href = "#myDiv";
Nikoloff
quelle
9
Chrome (WebKit) hat einen Fehler, der dazu führt, dass die Seite nach dem Setzen des Ankers nicht mehr gescrollt wird. Verwenden Sie : location.href="#";location.href="#myDiv". Die Verwendung id="myDiv"wird der Verwendung vorgezogen name="myDiv"und funktioniert auch.
Lekensteyn
8
Ich hatte genau dieses Problem, aber das WebKit "Fix" verursacht ein Problem für mich in FF 3.6.13. Es funktioniert ohne die Zeile "#", aber wenn Sie es hinzufügen, geht es zu "#" und versucht nie, zu "#myDiv" zu wechseln. Ich bleibe bei der Lösung ohne das "#", das für mich funktioniert ... woohoo!
TimFoolery
1
Dies funktioniert nicht gut für mich, da es alle diese Navigationsereignisse zum Browserverlauf hinzufügt und ich nicht einfach zur vorherigen Seite zurückkehren kann
bikeman868
Ich denke, 'AnhSirk Dasarp' unten ist eine bessere Methode, um das gewünschte Element an den oberen Rand des sichtbaren Bildschirms zu scrollen.
Curious101
Was ist, wenn sich der Scroller in einem inneren Div befindet?
Qian Chen
241

scrollIntoView funktioniert gut:

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

Vollständige Referenz in den MDN-Dokumenten:
https://developer.mozilla.org/en-US/docs/Web/API/Element.scrollIntoView

schpet
quelle
11
@CameronMcCluskie Es sind nur die seltsamen "scrollIntoViewOptions" (reibungsloses Scrollen usw.), die exklusive Firefox-Unterstützung bieten. Die grundlegende Verwendung, die ich in meiner Antwort habe, sollte für fast alles funktionieren.
schpet
4
Ich bestätige, dass es ab dem 16. April auch unter Opera und Chrome funktioniert.
lvr123
2
Wenn Sie diese Lösung verwenden und oben eine feste Navigationsleiste haben, müssen Sie dies ebenfalls berücksichtigen. Eine andere Lösung ist möglicherweise besser geeignet, z. B. windows.scrollTo (posX, posY) mit richtig berechnetem posY.
Manfred
2
Arbeitete in Firefox, Opera und Safari.
Jagdeep Singh
3
Hier ist eine weitere Quelle (caniuse) für die Browserkompatibilität vonscrollIntoView
The Red Pea
99

Ihre Frage und die Antworten sehen anders aus. Ich weiß nicht, ob ich mich irre, aber für diejenigen, die googeln und hierher gelangen, wäre meine Antwort folgende:

  1. Meine Antwort zum Stackoverflow
  2. Eine ähnliche Frage

Meine Antwort erklärte:

Hier ist ein einfaches Javascript dafür

Rufen Sie dies auf, wenn Sie den Bildschirm zu einem Element mit der ID = "yourSpecificElementId" scrollen müssen.

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

dh. für die obige Frage, wenn die Absicht besteht, den Bildschirm mit der ID 'divFirst' zum div zu scrollen.

Der Code wäre: window.scroll(0,findPos(document.getElementById("divFirst")));

und Sie benötigen diese Funktion für die Arbeit:

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

Der Bildschirm wird zu Ihrem spezifischen Element gescrollt.

AnhSirk Dasarp
quelle
12
Diese Lösung hat den Vorteil, dass die sichtbare URL in der Navigationsleiste des Browsers nicht durch Hinzufügen von MyID-Ankern beeinträchtigt wird.
Renaud Bompuis
2
Vielen Dank, ich denke, dies sollte die akzeptierte Antwort sein. Es handelt sich um ein Java-Skript, nicht um HTML wie die aktuelle Antwort, die für mich nicht funktionieren würde, aber das tat es!
Steve Byrne
Das heißt, wenn es das ist, das windowSie scrollen möchten, kein überlaufender
Anzeigebereich
1
Funktioniert nach dem Wechsel [curtop]zu curtopam Ende
Goldylucks
Wenn Sie nicht möchten, dass dieses Element ganz oben auf der Seite angezeigt wird, sondern lieber einen Bildlauf durchführen, sodass sich das Element in der Mitte des Bildschirms befindet, subtrahieren (window.screen.height/2)Sie es
Albert Renshaw
47

Für Chrome und Firefox

Ich habe ein bisschen darüber nachgedacht und herausgefunden, was sich irgendwie wie die natürlichste Art anfühlt, es zu tun. Natürlich ist dies jetzt meine persönliche Lieblingsrolle. :) :)

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

Für IE-, Edge- und Safari-Unterstützer

Beachten Sie, dass window.scroll({ ...options })dies in IE, Edge und Safari nicht unterstützt wird. In diesem Fall ist es höchstwahrscheinlich am besten zu verwenden element.scrollIntoView(). (Unterstützt von IE 6). Sie können höchstwahrscheinlich (sprich: ungetestet) Optionen ohne Nebenwirkungen übergeben.

Diese können natürlich in eine Funktion eingeschlossen werden, die sich entsprechend dem verwendeten Browser verhält.

Höhlenmensch
quelle
3
Arbeiten wie Charme :)
Midzer
1
Dies ist die einzige Lösung, die bei mir mit Chrome funktioniert hat.
wkille
1
Ich wollte Ihre Lösung nehmen, da es möglich ist, die Position fein abzustimmen (in meinem Fall y-80). Es scheint, als var element = document.getElementById ("Div"); fehlt in deinem Beispiel? Außerdem funktioniert es nicht mit IE11. IE11 kennt window.scrollY nicht - wir müssen stattdessen window.pageYOffset verwenden, um einen Wert zu erhalten. Nachdem ich das geändert hatte, hatte ich verschiedene (nicht nachvollziehbare) Abfragefehler (natürlich - wie meistens - nur in IE11. Deshalb habe ich document.getElementById ("divFirst"). ScrollIntoView () und dann $ (window) implementiert ) .scrollTop ($ (Fenster) .scrollTop () - 80); was mit allen
Browsern
window.scroll
Wird
Vielen Dank für die Kommentare. Ich aktualisiere die Antwort, um die Browserkompatibilität einzuschließen.
Höhlenmensch
8

Versuche dies:

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

z.B @:

http://jsfiddle.net/Vgrey/

Chandu
quelle
Ich möchte nur betonen, dass die DOM-Eigenschaft element.tabIndexaber nicht ist element.tabindex; Der zweite funktioniert unter Firefox, aber nicht unter Chrome (zumindest als ich es vor einiger Zeit ausprobiert habe). Natürlich wird sowohl als HTML-Attribut als auch tabIndexals tabindexArbeit verwendet (und unter XHTML tabindexmuss verwendet werden)
Oriol
6

Um zu einem bestimmten Element zu scrollen, haben Sie unten nur diese JavaScript-Lösung erstellt.

Einfache Verwendung:

EPPZScrollTo.scrollVerticalToElementById('signup_form', 20);

Engine-Objekt (Sie können mit Filter- und FPS-Werten herumspielen):

/**
 *
 * 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
quelle
@codeWithMe Yap, es ist eher ein iOS-ähnlicher Code, bei dem die tatsächliche Menge keine Rolle spielt. Sie können also alles nach dem benennen, was es tut / enthält. Ich ziehe das der Kürze vor.
Geri Borbás
5

Hier ist eine Funktion, die einen optionalen Versatz für diese festen Überschriften enthalten kann. Keine externen Bibliotheken erforderlich.

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

Sie können die Höhe eines Elements mit JQuery erfassen und dorthin scrollen.

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

Update März 2018

Scrollen Sie zu dieser Antwort, ohne JQuery zu verwenden

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

Sie können den Fokus auf Element setzen. Es funktioniert besser alsscrollIntoView

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

node.focus()

node.removeAttribute('tabindex')

ZhenyaUsenko
quelle
Oh Mann, du hast meinen Tag gerettet. Habe viele Sachen getestet, aber dieses war das einzige, was für mich funktioniert hat und es wird von allen Browsern unterstützt. Übrigens habe ich eine Eingabe erstellt und 1px Höhe und Breite angegeben und mich auf die Eingabe konzentriert. Es funktioniert großartig. Danke
Martian.titan
5

Die beste, kürzeste Antwort darauf, was auch mit Animationseffekten funktioniert:

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

Wenn Sie eine feste Navigationsleiste haben, subtrahieren Sie einfach deren Höhe vom oberen Wert. Wenn Ihre feste Balkenhöhe also 70 Pixel beträgt, sieht Zeile 2 folgendermaßen aus:

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

Erläuterung: Zeile 1 erhält die Elementposition. Zeile 2 scrollt zur Elementposition. behaviorEigenschaft fügt einen glatten animierten Effekt hinzu

DAVID AJAYI
quelle
Wirklich cool, funktioniert aber noch nicht mit Safari und einigen anderen Browsern. Funktioniert jedoch mit dieser Polyfüllung github.com/iamdustan/smoothscroll . ;)
Mhor Mé
2

Der Fokus kann nur auf interaktive Elemente gelegt werden ... Div repräsentiert nur einen logischen Abschnitt der Seite.

Vielleicht können Sie die Ränder um div setzen oder die Farbe ändern, um einen Fokus zu simulieren. Und ja, Sichtbarkeit steht nicht im Mittelpunkt.

SM Kamran
quelle
1

Ich denke, wenn Sie Ihrem Div einen Tabindex hinzufügen, kann er sich konzentrieren:

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

Ich denke jedoch nicht, dass es gültig ist. Tabindex kann nur auf einen Bereich, eine Schaltfläche, eine Eingabe, ein Objekt, eine Auswahl und einen Textbereich angewendet werden. Aber probieren Sie es aus.

Robin
quelle
1
In HTML5 tabindexhandelt es sich um ein "Kernattribut", bei dem es sich um "globale Attribute" handelt (Attribute, die allen Elementen in der HTML-Sprache gemeinsam sind). Siehe w3.org/TR/2011/WD-html-markup-20110113/global-attributes.html
Oriol
1

Ähnlich wie bei @ caveman's Lösung

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

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

Sie können sich nicht auf ein Div konzentrieren. Sie können sich nur auf ein Eingabeelement in diesem Div konzentrieren. Außerdem müssen Sie element.focus () anstelle von display () verwenden.

Andrey
quelle
1
Sie können eine <div>Fokussierbarkeit festlegen, wenn Sie das tabindexAttribut verwenden. Siehe dev.w3.org/html5/spec-author-view/editing.html#attr-tabindex
Oriol
0

Nachdem ich mich viel umgesehen habe, hat das endlich für mich funktioniert:

  1. Suchen / lokalisieren Sie div in Ihrem Dom mit Bildlaufleiste. Für mich sah es so aus: "div class =" table_body table_body_div "scroll_top =" 0 "scroll_left =" 0 "style =" width: 1263px; Höhe: 499px; "

  2. Ich habe es mit diesem xpath gefunden: // div [@ class = 'table_body table_body_div']

  3. Verwendete JavaScript, um das Scrollen wie folgt auszuführen: (JavascriptExecutor) Treiber) .executeScript ("Argumente [0] .scrollLeft = Argumente [1];", Element, 2000);

2000 ist die Anzahl der Pixel, die ich nach rechts scrollen wollte. Verwenden Sie scrollTop anstelle von scrollLeft, wenn Sie Ihren Div nach unten scrollen möchten.

Hinweis: Ich habe versucht, scrollIntoView zu verwenden, aber es hat nicht richtig funktioniert, da meine Webseite mehrere Divs hatte. Es funktioniert, wenn Sie nur ein Hauptfenster haben, in dem der Fokus liegt. Dies ist die beste Lösung, die mir begegnet ist, wenn Sie jQuery nicht verwenden möchten, was ich nicht wollte.

Anchal Agrawal
quelle
0

Eine Methode, die ich oft benutze, um einen Container zu seinem Inhalt zu scrollen.

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

Wenn Sie global überschreiben möchten, können Sie auch Folgendes tun:

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
quelle
0

Aufgrund des Verhaltens funktioniert "glatt" in Safari, Safari ios, Explorer nicht. Normalerweise schreibe ich eine einfache Funktion mit 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
quelle
-1

Wenn Sie HTML verwenden möchten, können Sie Folgendes verwenden:

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

und machen Sie es zu einem HTML-Link zu der spezifischen Element-ID. Es ist im Grunde getElementByIdHTML-Version.

suryansh
quelle
-3

Probieren Sie diese Funktion aus

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

Übergeben Sie die Div-ID als Parameter, es wird funktionieren. Ich verwende sie bereits

Virendra Rastogi
quelle
Aus welcher Bibliothek stammt $j?
EoghanM
Ich gehe davon aus, dass $ j auf jQuery verweist - die Frage besagt, dass Javascript benötigt wird.
Cameron W.