Jak przewinąć do elementu za pomocą JavaScript?


152

Próbuję przenieść stronę do <div>elementu.

Próbowałem następnego kodu bez skutku:

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

1
visibilityi displaysłużą do uwidocznienia elementów (nie). Czy chcesz przewinąć element DIV na ekranie?
Lekensteyn

Jaki rodzaj skupienia? Taki sam cel jak przy przechodzeniu tabulatorami przez elementy formularza lub skupienie się w sensie podświetlania elementu? Jedyne, co musisz zrobić, to wyświetlić element, co nie ma wpływu, jeśli jest już wyświetlony.
Felix Kling

Ustawić ostrość jako przewijanie w widoku
epascarello

Odpowiedzi:


123

Możesz użyć kotwicy, aby „skupić” element div. To znaczy:

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

a następnie użyj następującego javascript:

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

9
Chrome (WebKit) ma błąd, który powoduje, że strona nie przewija się po ustawieniu kotwicy. Zastosowanie: location.href="#";location.href="#myDiv". Używanie id="myDiv"jest preferowane name="myDiv"i działa też.
Lekensteyn

8
Miałem dokładnie ten problem, ale „poprawka” WebKit powoduje problem w FF 3.6.13. Działa bez linii „#”, ale jeśli ją dodasz, przechodzi do „#” i nigdy nie próbuje przejść do „#myDiv”. Zostanę przy rozwiązaniu bez znaku „#”, które działa dla mnie ... woohoo!
TimFoolery,

1
To nie działa dobrze dla mnie, ponieważ dodaje wszystkie te zdarzenia nawigacji do historii przeglądarki i nie mogę łatwo wrócić do poprzedniej strony
bikeman868

Myślę, że „AnhSirk Dasarp” poniżej jest lepszą metodą przewijania żądanego elementu na górę widocznego ekranu.
Ciekawy101

A co, jeśli rolka znajduje się w wewnętrznym div?
Qian Chen

241

scrollIntoView działa dobrze:

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

pełne odniesienie w dokumentacji MDN:
https://developer.mozilla.org/en-US/docs/Web/API/Element.scrollIntoView


11
@CameronMcCluskie to tylko dziwne "scrollIntoViewOptions" (płynne przewijanie itp.), Które ma wyłączną obsługę przeglądarki Firefox. podstawowe zastosowanie, które mam w mojej odpowiedzi, powinno działać na prawie wszystkim.
schpet,

4
Potwierdzam, że od 16 kwietnia działa również w przeglądarce Opera i Chrome.
lvr123

2
Korzystając z tego rozwiązania i mając na górze stały pasek nawigacyjny, również musisz wziąć to pod uwagę. Inne rozwiązanie może być bardziej odpowiednie, na przykład windows.scrollTo (posX, posY) z prawidłowo obliczoną pozycją.
Manfred,

2
Pracował w przeglądarkach Firefox, Opera i Safari.
Jagdeep Singh

3
Oto kolejne źródło (caniuse) zgodności przeglądarkiscrollIntoView
The Red Pea

99

Twoje pytanie i odpowiedzi wyglądają inaczej. Nie wiem, czy się mylę, ale dla tych, którzy szukają w Google i docierają tutaj, moja odpowiedź byłaby następująca:

  1. Moja odpowiedź na temat stackoverflow
  2. Podobne pytanie

Moja odpowiedź wyjaśniła:

tutaj jest prosty skrypt javascript do tego

wywołaj to, gdy chcesz przewinąć ekran do elementu, który ma id = "yourSpecificElementId"

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

to znaczy. na powyższe pytanie, jeśli intencją jest przewinięcie ekranu do div o identyfikatorze 'divFirst'

kod wyglądałby następująco: window.scroll(0,findPos(document.getElementById("divFirst")));

i potrzebujesz tej funkcji do pracy:

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

ekran zostanie przewinięty do konkretnego elementu.


12
To rozwiązanie ma tę zaletę, że nie zmienia widocznego adresu URL na pasku nawigacyjnym przeglądarki, dodając kotwice MyID.
Renaud Bompuis

