jQuery:调用 URL 时滚动到锚点,替换浏览器行为

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1903574/
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 12:22:31  来源:igfitidea点击:

jQuery: Scroll to anchor when calling URL, replace browsers behaviour

jqueryscrollanchorsmooth

提问by bj.

I already know the jQuery plugin ScrollTo, but I didn't find any way up to now to realize the following:

我已经知道 jQuery 插件 ScrollTo,但到目前为止我还没有找到任何方法来实现以下内容:

The users gets to my site (by typing, NOT by clicking a link on my page) domain.com/bla.php#foo

用户访问我的网站(通过键入,而不是通过单击我页面上的链接) domain.com/bla.php#foo

and the anchor "#foo" exists. Now I want that the browser of the user does NOT automatically scroll to "#foo", instead I want to smoothly scroll so that the element '#foo' is about in the middle of the view and NOT on the absolute top position of the users view.

并且存在锚点“#foo”。现在我希望用户的浏览器不会自动滚动到“#foo”,而是希望平滑滚动,以便元素“#foo”位于视图的中间,而不是位于视图的绝对顶部位置用户查看。

thanks so far!

到目前为止,谢谢!

回答by Jan Jongboom

If you don't create the actual anchor foo, but rather create your anchor with an id like _foo(something like <a id="_foo">). You can handle the $(document).readyto achieve this.

如果您不创建实际的 anchor foo,而是创建带有 id like _foo(类似于<a id="_foo">)的锚点。你可以处理$(document).ready来实现这一点。

Something like (pseudo code)

类似(伪代码)

$(document).ready(function() { 
    var elem = $('#_' + window.location.hash.replace('#', ''));
    if(elem) {
         $.scrollTo(elem.left, elem.top);
    }
});

回答by Viktor Stískala

I made some enhancement to script from Jan Jongboom so it now looks like this:

我对 Jan Jongboom 的脚本做了一些改进,现在看起来像这样:

$(document).ready(function () {
    // replace # with #_ in all links containing #
    $('a[href*=#]').each(function () {
        $(this).attr('href', $(this).attr('href').replace('#', '#_'));
    });

    // scrollTo if #_ found
    hashname = window.location.hash.replace('#_', '');
    // find element to scroll to (<a name=""> or anything with particular id)
    elem = $('a[name="' + hashname + '"],#' + hashname);

    if(elem) {
         $(document).scrollTo(elem, 800);
    }

});

It changes all anchors in links so for users without javascript the behaviour will remain untouched.

它会更改链接中的所有锚点,因此对于没有 javascript 的用户,行为将保持不变。

回答by ReLeaf

Machineghost's answer was very helpful. The code I patched together takes a URL param and turns it into a hash tag that the browser then scrolls to as soon as the DOM is ready.

Machineghost 的回答非常有帮助。我修补的代码接受一个 URL 参数并将其转换为一个哈希标签,浏览器会在 DOM 准备好后立即滚动到该标签。

The URL would look like this:

该 URL 将如下所示:

www.mysite.com/hello/world.htm?page=contact

Contact is the name of the ID you want to scroll to

联系人是您要滚动到的 ID 的名称

<h1 id="contact">Contact Us</h1>

Here's the code:

这是代码:

// Get any params from the URL
$.extend({
  getUrlVars: function(){
    var vars = [], hash;
    var url = decodeURIComponent(window.location.href);
    var hashes = url.slice(window.location.href.indexOf('?') + 1).split('&');
    for(var i = 0; i < hashes.length; i++)
    {
      hash = hashes[i].split('=');
      vars.push(hash[0]);
      vars[hash[0]] = hash[1];
    }
    return vars;
  },
  getUrlVar: function(name){
    return $.getUrlVars()[name];
 }
});

$(document).ready(function() {
    // Unhide the main content area
    $('section.centered').fadeIn('slow');

    // Create a var out of the URL param that we can scroll to
    var page = $.getUrlVar('page');
    var scrollElement = '#' + page;

    // Scroll down to the newly specified anchor point
    var destination = $(scrollElement).offset().top;
    $("html:not(:animated),body:not(:animated)").animate({ scrollTop: destination-75}, 800 );
    return false;
});

I checked this in Chrome and FF and it worked very well. Try adjusting "destination-75" if the scroll target isn't going to the exact place you want it to.

我在 Chrome 和 FF 中检查过这个,效果很好。如果滚动目标没有到达您想要的确切位置,请尝试调整“destination-75”。

I couldn't have done it with out the posts above, so thanks!

如果没有上面的帖子,我无法做到这一点,所以谢谢!

回答by Emilion

