Изменить URL при прокрутке вручную на якорь?

По умолчанию, если у меня есть якоря на моем веб-сайте, то URL-адрес в адресной строке изменяется, когда я нажимаю на ссылку (например, www.mysite.com/#anchor).

Можно ли изменить URL-адрес в адресной строке, когда я прокручиваю до якоря? Или у меня длинный документ с несколькими якорями и URL-адресом меняется в адресной строке, когда я нажимаю новый якорь?

5 ответов

Решение

Попробуйте использовать этот плагин jquery: Scrollorama. Он имеет массу интересных функций, и вы можете использовать window.location.hash обновить хеш вашего браузера.

Кроме того, вы можете добавить событие "прокрутка", чтобы проверить, когда якорь достигнут.

Вот рабочая скрипка, иллюстрирующая событие: http://jsfiddle.net/gugahoi/2ZjWP/8/ Пример:

$(function () {
    var currentHash = "#initial_hash"
    $(document).scroll(function () {
        $('.anchor_tags').each(function () {
            var top = window.pageYOffset;
            var distance = top - $(this).offset().top;
            var hash = $(this).attr('href');
            // 30 is an arbitrary padding choice, 
            // if you want a precise check then use distance===0
            if (distance < 30 && distance > -30 && currentHash != hash) {
                window.location.hash = (hash);
                currentHash = hash;
            }
        });
    });
});

Простая версия js Исследуя, как обновить URL-адрес на основе положения элементов раздела HTML на экране, я продолжал находить эту ветку, поэтому надеюсь, что это хорошее место для публикации.

Эта функция перебирает элементы раздела HTML.

        function updateFragId() {
        var len = sections.length;
          for (var i = 0; i < len; i++) {
            var id = sections[i].id;

Собирает положение прокрутки Y относительно области просмотра.

            var rect = sections[i].getBoundingClientRect().y;

преобразовать два массива в объект

            var pageData = {id:id, rect:rect};

установить диапазон для кода, который будет запускаться между ними. Здесь он сработает, когда верхняя часть элемента раздела находится в диапазоне от -200 пикселей до 400 пикселей.

            if (pageData.rect > -200 && pageData.rect < 400) {

запускать только один раз, убедившись, что pageData.id и location.hash еще не совпадают. Это не дает ему забивать ваш браузер событиями.

        if (pageData.rect > -100 && pageData.rect < 100) {
            if (pageData.id !== location.hash.substr(1)) {
                fragmentId = pageData.id;
                setActiveLink(fragmentId);
              } else {
                return;
            }
          }
        }
      }

    window.addEventListener('scroll', updateFragId);

Я использую противодействие этому блоку кода с другим блоком, чтобы установить активную ссылку. Но это как раз то, как отслеживать # якоря.

Вы можете использовать HTML 5 pushstate, чтобы изменить URL в адресной строке

window.history.pushstate


  1. https://developer.mozilla.org/en-US/docs/DOM/Manipulating_the_browser_history
  2. Как я могу использовать window.history.pushState "безопасно"
  1. Свяжите обработчик с событием прокрутки jquery.
  2. Проверьте, виден ли якорь в данный момент на экране с помощью этого jquery-скрипта.
  3. Используйте pushstate или установите местоположение (вероятно, вызовет прыжки)

Вы можете привязаться к событию прокрутки jQuery ( http://api.jquery.com/scroll/) и при каждом вызове обратного вызова проверять, насколько далеко документ прокручивается пользователем, проверяя это значение:.scrollTop ( http://api.jquery.com/scrollTop/) и установите привязку, манипулируя объектом location.hash ( http://www.w3schools.com/jsref/prop_loc_hash.asp).

Это было бы что-то вроде этого:

// Checks if the passed element is visible on the screen after scrolling
// source: http://stackru.com/questions/487073/check-if-element-is-visible-after-scrolling
function isScrolledIntoView(elem) {
  var docViewTop = $(window).scrollTop();
  var docViewBottom = docViewTop + $(window).height();

  var elemTop = $(elem).offset().top;
  var elemBottom = elemTop + $(elem).height();

  return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}

$('#document').scroll(function(e) {
  var anchors = $('.anchor');
  for (var i = 0; i < anchors.length; ++i) {
    if (isScrolledIntoView(anchors[i])){
      var href = $(anchors[i]).attr('href');
      location.hash = href.slice(href.indexOf('#') + 1);
      break;
    }
  }
});

Вы можете быть более точным, если вы выберете якоря после их выбора, так что первый видимый якорь будет установлен всегда.

Я думаю, тебе нужно сделать что-то подобное. Не пробовал в действии

var myElements = $("div.anchor"); // You target anchors
$(window).scroll(function(e) {
    var scrollTop = $(window).scrollTop();
    myElements.each(function(el,i) {
        if ($(this).offset().top > scrollTop && $(myElements[i+1]).offset().top < scrollTop) {
             location.hash = this.id;
        }
    });
});`
Другие вопросы по тегам