加载页面时如何禁用锚点“跳转”?
我想这可能是不可能的,会尽我所能地尽力解释。 我有一个页面包含选项卡(由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
然后显示适当的选项卡。
由于“返回false”,页面不会“跳转”到锚点。
这个事件只是在一个点击事件触发。 因此,如果我从任何其他页面访问我的“标签”,则会触发“跳转”效果。 为了解决这个问题,我自动滚动到页面的顶部,但我宁愿这没有发生。
有没有什么办法可以在页面加载的时候模拟“返回false”,从而防止锚点发生跳转。
希望这已经够清楚了。
谢谢
你的修补程序不工作? 我不确定是否正确理解这个问题 – 你有一个演示页面吗? 你可以尝试:
if (location.hash) { setTimeout(function() { window.scrollTo(0, 0); }, 1); }
编辑:testing和工作在Windows,Firefox和IE浏览器。
编辑2:移动setTimeout()
, if
block,props @vsync。
看到我的答案在这里: Stackoverflow答案
诀窍是尽快删除hashtag并存储它自己的价值:
重要的是,不要将这部分代码放在$()或$(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 () {}); } });
还有其他的方式来跟踪你的标签。 也许设置一个cookie或一个隐藏字段中的值等
我会说,如果你不希望页面跳跃加载,你最好使用其他选项之一,而不是散列,因为使用散列优先于他们的主要原因是准确地让你想要阻止。
另一点 – 如果你的哈希链接不匹配文档中的标签名称,页面将不会跳转,所以如果你想继续使用哈希,你可以操纵内容,这样标签的命名就不一样了。 如果你使用一致的前缀,你仍然可以使用Javascript来跳转。
希望有所帮助。
-
如果地址中存在http://site.com/#abc散列并且id =“abc”的元素可见,则浏览器跳转到
<element id="abc" />
。 所以,你应该默认隐藏元素:<element id="anchor" style="display: none" />
。 如果在页面上没有id = hash的可见元素,浏览器将不会跳转。 -
创build一个脚本,检查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>
我使用了dave1010的解决scheme,但是当我将它放在$()。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); }
虽然接受的答案确实运行良好,但我确实发现,有时候,特别是在包含大图像的页面上,滚动条会大量跳跃
window.scrollTo(0, 0);
这可能会让使用者感到分心。
我最终解决的解决scheme其实很简单,就是在目标上使用一个不同的ID到location.hash
使用的ID
例如:
这是其他网页上的链接
<a href="/page/with/tabs#tab2">Some info found in tab2 on tabs page</a>
所以当然,如果在标签页上有一个ID为tab2
的元素,窗口会在加载时跳转到它。
所以你可以附加一些东西来防止它:
<div id="tab2-noScroll">tab2 content</div>
然后你可以在javascript中添加"-noScroll"
到location.hash
:
<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>
肮脏的CSS只能修复每当锚点使用时保持滚动(如果您仍然想使用锚点进行滚动跳转,对于深度链接非常有用,则无用):
.elementsWithAnchorIds::before { content: ""; display: block; height: 9999px; margin-top: -9999px; //higher thin page height }
我想我已经find了一个UI标签的方式,而不用重做function。 到目前为止,我还没有发现任何问题。
$( ".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_”作为散列,但在单击和加载散列的页面时都可以工作。
另一种方法
尝试检查页面是否被滚动,然后重置位置:
var scrolled = false; $(window).scroll(function(){ scrolled = true; }); if ( window.location.hash && scrolled ) { $(window).scrollTop( 0 ); }
下面是一个演示
在Firefox上面的setTimeout
方法我没有太多的成功。
我使用了一个onload函数,而不是setTimeout:
window.onload = function () { if (location.hash) { window.scrollTo(0, 0); } };
不幸的是,它仍然非常糟糕。
这些解决scheme我没有取得任何一致的成功。
显然是由于跳转发生在Javascript =>引用之前( http://forum.jquery.com/topic/preventing-anchor-jump )
我的解决scheme是默认使用CSS定位所有锚点。
.scroll-target{position:fixed;top:0;left:0;}
然后使用jquery滚动到目标锚的父项,或兄弟(也许是一个空的电子标签)
<a class="scroll-target" name="section3"></a><em> </em>
使用哈希inputURL时滚动的jquery示例
(页面不能已经加载在窗口/标签,这涵盖来自其他/外部来源的链接)
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位置在顶部。
这应该意味着search引擎爬虫不会有问题。
干杯,我希望这有助于
灰色
试试这样做,以防止客户端在hashchanged(在您的事件处理程序中)上进行任何types的垂直滚动:
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); });`
没有一个答案对我来说不够好,我看到页面跳到锚点,然后到一些解决scheme的顶部,有些答案根本不起作用,可能会改变多年。 希望我的function对别人有帮助。
/** * Prevent automatic scrolling of page to anchor by browser after loading of page. * Do not call this function in $(document).ready(...) or $(window).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 $(document).ready(function () { setTimeout( function () { $(window).off('scroll', scrollToTop); }, 1000 ); }); }