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

发布于 2024-08-14 16:38:53 字数 224 浏览 3 评论 0原文

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

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

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

到目前为止谢谢!

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

The users gets to my site (by typing, NOT by clicking a link on my page) 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.

thanks so far!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

梦旅人picnic 2024-08-21 16:38:53

如果您没有创建实际的锚点 foo,而是使用类似 _foo 的 id 创建锚点(类似于 ;)。您可以处理 $(document).ready 来实现此目的。

类似于(伪代码)

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

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).ready to achieve this.

Something like (pseudo code)

$(document).ready(function() { 
    var elem = $('#_' + window.location.hash.replace('#', ''));
    if(elem) {
         $.scrollTo(elem.left, elem.top);
    }
});
只等公子 2024-08-21 16:38:53

我对 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);
    }

});

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

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

$(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.

dawn曙光 2024-08-21 16:38:53

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

URL 将如下所示:

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

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

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

这是代码:

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

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

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

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.

The URL would look like this:

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

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

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

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

纵情客 2024-08-21 16:38:53
/* 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 */

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

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

红焚 2024-08-21 16:38:53
if(window.location.hash) {
  var hash = window.location.hash;

  $('html, body').animate({
    scrollTop: $(hash).offset().top
  }, 1500, 'swing');
}

这对我来说效果很好..

if(window.location.hash) {
  var hash = window.location.hash;

  $('html, body').animate({
    scrollTop: $(hash).offset().top
  }, 1500, 'swing');
}

This works fine for me..

怪异←思 2024-08-21 16:38:53

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

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

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.

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

我是有多爱你 2024-08-21 16:38:53

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

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

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

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

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

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

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

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

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)

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.

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

许一世地老天荒 2024-08-21 16:38:53

试试这个代码,仅使用 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');
    }
});

Try this Code is working for me perfectly only using 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');
    }
});
℡寂寞咖啡 2024-08-21 16:38:53

这是不可能的,

编辑

行为完全掌握在用户代理手中。

that's not possible

edit

the behavior is completely in the hands of the UA.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文