如何在加载页面时禁用锚点“跳转”?

时间:2010-09-07 13:31:53

标签: jquery tabs href

我认为这可能是不可能的,我会尽力解释。 我有一个包含选项卡(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>

当我直接访问“标签页”时,此代码效果很好。

但是,我需要链接到其他页面的invidual标签 - 为此,代码获取window.location.hash然后显示适当的标签。

由于“return false”,页面不会“跳转”到锚点。

此事件仅在点击事件中触发。因此,如果我从任何其他页面访问我的“标签”,则会触发“跳转”效果。为了解决这个问题,我会自动滚动到页面顶部,但我宁愿这不会发生。

有没有办法在页面加载时模拟“return false”,防止锚点“跳”出现。

希望这很清楚。

感谢

15 个答案:

答案 0 :(得分:133)

你的修复不起作用吗?我不确定我是否正确理解了这个问题 - 你有一个演示页吗?你可以尝试:

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

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

编辑:测试并在Firefox,IE和&amp; Windows上的Chrome。
编辑2:在setTimeout()块内移动if,道具@vsync。

答案 1 :(得分:35)

请在此处查看我的回答:Stackoverflow Answer

诀窍是只删除主题标签ASAP并存储其值供您自己使用:

重要的是,不要将代码的那部分放在$()或$(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 () {});
    }
});

答案 2 :(得分:11)

还有其他方法可以跟踪您所使用的标签;也许设置一个cookie,或隐藏字段中的值等等。

我想说如果你不希望页面在加载时跳转,你最好使用其中一个选项而不是哈希,因为使用哈希优先于它们的主要原因是允许正是你想要阻止的东西。

另一点 - 如果您的哈希链接与文档中的标记名称不匹配,页面将不会跳转,因此,如果您想继续使用哈希,您可以操纵内容以便标记被命名不同。如果你使用一致的前缀,你仍然可以使用Javascript在那之间跳转。

希望有所帮助。

答案 3 :(得分:11)

我使用了dave1010的解决方案,但当我把它放在$()。ready函数中时,它有点跳跃。所以我这样做了:(不在$()。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);
    }

答案 4 :(得分:9)

  1. 如果地址中有http://site.com/#abc哈希值,则浏览器会跳转到<element id="abc" />,并且可以看到id =“abc”的元素。因此,您应该默认隐藏元素:<element id="anchor" style="display: none" />。 如果页面上没有id = hash的可见元素,则浏览器不会跳转。

  2. 创建一个脚本,检查url中的哈希值,然后查找并显示prrpopriate元素(默认情况下隐藏)。

  3. 通过将onclick事件绑定到链接来禁用默认的“类似哈希的链接”行为,并指定return false;作为onclick事件的结果。

  4. 当我实现标签时,我写了类似的东西:

        <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>
    

答案 5 :(得分:3)

没有一个答案对我来说不够好,我看到页面跳转到锚点,然后到顶部找到一些解决方案,一些答案根本不起作用,可能会改变多年。希望我的功能对某人有所帮助。

/**
 * 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
        );
    });
}

答案 6 :(得分:2)

虽然接受的答案确实有效,但我确实发现有时候,特别是在包含大图像的页面上,滚动条会疯狂地跳转使用

 window.scrollTo(0, 0);

这对用户来说可能会让人分心。

我最终确定的解决方案实际上非常简单,并且要在目标上使用与location.hash中使用的ID不同的ID

例如:

以下是其他页面上的链接

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

当然,如果标签页上有一个ID为tab2的元素,那么窗口会在加载时跳转到它。

所以你可以在ID上添加一些内容来阻止它:

<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>

答案 7 :(得分:2)

在我的情况下,由于将锚定链接用于CSS弹出窗口,因此我使用了这种方式:

只需在单击时保存pageYOffset,然后将ScrollTop设置为:

aJsonString

答案 8 :(得分:1)

我认为我已经为UI标签找到了一种方法而无需重做功能。到目前为止,我还没有发现任何问题。

    $( ".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_”,但在点击和加载哈希页面时都可以使用。

答案 9 :(得分:0)

另一种方法

尝试检查页面是否已滚动,然后才重置位置:

var scrolled = false;

$(window).scroll(function(){
  scrolled = true;
});

if ( window.location.hash && scrolled ) {
  $(window).scrollTop( 0 );
}

Heres a demo

答案 10 :(得分:0)

我在Firefox中使用上述setTimeout方法并没有取得多大成功。

我没有使用setTimeout,而是使用了onload函数:

window.onload = function () {
    if (location.hash) {
        window.scrollTo(0, 0);
    }
};

不幸的是,它仍然非常小问题。

答案 11 :(得分:0)

我对这些解决方案没有取得任何成功。

显然是因为跳转发生在Javascript =&gt;之前。 参考(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>&nbsp</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位置在顶部。

这应该意味着搜索引擎爬虫不会有问题。

干杯,我希望这有助于格雷

答案 12 :(得分:0)

尝试这样做是为了防止客户端在hashchanged上进行任何类型的垂直滚动(在事件处理程序中):

var sct = document.body.scrollTop;
document.location.hash = '#next'; // or other manipulation
document.body.scrollTop = sct;

(浏览器重绘)

答案 13 :(得分:0)

通过这样做解决了我的问题:

// 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);
});`

答案 14 :(得分:0)

这将适用于Bootstrap v3

$(document).ready(function() {
  if ($('.nav-tabs').length) {
    var hash = window.location.hash;
    var hashEl = $('ul.nav a[href="' + hash + '"]');
    hash && hashEl.tab('show');

    $('.nav-tabs a').click(function(e) {
      e.preventDefault();
      $(this).tab('show');
      window.location.hash = this.hash;
    });

    // Change tab on hashchange
    window.addEventListener('hashchange', function() {
      var changedHash = window.location.hash;
      changedHash && $('ul.nav a[href="' + changedHash + '"]').tab('show');
    }, false);
  }
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/js/bootstrap.min.js"></script>
<div class="container">
<ul class="nav nav-tabs">
  <li class="active"><a data-toggle="tab" href="#home">Home</a></li>
  <li><a data-toggle="tab" href="#menu1">Menu 1</a></li>
</ul>

<div class="tab-content">
  <div id="home" class="tab-pane fade in active">
    <h3>HOME</h3>
    <p>Some content.</p>
  </div>
  <div id="menu1" class="tab-pane fade">
    <h3>Menu 1</h3>
    <p>Some content in menu 1.</p>
  </div>
</div>
</div>