Как отключить якорь "прыжок" при загрузке страницы?
Я думаю, что это может быть невозможно, постараюсь объяснить как можно лучше. У меня есть страница, содержащая вкладки (jQuery powered), управляемые следующим образом:
Я использую этот код, как указано другим пользователем из предыдущего вопроса.
<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".
это событие запускается только на событие щелчка, однако. следовательно, если я посещаю свои "вкладки" с любой другой страницы, срабатывает эффект "прыжок". Для борьбы с этим я автоматически прокручиваю до верхней части страницы, но я бы предпочел, чтобы этого не произошло.
есть ли способ имитировать "возврат false" при загрузке страницы, предотвращая якорный "прыжок" от возникновения.
надеюсь, что это достаточно ясно.
спасибо
14 ответов:
ваше исправление не работает? Я не уверен, что правильно понял вопрос - у вас есть демо-страница? Вы можете попробовать:
if (location.hash) { setTimeout(function() { window.scrollTo(0, 0); }, 1); }
Edit: протестировано и работает в Firefox, IE и Chrome на Windows.
Правка 2: перемещениеsetTimeout()
внутриif
блок, реквизит @vsync.
смотрите мой ответ здесь: Stackoverflow Ответ
хитрость заключается в том, чтобы просто удалить хэштег как можно скорее и сохранить его значение для вашего собственного использования:
важно, чтобы вы не помещали эту часть кода в окно $() или $().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 () {}); } });
есть и другие способы отслеживания того, на какой вкладке вы находитесь; возможно, установка файла cookie или значения в скрытом поле и т. д. и т. д.
Я бы сказал, что если вы не хотите, чтобы страница прыгала при загрузке, вам было бы лучше использовать один из этих других вариантов, а не хэш, потому что основная причина использования хэша в предпочтении к ним-разрешить именно то, что вы хотите заблокировать.
еще один момент - страница не будет прыгать, если ваш хэш-ссылки не совпадают с именами теги в документе, поэтому, возможно, если вы хотите продолжать использовать хэш, вы можете манипулировать содержимым, чтобы теги назывались по-разному. Если вы используете последовательный префикс, вы все равно сможете использовать Javascript для перехода между ними.
надеюсь, что это поможет.
я использовал решение dave1010, но это было немного нервным, когда я положил его в $().готовая функция. Поэтому я сделал это: (не внутри $().готов)
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); }
браузер переходит к
<element id="abc" />
если есть http://site.com/#abc хэш в поле адреса и элемент с ID="ABC" является видимым. Итак, вы просто должны скрыть элемент по умолчанию:<element id="anchor" style="display: none" />
. Если на странице нет видимого элемента с id=hash, браузер не будет прыгать.создайте скрипт, который проверяет хэш в url, а затем находит и показывает элемент prrpopriate (который скрыт неисполнение.)
отключите поведение "хэш-подобной ссылки" по умолчанию, привязав событие 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>
грязный CSS только исправить, чтобы оставаться прокручивается каждый раз, когда якорь используется (не полезно, если вы все еще хотите использовать якоря для прокрутки прыжков, очень полезно для deeplinking):
.elementsWithAnchorIds::before { content: ""; display: block; height: 9999px; margin-top: -9999px; //higher thin page height }
ни один из ответов не работает достаточно хорошо для меня, я вижу, что страница прыгает на якорь, а затем на вершину для некоторых решений, некоторые ответы вообще не работают, могут быть вещи изменены в течение многих лет. Надеюсь, моя функция поможет кому-то.
/** * 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 ); }); }
хотя принятый ответ работает хорошо, я обнаружил, что иногда, особенно на страницах, содержащих большие изображения, полоса прокрутки будет прыгать дико, используя
window.scrollTo(0, 0);
который может быть довольно отвлекающим для пользователя.
решение, на котором я остановился в конце концов, на самом деле довольно простое, и это использовать другой идентификатор на цели к тому, который используется в
location.hash
например:
вот ссылка на некоторые другие страница
<a href="/page/with/tabs#tab2">Some info found in tab2 on tabs page</a>
так что, конечно, если есть элемент с идентификатором
tab2
на странице вкладки окно перейдет к нему при загрузке.так что вы можете добавить что-то к ID, чтобы предотвратить это:
<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>
Я думаю, что нашел способ для вкладок пользовательского интерфейса без повторного использования функциональности. До сих пор я не нашел никаких проблем.
$( ".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);
все внутри события ready. Он добавляет "tab_" для хэша, но работает как при нажатии, так и при загрузке страницы с хэшем.
другой подход
попробуйте проверить, если страница была прокручена и только потом сбросить установки:
var scrolled = false; $(window).scroll(function(){ scrolled = true; }); if ( window.location.hash && scrolled ) { $(window).scrollTop( 0 ); }
Я не имел большого успеха с выше
setTimeout
методы в Firefox.вместо setTimeout, я использовал функцию onload:
window.onload = function () { if (location.hash) { window.scrollTo(0, 0); } };
это все еще очень Глюк, к сожалению.
у меня не было никакого последовательного успеха с этими решениями.
видимо из-за того, что скачок происходит до Javascript => ссылка(http://forum.jquery.com/topic/preventing-anchor-jump)
мое решение состоит в том, чтобы расположить все якоря в верхней части по умолчанию с помощью CSS.
.scroll-target{position:fixed;top:0;left:0;}
затем используйте jquery для прокрутки до родителя целевого якоря или брата(возможно, пустой тег em)
<a class="scroll-target" name="section3"></a><em> </em>
пример jQuery для прокрутка для того, когда URL вводится с хэшем
(страница не должна быть уже загружена в разделе окна, это касается одной из других внешних источников)setTimeout(function() { if (window.location.hash) { var hash = window.location.hash.substr(1); var scrollPos = $('.scroll-target[name="'+hash+'"]').siblings('em').offset().top; $("html, body").animate({ scrollTop: scrollPos }, 1000); } }, 1);
кроме того, вы хотите, чтобы предотвратить по умолчанию для якорных кликов в то время как на странице, а затем прокрутите до своих целей
<a class="scroll-to" href="#section3">section three</a>
и jquery
$('a.scroll-to').click(function(){ var target = $(this).attr('href').substr(1); var scrollPos = $('.scroll-target[name="'+target+'"]').siblings('em').offset().top; $("html, body").animate({ scrollTop: scrollPos }, 1000); return false; });
хорошая вещь об этом методе-это цели тега привязки, остающиеся структурно рядом с соответствующим контентом, хотя их позиция CSS находится на верхний.
Это должно означать, что поисковые роботы не будут иметь проблемы.
Ура, я надеюсь, что это поможет
серый
попробуйте это, чтобы предотвратить клиента от любого вида вертикальной прокрутки на hashchanged (внутри обработчика событий):
var sct = document.body.scrollTop; document.location.hash = '#next'; // or other manipulation document.body.scrollTop = sct;
(браузер перерисовывать)
решил мой промлем, сделав это:
// navbar height var navHeigth = $('nav.navbar').height(); // Scroll to anchor function var scrollToAnchor = function(hash) { // If got a hash if (hash) { // Scroll to the top (prevention for Chrome) window.scrollTo(0, 0); // Anchor element var term = $(hash); // If element with hash id is defined if (term) { // Get top offset, including header height var scrollto = term.offset().top - navHeigth; // Capture id value var id = term.attr('id'); // Capture name value var name = term.attr('name'); // Remove attributes for FF scroll prevention term.removeAttr('id').removeAttr('name'); // Scroll to element $('html, body').animate({scrollTop:scrollto}, 0); // Returning id and name after .5sec for the next scroll setTimeout(function() { term.attr('id', id).attr('name', name); }, 500); } } }; // if we are opening the page by url if (location.hash) { scrollToAnchor(location.hash); } // preventing default click on links with an anchor $('a[href*="#"]').click(function(e) { e.preventDefault(); // hash value var hash = this.href.substr(this.href.indexOf("#")); scrollToAnchor(hash); });`