Як перейти до елемента за допомогою JavaScript?


152

Я намагаюся перемістити сторінку до <div>елемента.

Я спробував наступний код безрезультатно:

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

1
visibilityі displayвикористовуються для того, щоб зробити видимими (не) елементи. Ви хочете прокрутити діва на екрані?
Лекенштейн

Який фокус? Такий же фокус, який ви маєте, коли ви перебираєте елементи форми або фокус у сенсі виділення елемента якось? Єдине, що ви повинні зробити - це відобразити елемент, який не має ефекту, якщо він уже відображається.
Фелікс Клінг

Фокусувати як прокручування в огляді?
epascarello

Відповіді:


123

Ви можете використовувати якір для "фокусування" діва. Тобто:

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

а потім скористайтеся таким javascript:

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

9
У Chrome (WebKit) є помилка, через яку сторінка не прокручується після встановлення якоря. Використання: location.href="#";location.href="#myDiv". Використовувати id="myDiv"перевагу над name="myDiv"та працює також.
Лекенштейн

8
У мене була така точна проблема, але «виправлення» WebKit викликає для мене проблему у FF 3.6.13. Він працює без рядка "#", але якщо додати його, він переходить до "#" і ніколи не намагається перейти до "#myDiv". Я буду дотримуватися рішення без "#", яке працює для мене ... woohoo!
TimFoolery

1
Це не добре працює для мене, оскільки він додає всі ці події навігації до історії браузера, і я не можу легко повернутися до попередньої сторінки
bikeman868

Я думаю, що "AnhSirk Dasarp" нижче - кращий метод прокручування потрібного елемента до верхньої частини видимого екрана.
Цікаво101,

Що робити, якщо скроллер знаходиться у внутрішній діві?
Qian Chen

241

scrollIntoView добре працює:

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

повна довідка в документах MDN:
https://developer.mozilla.org/en-US/docs/Web/API/Element.scrollIntoView


11
@CameronMcCluskie це ексклюзивна підтримка Firefox - лише дивна "scrollIntoViewOptions" (плавна прокрутка тощо). основне використання, яке я маю у своїй відповіді, повинно працювати майже на чому завгодно.
schpet

4
Я підтверджую, що станом на 16 квітня він працює також під Opera та Chrome.
lvr123

2
Якщо ви користуєтесь цим рішенням і у вас є фіксований планок наверху вгорі, вам також слід врахувати це. Інше рішення може бути більш підходящим, наприклад, windows.scrollTo (posX, posY) з правильно розрахованим posY.
Манфред

2
Працював у Firefox, Opera та Safari.
Jagdeep Singh

3
Ось ще одне джерело (канеза) для сумісності браузераscrollIntoView
The Red Pea

99

ваше запитання та відповіді виглядає інакше. Я не знаю, чи помиляюсь, але для тих, хто гуглить і дістається сюди, моя відповідь була б така:

  1. Моя відповідь на stackoverflow
  2. Подібне запитання

Моя відповідь пояснила:

ось простий javascript для цього

зателефонуйте цьому, коли потрібно прокрутити екран до елемента, який має id = "yourSpecificElementId"

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

тобто. для вищезазначеного питання, якщо наміром є прокрутка екрана до div з id 'divFirst'

код буде: window.scroll(0,findPos(document.getElementById("divFirst")));

і вам потрібна ця функція для працюючих:

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

екран буде прокручуватися до вашого конкретного елемента.


12
Це рішення має перевагу в тому, щоб не возитися з видимою URL-адресою на навігаційній панелі браузера шляхом додавання якорів MyID
Рено Бомпуа

2
Дякую, я відчуваю, що це має бути прийнятою відповіддю, це Java-скрипт, а не HTML, як поточна відповідь, яка не працювала б для мене, але це все-таки!
Стів Бірн

Тобто, якщо windowви хочете прокрутити, а не переповнену область перегляду
WebWanderer

1
Роботи після зміни [curtop]в curtopкінці
goldylucks

Якщо ви не хочете, щоб він переміщав цей елемент на саму верхню частину сторінки, але замість цього віддаєте перевагу прокрутці, щоб елемент (window.screen.height/2)знаходився в центрі екрана, відніміть від findPos
Альберт Реншо

47

Для Chrome та Firefox

Я трохи розглядав це, і я зрозумів це, яке якось відчуває себе як найприродніший спосіб зробити це. Звичайно, це моя особиста улюблена прокрутка зараз. :)

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

Для прихильників IE, Edge та Safari

Зауважте, що window.scroll({ ...options })це не підтримується в IE, Edge та Safari. У цьому випадку це, швидше за все, найкраще використовувати element.scrollIntoView(). (Підтримується в IE 6). Ви, швидше за все, можете (прочитати: неперевірене) пройти у варіантах без будь-яких побічних ефектів.

Звичайно, вони можуть бути зафіксовані у функції, яка поводиться відповідно до того, який браузер використовується.


3
Працює як шарм :)
середина

1
Це єдине рішення, яке працювало для мене з Chrome.
wkille

1
Я хотів прийняти ваше рішення, оскільки можна точно налаштувати положення (у моєму випадку y-80). Здається, як var element = document.getElementById ("Div"); відсутня у вашому прикладі? Далі це не працює з IE11. IE11 не знаю window.scrollY - нам потрібно використовувати window.pageYOffset, щоб отримати значення. Після того як я змінив це, у мене виникли різні помилки jquery (звичайно - як в основному - лише в IE11. Тому, я реалізував document.getElementById ("divFirst"). ScrollIntoView (); а потім $ (window) ) .scrollTop ($ (window) .scrollTop () - 80); що працює з усіма браузерами.
FredyWenger