2
Dziękuję, czuję, że to powinna być akceptowana odpowiedź, ponieważ jest to skrypt java, a nie HTML, jak obecna odpowiedź, która nie zadziała dla mnie, ale tak się stało!
Steve Byrne

To znaczy, jeśli windowchcesz przewijać, a nie przepełniony obszar wyświetlania
WebWanderer

1
Prace po zmianie [curtop], aby curtopna koniec
goldylucks

Jeśli nie chcesz, aby ten element spychał na samą górę strony, ale zamiast tego wolisz, aby przewijał się tak, aby element znajdował się na środku ekranu, odejmij (window.screen.height/2)od findPos
Albert Renshaw

47

Dla Chrome i Firefox

Trochę się temu przyglądałem i znalazłem ten, który wydaje się być najbardziej naturalnym sposobem na zrobienie tego. Oczywiście jest to teraz mój ulubiony zwój. :)

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

Dla zwolenników IE, Edge i Safari

Pamiętaj, że window.scroll({ ...options })nie jest obsługiwane w przeglądarkach IE, Edge i Safari. W takim przypadku najlepiej jest użyć element.scrollIntoView(). (Obsługiwane w IE 6). Najprawdopodobniej możesz (czytaj: nieprzetestowane) przekazać opcje bez żadnych skutków ubocznych.

Można je oczywiście opakować w funkcję, która zachowuje się w zależności od używanej przeglądarki.


3
Działa jak urok :)
midzer

1
To jedyne rozwiązanie, które działało u mnie z Chrome.
wkille

1
Chciałem wziąć Twoje rozwiązanie, ponieważ możliwe jest precyzyjne dostrojenie pozycji (w moim przypadku y-80). Wygląda na to, że var element = document.getElementById ("Div"); brakuje w twoim przykładzie? Ponadto nie działa z IE11. IE11 nie zna window.scrollY - zamiast tego musimy użyć window.pageYOffset, aby otrzymać wartość. Po tym, jak to zmieniłem, miałem różne (nie do zrozumienia) błędy jquery (oczywiście - jak w większości - tylko w IE11). Dlatego zaimplementowałem document.getElementById ("divFirst"). ScrollIntoView (); a następnie $ (window ) .scrollTop ($ (window) .scrollTop () - 80); co działa ze wszystkimi przeglądarkami.
FredyWenger

