Подтвердить что ты не робот

ScrollIntoView() вызывает перемещение всей страницы

Я использую ScrollIntoView() для прокрутки выделенного элемента в списке в представлении. Когда я прокручиваю вниз, ScrollIntoView (false) работает отлично. Но когда я прокручиваю вверх, ScrollIntoView (true) вызывает перемещение всей страницы, которая, как мне кажется, предназначена. Есть ли способ избежать перемещения всей страницы при использовании ScrollIntoView (true)?

Вот структура моей страницы -

#listOfDivs {
  position:fixed;
  top:100px;
  width: 300px;
  height: 300px;
  overflow-y: scroll;
}

<div="container">
    <div="content"> 
         <div id="listOfDivs"> 
             <div id="item1"> </div>
             <div id="item2"> </div>
             <div id="itemn"> </div>
         </div>
    </div>
</div>

listOfDivs происходит от вызова ajax. Использование мобильного сафари.

Спасибо за вашу помощь заранее!

4b9b3361

Ответ 1

Вы можете использовать scrollTop вместо scrollIntoView():

var target = document.getElementById("target");
target.parentNode.scrollTop = target.offsetTop;

jsFiddle: http://jsfiddle.net/LEqjm/

Если имеется более одного прокручиваемого элемента, который вы хотите прокрутить, вам нужно изменить scrollTop каждого отдельно, на основе offsetTop промежуточных элементов. Это должно дать вам мелкомасштабный контроль, чтобы избежать проблем, которые у вас есть.

EDIT: offsetTop необязательно относится к родительскому элементу - по отношению к первому позиционированному предку. Если родительский элемент не расположен (относительный, абсолютный или фиксированный), вам может потребоваться изменить вторую строку на:

target.parentNode.scrollTop = target.offsetTop - target.parentNode.offsetTop;

Ответ 3

Плагин jQuery scrollintoview() увеличивает удобство использования

Вместо реализации DOM по умолчанию вы можете использовать плагин, который оживляет движение и не имеет каких-либо нежелательных эффектов. Здесь простейший способ использовать его со значениями по умолчанию:

$("yourTargetLiSelector").scrollintoview();

В любом случае, переходите к этому сообщению , где вы можете прочитать все подробности и в конечном итоге вы получите исходный код GitHub плагина.

Этот плагин автоматически ищет ближайший прокручиваемый элемент предка и прокручивает его так, чтобы выбранный элемент находился внутри видимого порта представления. Если элемент уже находится в порт представления, он ничего не делает.

Ответ 4

Играйте с scrollIntoViewIfNeeded()... убедитесь, что он поддерживается браузером.

Ответ 5

Я добавил способ отображения впечатляющего поведения ScrollIntoView - http://jsfiddle.net/LEqjm/258/ [это должен быть комментарий, но у меня недостаточно репутации)

$("ul").click(function() {
    var target = document.getElementById("target");
if ($('#scrollTop').attr('checked')) {
    target.parentNode.scrollTop = target.offsetTop;    
} else {
        target.scrollIntoView(!0);
}
});

Ответ 6

var el = document.querySelector("yourElement");
window.scroll({top: el.offsetTop, behavior: 'smooth'});

Ответ 7

У меня тоже была эта проблема, и я потратил много часов, пытаясь справиться с этим. Надеюсь, мое решение может помочь некоторым людям.

Мое исправление оказалось:

  • Для Chrome: изменение .scrollIntoView() на .scrollIntoView({block: 'nearest'}) (спасибо @jfrohn).
  • Для Firefox: применить overflow: -moz-hidden-unscrollable; на элемент контейнера, который сдвигается.
  • Не тестировалось в других браузерах.

Ответ 8

У меня была та же проблема, я исправил ее, удалив transform:translateY CSS i, помещенный на footer страницы.

Ответ 9

Используя блестящую идею, здесь решение, которое только (по вертикали) прокручивается, если элемент НЕ отображается в настоящее время. Идея состоит в том, чтобы получить ограничивающий прямоугольник окна просмотра и элемент, который будет отображаться в пространстве координат окна браузера. Проверьте, видимо ли это, а если нет, прокрутите требуемое расстояние, чтобы элемент отображался в верхней или нижней части окна просмотра.

    function ensure_visible(element_id)
    {
        // adjust these two to match your HTML hierarchy
        var element_to_show  = document.getElementById(element_id);
        var scrolling_parent = element_to_show.parentElement;

        var top = parseInt(scrolling_parent.getBoundingClientRect().top);
        var bot = parseInt(scrolling_parent.getBoundingClientRect().bottom);

        var now_top = parseInt(element_to_show.getBoundingClientRect().top);
        var now_bot = parseInt(element_to_show.getBoundingClientRect().bottom);

        // console.log("Element: "+now_top+";"+(now_bot)+" Viewport:"+top+";"+(bot) );

        var scroll_by = 0;
        if(now_top < top)
            scroll_by = -(top - now_top);
        else if(now_bot > bot)
            scroll_by = now_bot - bot;
        if(scroll_by != 0)
        {
            scrolling_parent.scrollTop += scroll_by; // tr.offsetTop;
        }
    }

Ответ 10

Добавление дополнительной информации к посту @Jesco.

  • Element.scrollIntoViewIfNeeded() non-standard WebKit method для браузеров Chrome, Opera, Safari.
    Если элемент уже находится в видимой области окна браузера, прокрутка не происходит.
  • Метод Element.scrollIntoView() прокручивает элемент, с которым он вызван, в видимую область окна браузера.

Попробуйте приведенный ниже код в scrollIntoView() на mozilla.org. Опубликовать для идентификации браузера

var xpath = '//*[@id="Notes"]';
ScrollToElement(xpath);

function ScrollToElement(xpath) {
    var ele = $x(xpath)[0];
    console.log( ele );

    var isChrome = !!window.chrome && (!!window.chrome.webstore || !!window.chrome.runtime);
    if (isChrome) { // Chrome
        ele.scrollIntoViewIfNeeded();
    } else {
        var inlineCenter = { behavior: 'smooth', block: 'center', inline: 'start' };
        ele.scrollIntoView(inlineCenter);
    }
}

Ответ 11

Я также столкнулся с этой проблемой, и она работала нормально для меня. Рассмотрим listOfDivs как родительский ref, а item как дочерний ref. Передайте его как параметр функции, которую я написал, она будет работать без проблем.https://medium.com/@vigu_madurai/solved-alternate-to-the-default-scrollintoview-8da76e083066?sk=89ac693c8e8140c71c8a53147bf3ccf6

Ответ 12

Я также столкнулся с этой проблемой, и она работала нормально для меня. Рассмотрим listOfDivs как родительский ref, а item как дочерний ref. Передайте его в качестве параметра функции, которую я опубликовал на моем носителе, она наверняка сработает.