jQuery: Scroll to anchor when calling URL, replace

2019-01-22 04:04发布

问题:

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!

回答1:

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


回答2:

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.



回答3:

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!



回答4:

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



回答5:

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.



回答6:

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.



回答7:

that's not possible

edit

the behavior is completely in the hands of the UA.