Как прокрутить элемент с помощью JavaScript?


153

Я пытаюсь переместить страницу в <div>элемент.

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

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

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

Что за фокус? Тот же фокус, что и у вас, когда вы используете табуляцию элементов формы или фокус в смысле выделения элемента каким-либо образом? Единственное, что вы делаете, это отображаете элемент, который не имеет эффекта, если он уже отображается.
Феликс Клинг

Фокус как прокрутка в поле зрения?
epascarello

Ответы:


124

Вы можете использовать якорь, чтобы "сфокусировать" div. То есть:

<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". Я буду придерживаться решения без "#", которое работает для меня ... вау!
TimFoolery

1
Это не очень хорошо для меня, потому что добавляет все эти события навигации в историю браузера, и я не могу легко вернуться на предыдущую страницу
bikeman868

Я думаю, что «AnhSirk Dasarp» ниже - лучший способ прокрутки нужного элемента в верхней части видимого экрана.
Curious101

Что, если скроллер находится во внутреннем div?
Цянь Чен

241

scrollIntoView работает хорошо:

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

Полная ссылка в документах MDN:
https://developer.mozilla.org/en-US/docs/Web/API/Element.scrollIntoView


11
@CameronMcCluskie - это только странные «scrollIntoViewOptions» (плавная прокрутка и т. Д.), Которые имеют эксклюзивную поддержку Firefox. основное использование, которое я имею в своем ответе, должно работать почти на что угодно.
Schpet

4
Подтверждаю, что по состоянию на 16 апреля он работает также под Opera и Chrome.
lvr123

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

2
Работал в Firefox, Opera и Safari.
Джагдип Сингх

3
Вот еще один источник (caniuse) для совместимости браузераscrollIntoView
The Red Pea

100

Ваш вопрос и ответы выглядят иначе. Я не знаю, ошибаюсь ли я, но для тех, кто гуглит и достигает здесь, мой ответ будет следующим:

  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
Работая как очарование :)
Midzer

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); что работает со всеми
браузерами

Не поддерживается в 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 Да, это больше похоже на iOS-подобный код, где фактическое количество не имеет значения, так что вы можете пойти дальше и назвать все, что он делает / содержит. Я предпочитаю это, чем краткость.
Джери Борбас

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 и некоторых других браузерах. Работает ли с этим polyfill github.com/iamdustan/smoothscroll, хотя. ;)
Mhor Mé

2

Фокус может быть установлен только на интерактивные элементы ... Div только представляют логический раздел страницы.

Возможно, вы можете установить границы вокруг div или изменить его цвет, чтобы имитировать фокус. И да, Видимость не в фокусе.


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

Вы не можете сосредоточиться на div. Вы можете сосредоточиться только на элементе ввода в этом div. Также вам нужно использовать 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) driver) .executeScript ("arguments [0] .scrollLeft = arguments [1];", element, 2000);

2000 - это количество пикселей, которое я хотел прокрутить вправо. Используйте scrollTop вместо scrollLeft, если вы хотите прокрутить ваш div вниз.

Примечание. Я попытался использовать scrollIntoView, но он не работал должным образом, поскольку на моей веб-странице было несколько элементов div. Это будет работать, если у вас есть только одно главное окно, где находится фокус. Это лучшее решение, с которым я столкнулся, если вы не хотите использовать 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 id в качестве параметра, он будет работать, я уже его использую


из какой библиотеки $j?
EoghanM

Я предполагаю, что $ j ссылается на jQuery - в вопросе говорится, что ему нужен Javascript.
Кэмерон В.
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.