Не підтримується на Safari (передача варіантів доwindow.scroll
goldylucks

Дякую за коментарі, я оновлюю відповідь, щоб включити сумісність браузера.
Печера

8

Спробуйте це:

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

наприклад @:

http://jsfiddle.net/Vgrey/


Я хочу лише підкреслити, що властивість DOM є, element.tabIndexале ні element.tabindex; другий працює на Firefox, але не на Chrome (принаймні, коли я його спробував деякий час тому). Звичайно, використовується як атрибут HTML як tabIndexі tabindexробота (і на XHTML, tabindexповинен використовуватися)
Oriol

6

Щоб перейти до заданого елемента, просто зробив це рішення тільки для JavaScript нижче.

Просте використання:

EPPZScrollTo.scrollVerticalToElementById('signup_form', 20);

Об'єкт двигуна (можна пограти з значеннями фільтра, кадрів в секунду):

/**
 *
 * 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, він більше схожий на iOS-подібний код, де фактична кількість не має значення, тому ви можете продовжувати називати все, що він робить / містить. Я вважаю за краще це через нетривалість.
Geri Borbás

5

Ось функція, яка може включати необов'язкове зміщення для цих фіксованих заголовків. Зовнішні бібліотеки не потрібні.

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

Ви можете схопити висоту елемента за допомогою JQuery і прокрутити його.

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

Оновлення березня 2018 року

Перейдіть до цієї відповіді, не використовуючи JQuery

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

5

Ви можете встановити фокус на елемент. Це працює краще, ніжscrollIntoView

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

node.focus()

node.removeAttribute('tabindex')


О людино, ти врятував мені день. Випробував багато матеріалів, але це було єдине, що працювало на мене, і він підтримував усі браузери. До речі, я створив вхід і дав висоту та ширину 1px і зробив фокус на input.it працює чудово. Спасибі
Martian.titan

5

Найкраща, найкоротша відповідь, що працює навіть з анімаційними ефектами:

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

Якщо ви маєте фіксовану смугу навігації, просто відніміть її висоту від верхнього значення, тож якщо ваша фіксована висота смуги становить 70 пікселів, рядок 2 буде виглядати так:

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

Пояснення: Рядок 1 отримує положення елемента Лінія 2 прокручується до положення елемента; behaviorвластивість додає плавний анімований ефект


Дійсно здорово, але поки не працює на Safari та деяких інших браузерах. Працює з цим поліфункцією github.com/iamdustan/smoothscroll . ;)
Íhor Mé

2

Фокус можна встановлювати лише на інтерактивних елементах ... Div представляє лише логічний розділ сторінки.

Можливо, ви можете встановити межі навколо div або змінити його колір, щоб імітувати фокус. І так, Visiblity - це не фокус.


1

Я думаю, що якщо ви додасте tabindex до свого div, він зможе отримати фокус:

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

Я не думаю, що це дійсно, але tabindex можна застосовувати лише до області, області, кнопки, вводу, об'єкта, вибору та текстової області. Але спробуйте.


1
У HTML5 tabindex- це "основний атрибут", який є "глобальними атрибутами" (атрибути, спільні для всіх елементів мови HTML). Дивіться w3.org/TR/2011/WD-html-markup-20110113/global-attributes.html
Oriol


0

Ви не можете зосередитися на діві. Ви можете зосередитись лише на вхідному елементі в цьому розділі. Також вам потрібно використовувати element.focus () замість display ()


1
Ви можете зробити <div>фокусируваний, якщо використовуєте tabindexатрибут. Дивіться dev.w3.org/html5/spec-author-view/editing.html#attr-tabindex
Oriol

0

Після багато чого озирнувшись, ось що нарешті для мене спрацювало:

  1. Знайдіть / знайдіть div у своєму будинку, у якому є смуга прокрутки. Для мене це виглядало так: "div class =" table_body table_body_div "scroll_top =" 0 "scroll_left =" 0 "style =" width: 1263px; висота: 499 пікселів; "

  2. Я знаходив його за допомогою цього xpath: // div [@ class = 'table_body table_body_div']

  3. Використовується JavaScript для виконання прокрутки так: (JavascriptExecutor) драйвер) .executeScript ("аргументи [0] .scrollLeft = аргументи [1];", елемент, 2000);

2000 - це кількість пікселів, яку я хотів прокрутити вправо. Використовуйте scrollTop замість scrollLeft, якщо ви хочете прокрутити свій div вниз.

Примітка. Я спробував використовувати scrollIntoView, але він не працював належним чином, оскільки на моїй веб-сторінці було кілька дівок. Він буде працювати, якщо у вас є лише одне головне вікно, на якому лежить фокус. Це найкраще рішення, з яким я зіткнувся, якщо ви не хочете використовувати jQuery, якого я не хотів.


0

Метод, який я часто використовую для прокрутки контейнера до його вмісту.

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

якщо ваш бажання перемогти в усьому світі, ви також можете зробити:

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

Через поведінку "гладка" не працює в Safari, Safari ios, Explorer. Зазвичай я записую просту функцію, використовуючи 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

Якщо ви хочете використовувати html, ви можете просто скористатися цим:

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

і зробіть його HTML-посиланням на конкретний ідентифікатор елемента. Його в основному getElementByIdhtml-версія.


-3

спробуйте цю функцію

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

Передайте ідентифікатор div як параметр, він буде працювати, я його вже використовую


з якої бібліотеки $j?
EoghanM

Я припускаю, що $ j посилається jQuery - у питанні зазначено, що він потребує Javascript.
Cameron W.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.