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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3659072/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 15:51:11  来源:igfitidea点击:

How to disable anchor "jump" when loading a page?

jquerytabshref

提问by Ross

I think this may not be possible, will try and explain as best as I can. I have a page containing tabs (jquery powered), controlled by the following:

我认为这可能是不可能的,我会尽力解释。我有一个包含选项卡(jquery 驱动)的页面,由以下控制:

I'm using this code, as provided by another user from a previous question.

我正在使用此代码,由上一个问题的另一个用户提供。

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

this code works great when I visit the "tabs" page directly.

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

however, I need to link to invidual tabs from other pages - so to do this, the code gets the window.location.hashthen shows the appropiate tab.

但是,我需要从其他页面链接到单个选项卡 - 为此,代码获取window.location.hash然后显示适当的选项卡。

the page doesn't "jump" to the anchor because of "return false".

由于“返回假”,页面不会“跳转”到锚点。

this event is only triggered on a click event however. hence, if i visit my "tabs" from any other page, the "jump" effect is triggered. To combat this I automatically scroll to teh top of the page, but I would rather this didn't happen.

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

is there any way to simulate "return false" when the page loads, preventing the anchor "jump" from occuring.

有什么方法可以在页面加载时模拟“返回假”,防止发生锚点“跳转”。

hope this is clear enough.

希望这足够清楚。

thanks

谢谢

回答by dave1010

Does your fix not work? I'm not sure if I understand the question correctly - do you have a demo page? You could try:

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

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

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

Edit: tested and works in Firefox, IE & Chrome on Windows.
Edit 2: move setTimeout()inside ifblock, props @vsync.

编辑:在 Windows 上的 Firefox、IE 和 Chrome 中测试和工作。
编辑 2:setTimeout()if块内移动,道具 @vsync。

回答by Larzan

See my answer here: Stackoverflow Answer

在此处查看我的答案:Stackoverflow 答案

The trick is to just remove the hashtag ASAP and store its value for your own use:

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

It is important that you do not put that part of the code in the $() or $(window).load() functions as it would be too late and the browser already has moved to the tag.

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

回答by Spudley

There are other ways of tracking what tab you're on; perhaps setting a cookie, or a value in a hidden field, etc etc.

还有其他方法可以跟踪您所在的选项卡;也许设置 cookie,或隐藏字段中的值等。

I would say that if you don't want the page jumping on load, you would be better off using one of these other options rather than the hash, because the main reason for using the hash in preference to them is to allow exactly what you're wanting to block.

我会说,如果您不希望页面在加载时跳转,那么最好使用这些其他选项之一而不是散列,因为优先使用散列的主要原因是允许您使用想阻止。

Another point - the page won't jump if your hash links don't match the names of the tags in the document, so perhaps if you want to keep using the hash you could manipulate the content so that the tags are named differently. If you use a consistent prefix, you will still be able to use Javascript to jump between then.

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

Hope that helps.

希望有帮助。

回答by lopsided

I used dave1010's solution, but it was a bit jumpy when I put it inside the $().ready function. So I did this: (not inside the $().ready)

我使用了 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);
    }

回答by Sergei Smirnov

  1. Browser jumps to <element id="abc" />if there are http://site.com/#abchash in the address and the element with id="abc" is visible. So, you just should hide the element by default: <element id="anchor" style="display: none" />. If there is no visible element with id=hash at the page, the browser would not jump.

  2. Create a script that checks the hash in url, and then finds and shows the prrpopriate element (that is hidden by default).

  3. Disable default "hash-like link" behaviour by binding an onclick event to a link and specify return false;as a result of onclick event.

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

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

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

When I implemented tabs, I wrote something like that:

当我实现标签时,我写了这样的东西:

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

回答by kdmitry

None of answers do not work good enough for me, I see page jumping to anchor and then to top for some solutions, some answers do not work at all, may be things changed for years. Hope my function will help to someone.

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

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

回答by anotheryou

dirty CSS only fix to stay scrolled up every time the anchor is used (not useful if you still want to use anchors for scroll-jumps, very useful for deeplinking):

脏 CSS 仅修复每次使用锚点时保持向上滚动(如果您仍然想使用锚点进行滚动跳转,则没有用,对于深层链接非常有用):

.elementsWithAnchorIds::before {
   content: "";
   display: block;
   height: 9999px;
   margin-top: -9999px; //higher thin page height
}

回答by andrew

While the accepted answer does work well, I did find that sometimes, especially on pages containing large images that the scroll bar will jump about wildly using

虽然接受的答案效果很好,但我确实发现有时,尤其是在包含滚动条会疯狂使用的大图像的页面上

 window.scrollTo(0, 0);

Which can be quite distracting for the user.

这可能会让用户分心。

The solution I settled on in the end is actually pretty simple, and that's to use a different ID on the target to the one used in location.hash

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

Eg:

例如:

Here is the link on some other page

这是其他页面上的链接

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

So of course if there is an element with an ID of tab2on the tabs page the window will jump to it on load.

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

So you can append something to the ID to prevent it:

所以你可以在 ID 上附加一些东西来防止它:

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

And then you can append "-noScroll"to location.hashin the javascript:

然后你可以在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>

回答by Metro Polisue

In my case because of using anchor link for CSS popup I've used this way:

在我的情况下,因为使用锚链接 CSS 弹出我用这种方式:

Just save the pageYOffset first thing on click and then set the ScrollTop to that:

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

$(document).on('click','yourtarget',function(){
        var st=window.pageYOffset;
        $('html, body').animate({
                'scrollTop' : st
            });
});

回答by Lasithds

This will work with bootstrap v3

这将适用于引导程序 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>