jQuery: прокрутите до привязки при вызове URL, замените поведение браузера

Я уже знаю плагин jQuery ScrollTo, но до сих пор не нашел способа реализовать следующее:

Пользователи попадают на мой сайт (набрав, а НЕ нажав ссылку на моей странице) domain.com/bla.php#foo

и якорь "#foo" существует. Теперь я хочу, чтобы браузер пользователя НЕ автоматически прокручивался до «#foo», вместо этого я хочу плавно прокручивать, чтобы элемент «#foo» находился примерно в середине представления, а НЕ в абсолютной верхней позиции просмотр пользователей.

спасибо пока!


person bj.    schedule 14.12.2009    source источник


Ответы (9)


Если вы не создаете фактический якорь foo, а создаете свой якорь с идентификатором вроде _foo (что-то вроде <a id="_foo">). Вы можете справиться с $(document).ready, чтобы добиться этого.

Что-то вроде (псевдокод)

$(document).ready(function() { 
    var elem = $('#_' + window.location.hash.replace('#', ''));
    if(elem) {
         $.scrollTo(elem.left, elem.top);
    }
});
person Jan Jongboom    schedule 14.12.2009
comment
Вау, это кажется довольно ПРИЯТНЫМ! Должно быть выполнимо, большое спасибо :) Единственное, что в этом немного глупо: пользователь прокручивается только после загрузки всей страницы. Возможно, пользователь не хочет ждать так долго и прокручивает себя вниз или раздражается... Но я обязательно попробую, спасибо! - person bj.; 15.12.2009
comment
Ну, вы можете вставить jquery ниже всего вашего html без document.ready, это должно дать вам то, что вы ищете :-) - person Jan Jongboom; 15.12.2009

Я немного улучшил сценарий от 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 поведение останется нетронутым.

person Viktor Stískala    schedule 31.07.2010

Ответ Machineghost был очень полезным. Код, который я исправил вместе, берет параметр URL и превращает его в хэш-тег, который затем прокручивается браузером, как только DOM будет готов.

URL-адрес будет выглядеть следующим образом:

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

Контакт — это имя идентификатора, к которому вы хотите перейти

<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», если цель прокрутки не идет точно туда, куда вы хотите.

Я не смог бы сделать это без постов выше, так что спасибо!

person ReLeaf    schedule 04.01.2012

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

person Emilion    schedule 27.08.2012

Вы по-прежнему можете использовать ScrollTo. Вы хотели бы отобразить страницу без привязок, а затем использовать JavaScript, который запускается при загрузке страницы, чтобы получить привязку из URL-адреса. Затем вы можете использовать этот текст для прокрутки до определенного идентификатора.

Не уверен, как получить элемент в середине страницы, но вы можете указать смещение для прокрутки.

person Chris Williams    schedule 14.12.2009

Я не хочу сказать, что это невозможно, но... как минимум это будет довольно сложно. Браузер (или, по крайней мере, все известные мне) прокручивают до точки привязки, как только эта часть страницы загружается; Насколько я знаю, нет способа избежать этого на основе Javascript (вам понадобится плагин для браузера или что-то в этом роде).

Однако я думаю, что вы могли бы использовать вариант сценария «не показывать страницу, пока страница не будет полностью загружена», чтобы потенциально получить желаемое поведение. Другими словами, вы бы:

  1. Скрыть предварительную загрузку всего содержимого вашей страницы (т.е. иметь DIV, который обертывает всю вашу страницу, и поместить на него стиль «display: none»)

  2. Прикрепите обработчик события onLoad к странице, которая скрывает ваш DIV, и...

  3. В том же обработчике событий onLoad используйте стандартный механизм прокрутки JS (т.е. ScrollTo) для прокрутки до якоря (я думаю, вы сможете определить, к какому якорю прокручиваться, проверив window.location)

Теоретически, поскольку браузер будет прокручивать браузер между #1 и #2 (и поскольку прокручивать некуда, что со скрытым содержимым и все такое, я полагаю, что он просто ничего не сделает), механизм прокрутки вы используете в # 3 не должны иметь каких-либо помех.

При этом все вышеперечисленное является совершенно непроверенным планом; ваш пробег мой варьируется. Даже если это сработает, реализовать его будет сложно, поэтому, если вы действительно не хотите такого поведения, оно почти наверняка не стоит хлопот.

person machineghost    schedule 14.12.2009

Попробуйте этот код, у меня он отлично работает только с использованием 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');
    }
});
person Silambarasan R.D    schedule 11.12.2019

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

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

Это отлично работает для меня.

person JustPBK    schedule 25.10.2020

это невозможно

изменить

поведение полностью находится в руках UA.

person just somebody    schedule 14.12.2009