Как отключить якорный «прыжок» при загрузке страницы? - PullRequest
98 голосов
/ 07 сентября 2010

Я думаю, что это не возможно, постараюсь объяснить как можно лучше.У меня есть страница, содержащая вкладки (с поддержкой jquery), которые управляются следующим образом:

Я использую этот код, предоставленный другим пользователем из предыдущего вопроса.

<script type="text/javascript">
    $(function() {

     $('html, body').animate({scrollTop:0}); // this is my "fix"

        var tabContent = $(".tab_content");
        var tabs = $("#menu li");
        var hash = window.location.hash;
     tabContent.not(hash).hide();
        if(hash=="") {
      $('#tab1').fadeIn();
     }
        tabs.find('[href=' + hash + ']').parent().addClass('active');

        tabs.click(function() {
            $(this).addClass('active').siblings().removeClass('active');
            tabContent.hide();
            var activeTab = $(this).find("a").attr("href");

            $(activeTab).fadeIn();
           return false;
        });

    });
</script>

этот кодпрекрасно работает, когда я захожу на страницу «вкладок» напрямую.

однако мне нужно сослаться на отдельные вкладки с других страниц - поэтому для этого код получает window.location.hash, затем показывает соответствующую вкладку.

страница не «перепрыгивает» на привязку из-за «return false».

однако это событие вызывается только при событии щелчка.следовательно, если я захожу на мои «вкладки» с любой другой страницы, срабатывает эффект «прыжка».Чтобы бороться с этим, я автоматически прокручиваю до верхней части страницы, но я бы предпочел, чтобы этого не произошло.

есть ли способ имитировать «возврат ложного» при загрузке страницы, предотвращая «прыжок» привязкиот происходящего.

надеюсь, что это достаточно ясно.

спасибо

Ответы [ 16 ]

134 голосов
/ 07 сентября 2010

Не работает ли ваше исправление? Я не уверен, правильно ли я понял вопрос - у вас есть демо-страница? Вы можете попробовать:

if (location.hash) {
  setTimeout(function() {

    window.scrollTo(0, 0);
  }, 1);
}

Редактировать: протестировано и работает в Firefox, IE и Chrome в Windows.
Редактировать 2: переместить setTimeout() внутрь if блока, props @ vsync.

36 голосов
/ 23 апреля 2015

Смотрите мой ответ здесь: Ответ Stackoverflow

Хитрость заключается в том, чтобы просто удалить хештег как можно скорее и сохранить его значение для собственного использования:

Важно, чтобыВы не помещаете эту часть кода в функции $ () или $ (window) .load (), как это было бы поздно, и браузер уже перешел на тег.

// store the hash (DON'T put this code inside the $() function, it has to be executed 
// right away before the browser can start scrolling!
var target = window.location.hash,
    target = target.replace('#', '');

// delete hash so the page won't scroll to it
window.location.hash = "";

// now whenever you are ready do whatever you want
// (in this case I use jQuery to scroll to the tag after the page has loaded)
$(window).on('load', function() {
    if (target) {
        $('html, body').animate({
            scrollTop: $("#" + target).offset().top
        }, 700, 'swing', function () {});
    }
});
11 голосов
/ 12 ноября 2012

Я использовал решение dave1010, но оно было немного странным, когда я поместил его в функцию $ (). Ready.Итак, я сделал это: (не внутри $ (). Готов)

    if (location.hash) {               // do the test straight away
        window.scrollTo(0, 0);         // execute it straight away
        setTimeout(function() {
            window.scrollTo(0, 0);     // run it a bit later also for browser compatibility
        }, 1);
    }
11 голосов
/ 07 сентября 2010

Существуют и другие способы отслеживания того, на какой вкладке вы находитесь; возможно установление файла cookie или значения в скрытом поле и т. д. и т. д.

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

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

Надеюсь, это поможет.

9 голосов
/ 30 июля 2013
  1. Браузер переходит на <element id="abc" />, если в адресе есть хэш http://site.com/#abc и элемент с id = "abc" виден.Итак, вы просто должны скрыть элемент по умолчанию: <element id="anchor" style="display: none" />.Если на странице нет видимого элемента с хешем id =, браузер не будет прыгать.

  2. Создать скрипт, который проверяет хеш в URL, а затем находит и показывает элемент prrpopriate(по умолчанию это скрыто).

  3. Отключить поведение «хеш-подобной ссылки» по умолчанию, привязав событие onclick к ссылке и указав return false; в результате события onclick.