Nieobsługiwane w Safari (przekazywanie opcji dowindow.scroll
goldylucks,

Dzięki za komentarze, aktualizuję odpowiedź o zgodność z przeglądarką.
Caveman

8

Spróbuj tego:

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

np. @:

http://jsfiddle.net/Vgrey/


Chcę tylko podkreślić, że właściwość DOM jest, element.tabIndexale nie element.tabindex; druga działa na Firefoksie, ale nie na Chrome (przynajmniej kiedy próbowałem go jakiś czas temu). Oczywiście, używany jako atrybut HTML tabIndexi tabindexdziała (i na XHTML, tabindexmusi być używany)
Oriol

6

Aby przewinąć do danego elementu, po prostu zrobiłem to rozwiązanie tylko javascript poniżej.

Proste użycie:

EPPZScrollTo.scrollVerticalToElementById('signup_form', 20);

Obiekt silnika (możesz bawić się filtrem, wartościami 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, jest bardziej podobny do kodu podobnego do iOS, w którym rzeczywista ilość nie ma znaczenia, więc możesz śmiało nazwać wszystko po tym, co robi / zawiera. Wolę to od krótkości.
Geri Borbás

5

Oto funkcja, która może zawierać opcjonalne przesunięcie dla tych stałych nagłówków. Żadne zewnętrzne biblioteki nie są potrzebne.

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

Możesz pobrać wysokość elementu za pomocą JQuery i przewinąć do niego.

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

Aktualizacja marzec 2018

Przewiń do tej odpowiedzi bez używania JQuery

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

5

Możesz ustawić fokus na element. Działa lepiej niżscrollIntoView

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

node.focus()

node.removeAttribute('tabindex')


O rany, uratowałeś mi dzień. Przetestowałem wiele rzeczy, ale ta była jedyną, która działała dla mnie i obsługuje wszystkie przeglądarki. Przy okazji stworzyłem dane wejściowe i podałem 1px wysokość i szerokość i skupiłem się na danych wejściowych. Działa świetnie. Dzięki
Martian.titan

5

Najlepsza, najkrótsza odpowiedź, że to, co działa nawet z efektami animacji:

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

Jeśli masz stały pasek nawigacji, po prostu odejmij jego wysokość od górnej wartości, więc jeśli stała wysokość paska wynosi 70 pikseli, linia 2 będzie wyglądać następująco:

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

Objaśnienie: Linia 1 pobiera pozycję elementu Linia 2 przewija do pozycji elementu; behaviorwłaściwość dodaje płynny efekt animacji


Naprawdę fajne, ale jeszcze nie działa w Safari i niektórych innych przeglądarkach. Działa z tym wypełnieniem github.com/iamdustan/smoothscroll . ;)
Íhor Mé

2

Fokus można ustawić tylko na elementach interaktywnych ... DIV reprezentują tylko logiczną sekcję strony.

Być może możesz ustawić obramowanie wokół div lub zmienić jego kolor, aby zasymulować ostrość. I tak Widoczność nie jest skupiona.


1

Myślę, że jeśli dodasz tabindex do swojego div, będzie on mógł uzyskać fokus:

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

Nie sądzę jednak, że jest to poprawne, tabindex można zastosować tylko do obszaru, przycisku, wejścia, obiektu, zaznaczenia i obszaru tekstu. Ale spróbuj.


1
W HTML5 tabindexjest to „podstawowy atrybut”, czyli „atrybuty globalne” (atrybuty, które są wspólne dla wszystkich elementów w języku HTML). Zobacz w3.org/TR/2011/WD-html-markup-20110113/global-attributes.html
Oriol

1

Podobne do rozwiązania @ caveman

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

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


0

Po długim rozglądaniu się, to w końcu zadziałało:

  1. Znajdź / zlokalizuj div w swojej domenie, który ma pasek przewijania. Dla mnie wyglądało to tak: "div class =" table_body table_body_div "scroll_top =" 0 "scroll_left =" 0 "style =" width: 1263px; wysokość: 499px; "

  2. Zlokalizowałem to za pomocą tej ścieżki xpath: // div [@ class = 'table_body table_body_div']

  3. Użył JavaScript do wykonania przewijania w następujący sposób: (JavascriptExecutor) sterownik) .executeScript ("arguments [0] .scrollLeft = arguments [1];", element, 2000);

2000 to liczba pikseli, które chciałem przewinąć w prawo. Użyj scrollTop zamiast scrollLeft, jeśli chcesz przewijać div w dół.

Uwaga: próbowałem użyć scrollIntoView, ale nie działało to poprawnie, ponieważ moja strona internetowa zawierała wiele elementów div. Będzie działać, jeśli masz tylko jedno główne okno, w którym znajduje się fokus. To najlepsze rozwiązanie, z jakim się spotkałem, jeśli nie chcesz używać jQuery, czego ja nie chciałem.


0

Metoda, której często używam do przewijania kontenera do jego zawartości.

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

jeśli chcesz nadpisać globalnie, możesz również zrobić:

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

Ze względu na zachowanie "płynne" nie działa w Safari, Safari ios, Explorer. Zwykle piszę prostą funkcję wykorzystującą 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

Jeśli chcesz używać html, możesz po prostu użyć tego:

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

i uczyń z niego link html do określonego identyfikatora elementu. Jego zasadniczo getElementByIdwersja html.


-3

spróbuj tej funkcji

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

Przekaż id div jako parametr, który zadziała. Już go używam


z jakiej biblioteki pochodzi $j?
EoghanM

Zakładam, że $ j odwołuje się do jQuery - pytanie mówi, że wymaga Javascript.
Cameron W.
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.