Как узнать, переместилась ли страница на якорь (#) в javascript?

У меня есть javascript, который может отображаться на разных страницах. Иногда к этим страницам обращались по URL-адресу, содержащему ссылку привязки (например, # comment-100). В тех случаях я хочу, чтобы javascript откладывал выполнение до тех пор, пока окно не подскочило. Сейчас я просто использую задержку, но это довольно хаки и, очевидно, не работает во всех случаях. Кажется, я не могу найти какое-либо событие DOM, соответствующее окну "прыжок".

Помимо простой задержки, единственное решение, с которым я столкнулся, - это заставить JS искать якорь в URL-адресе и, если он найдет его, следить за изменениями в scrollTop. Но это кажется ошибкой, и я не уверен на 100%, что мой script всегда будет запущен до прокрутки, поэтому он будет работать, только если пользователь будет вручную прокручивать страницу. Во всяком случае, мне не очень нравится решение, и я бы предпочел что-то большее, чем событие. Любые предложения?

Изменить, чтобы уточнить:

Я не пытаюсь обнаружить изменение хэша. Возьмем следующий пример:

  • Страница index.php содержит ссылку на post.php # комментарий-1
  • Пользователь щелкает ссылку на post.php # комментарий-1
  • post.php # комментарий-1 загружает
  • $(document).ready fire
  • Вскоре браузер перейдет к # comment-1

Я пытаюсь надежно обнаруживать, когда происходит шаг 5.

Ответ 1

Похоже, вы могли бы использовать window.onscroll. Я тестировал этот код только сейчас:

<a name="end" />
<script type="text/javascript">
    window.onscroll = function (e) {
        alert("scrolled");
}
</script>

который, похоже, работает.

Изменить: Hm, он не работает в IE8. Он работает как в Firefox, так и в Chrome.

Изменить: jQuery имеет обработчик .scroll(), но он запускается перед прокруткой на IE и, похоже, не работает для Chrome или Firefox.

Ответ 2

Вы можете проверить window.onhashchange в современных браузерах. Если вы хотите перекрестная совместимость, проверьте http://benalman.com/projects/jquery-hashchange-plugin/

На этой странице также есть дополнительная информация о window.onhashchange.

EDIT: вы в основном заменяете все имена привязок аналогичным соглашением, а затем используете .scrollTo для обработки прокрутки:

$(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,{onAfter:function(){
        //put after scroll code here }});
  }
});

См. jQuery: прокрутите до привязки при вызове URL, замените поведение браузеров для получения дополнительной информации.

Ответ 3

Чтобы обнаружить, когда элемент появляется на экране, используйте плагин appear:

$('#comment-1').appear(function() {
  $(this).text('scrolled');
});