Когда я реализовал вкладки, я написал что-то вроде этого:

    <script>
    $(function () {         
        if (location.hash != "") {
            selectPersonalTab(location.hash);
        }
        else {
            selectPersonalTab("#cards");
        }
    });

    function selectPersonalTab(hash) {
        $("#personal li").removeClass("active");
        $("a[href$=" + hash + "]").closest("li").addClass("active");
        $("#personaldata > div").hide();
        location.hash = hash;
        $(hash).show();
    }

    $("#personal li a").click(function (e) {
        var t = e.target;
        if (t.href.indexOf("#") != -1) {
            var hash = t.href.substr(t.href.indexOf("#"));
            selectPersonalTab(hash);
            return false;
        }
    });
</script>
3 голосов
/ 31 августа 2016

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

/**
 * Prevent automatic scrolling of page to anchor by browser after loading of page.
 * Do not call this function in $(...) or $(window).on('load', ...),
 * it should be called earlier, as soon as possible.
 */
function preventAnchorScroll() {
    var scrollToTop = function () {
        $(window).scrollTop(0);
    };
    if (window.location.hash) {
        // handler is executed at most once
        $(window).one('scroll', scrollToTop);
    }

    // make sure to release scroll 1 second after document readiness
    // to avoid negative UX
    $(function () {
        setTimeout(
            function () {
                $(window).off('scroll', scrollToTop);
            },
            1000
        );
    });
}
3 голосов
/ 23 ноября 2015

Исправлен только грязный CSS, чтобы оставаться прокручиваемым при каждом использовании привязки (бесполезно, если вы все еще хотите использовать привязки для переходов по прокрутке, очень полезно для глубоких ссылок):

.elementsWithAnchorIds::before {
   content: "";
   display: block;
   height: 9999px;
   margin-top: -9999px; //higher thin page height
}
2 голосов
/ 06 января 2019

В моем случае из-за использования якорной ссылки для всплывающего окна CSS я использовал этот способ:

Просто сохраните страницу YOffset первым делом при нажатии, а затем установите ScrollTop на это:

$(document).on('click','yourtarget',function(){
        var st=window.pageYOffset;
        $('html, body').animate({
                'scrollTop' : st
            });
});
2 голосов
/ 17 октября 2015

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

 window.scrollTo(0, 0);

Что может сильно отвлекать пользователя.

Решение, на котором я остановился в конце концов, на самом деле довольно простое, и оно заключается в использовании идентификатора, отличного от идентификатора, используемого в location.hash

Например:

Вот ссылка на другую страницу

<a href="/page/with/tabs#tab2">Some info found in tab2 on tabs page</a>

Так что, конечно, если на странице вкладок есть элемент с идентификатором tab2, окно перейдет к нему при загрузке.

Таким образом, вы можете добавить что-то к идентификатору, чтобы предотвратить это:

<div id="tab2-noScroll">tab2 content</div>

И тогда вы можете добавить "-noScroll" к location.hash в javascript:

<script type="text/javascript">
    $(function() {

        var tabContent = $(".tab_content");
        var tabs = $("#menu li");
        var hash = window.location.hash;


     tabContent.not(hash + '-noScroll').hide();                           
        if(hash=="") {       //^ here
      $('#tab1-noScroll').fadeIn();
     }
        tabs.find('[href=' + hash + ']').parent().addClass('active');

        tabs.click(function() {
            $(this).addClass('active').siblings().removeClass('active');
            tabContent.hide();
            var activeTab = $(this).find("a").attr("href") + '-noScroll'; 
                                                               //^ and here

            $(activeTab).fadeIn();
           return false;
        });

    });
</script>
1 голос
/ 09 февраля 2011

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

    $( ".tabs" ).tabs();
    $( ".tabs" ).not(".noHash").bind("tabsshow", function(event, ui) { 
        window.location.hash = "tab_"+ui.tab.hash.replace(/#/,"");
        return false;
    });

    var selectedTabHash = window.location.hash.replace(/tab_/,"");
    var index = $( ".tabs li a" ).index($(".tabs li a[href='"+selectedTabHash+"']"));
    $( ".tabs" ).not(".noHash").tabs('select', index);

Все в пределах готового события. Он добавляет "tab_" для хеша, но работает как при нажатии, так и при загрузке страницы с хешем.

...