/* scrolling to element */
    var headerHeight = $('#header').height() + $('#header-bottom-cap').height() + 10; //When the header position is fixed
    $('a').click(function(){
        var hashEle = $(this).attr('href').split('#');
        if (hashEle.length > 1) {
            if (hashEle[1] == 'top') {
                $('body, html').animate({
                    scrollTop: 0
                },500);
            } else {
            jQuery('body, html').animate({
                scrollTop: $('#'+ hashEle[1]).offset().top - headerHeight
            },500);
            }
        };
    })
        // find element from url
hashname = window.location.hash.replace('#', '');
elem = $('#' + hashname);
if(hashname.length > 1) {
    if(hashname == 'top') {
    $('body, html').animate({
            scrollTop: 0
        },200); 
    } else {
     $('body, html').animate({
            scrollTop: $(elem).offset().top - headerHeight
        },500);
 }
};
/* END scrolling to element */

this script should be into $(document).ready(function() {});

这个脚本应该放入 $(document).ready(function() {});

回答by Silambarasan R.D

Try this Code is working for me perfectly only using jQuery.

试试这个代码只使用 jQuery 对我来说是完美的。

$(document).ready(function() {
    var target = window.location.hash;
    var offset = 85; // You can change this value as per your need.
    if ($(target).length > 0) {
        $('html, body').animate({
            scrollTop: $(target).offset().top - offset
        }, 1000);
    } else {
        console.warn('Element ' + target + ' does not exist');
    }
});

回答by Chris Williams

You can still use ScrollTo. You would want to render the page with no anchors in it and then use JavaScript that runs when the page is loaded to get the anchor from the URL. You can then use that text to scroll to a particular ID.

您仍然可以使用 ScrollTo。您可能希望呈现没有锚点的页面,然后使用在页面加载时运行的 JavaScript 从 URL 获取锚点。然后,您可以使用该文本滚动到特定 ID。

Not sure how to get the item in the middle of the page but you can specify an offset for the scrolling.

不确定如何获取页面中间的项目,但您可以为滚动指定偏移量。

回答by machineghost

I don't want to say that this is impossible, but ... it will at the very least be quite challenging. The browser (or at least all the ones I know of) scroll to the anchor point as soon as that part of the page loads; AFAIK there is no Javascript-based way to avoid that (you'd need a browser plug-in or something).

我不想说这是不可能的,但是……至少会很有挑战性。一旦页面的那部分加载,浏览器(或至少我知道的所有浏览器)就会滚动到锚点;AFAIK 没有基于 Javascript 的方法可以避免这种情况(您需要浏览器插件或其他东西)。

However, I think you might be able to use a variant of a "don't show the page until the page is fully loaded" script to potentially get the behavior you want. In other words, you would:

但是,我认为您可以使用“在页面完全加载之前不显示页面”脚本的变体来潜在地获得您想要的行为。换句话说,你会:

  1. Hide all of your page's content pre-load (ie. have a DIV that wraps your whole page, and put a "display:none" style on it)

  2. Attach an "onLoad" event handler to the page which un-hides your DIV, and ...

  3. In that same "onLoad" event handler, use a standard JS scrolling mechanism (ie.ScrollTo) to scroll to the anchor (I think you'll be able to determine which anchor to scroll to by checking window.location)

  1. 隐藏您页面的所有内容预加载(即有一个包含整个页面的 DIV,并在其上放置“显示:无”样式)

  2. 将“onLoad”事件处理程序附加到取消隐藏 DIV 的页面,然后...

  3. 在同一个“onLoad”事件处理程序中,使用标准的 JS 滚动机制(即 ScrollTo)滚动到锚点(我认为你将能够通过检查 window.location 来确定滚动到哪个锚点)

In theory, because the browser will browser-scroll between #1 and #2 (and since there's nowhere to scroll to, what with the content being hidden and all, I imagine it just won't do anything at all), the scrolling mechanism you use in #3 shouldn't have any interference.

理论上,因为浏览器将在 #1 和 #2 之间进行浏览器滚动(并且由于无处可滚动,内容被隐藏等等,我想它根本不会做任何事情),滚动机制您在 #3 中使用不应该有任何干扰。

That being said, all of the above is a completelyuntested plan; your mileage my vary. Even if it does work, it's going to be a pain to implement, so unless you reallywant this behavior, it's almost certainly not worth the trouble.

话虽如此,以上所有内容都是完全未经测试的计划;你的里程我的因人而异。即使它确实有效,实现起来也会很痛苦,所以除非你真的想要这种行为,否则几乎肯定不值得麻烦。

回答by just somebody

that's not possible

那不可能

edit

编辑

the behavior is completely in the hands of the UA.

行为完全掌握在 UA 手中。