Как я могу удалить хеш местоположения, не вызывая прокрутку страницы? - PullRequest
75 голосов
/ 19 февраля 2010

Можно ли удалить хеш из window.location, не заставляя страницу прокручиваться вверх? Мне нужно иметь возможность изменять хэш, не вызывая скачков.

У меня есть это:

$('<a href="#123">').text('link').click(function(e) {
  e.preventDefault();
  window.location.hash = this.hash;
}).appendTo('body');

$('<a href="#">').text('unlink').click(function(e) {
  e.preventDefault();
  window.location.hash = '';
}).appendTo('body');

Смотрите живой пример здесь: http://jsbin.com/asobi

Когда пользователь нажимает ' link ', хэш-тег изменяется без каких-либо переходов по страницам, поэтому он работает нормально.

Но когда пользователь нажимает ' unlink ', тег has удаляется, и страница прокручивается вверх. Мне нужно удалить хэш без этого побочного эффекта.

Ответы [ 8 ]

93 голосов
/ 19 февраля 2010

Я полагаю, что если вы просто вставите фиктивный хеш, он не будет прокручиваться, поскольку нет соответствия для прокрутки.

<a href="#A4J2S9F7">No jumping</a>

или

<a href="#_">No jumping</a>

"#" само по себе эквивалентно "_top", что вызывает прокрутку вверх страницы

35 голосов
/ 18 октября 2011

Я использую следующее на нескольких сайтах, без скачков страниц!

Хорошая чистая адресная строка для браузеров, поддерживающих HTML5, и просто # для старых браузеров.

$('#logo a').click(function(e){
    window.location.hash = ''; // for older browsers, leaves a # behind
    history.pushState('', document.title, window.location.pathname); // nice and clean
    e.preventDefault(); // no page reload
});
18 голосов
/ 19 февраля 2010

Свойство хеша window.location является глупым в двух отношениях.Это один из них;другая - имеет разные значения get и set:

window.location.hash = "hello";  // url now reads *.com#hello
alert(window.location.hash);   // shows "#hello", which is NOT what I set.
window.location.hash = window.location.hash; // url now reads *.com##hello

Обратите внимание, что установка свойства hash в '' также удаляет метку хэша;это то, что перенаправляет страницу.Чтобы установить значение хеш-части URL-адреса '', оставляя хеш-метку и, следовательно, не обновляя, напишите это:

window.location.href = window.location.href.replace(/#.*$/, '#');

Нет способа полностью удалить хеш-метку, установленную без обновлениястраница.

ОБНОВЛЕНИЕ 2012:

Как отметили Blazemonger и thinkdj, технологии улучшились.Некоторые браузеры позволяют очистить этот хэштег, но некоторые этого не делают.Чтобы поддержать оба, попробуйте что-то вроде:

if ( window.history && window.history.pushState ) { 
    window.history.pushState('', '', window.location.pathname) 
} else { 
    window.location.href = window.location.href.replace(/#.*$/, '#'); 
}
3 голосов
/ 17 августа 2012

Это старый пост, но я хотел бы поделиться своим решением Все ссылки в моем проекте, которые обрабатываются JS, имеют атрибут href = "#_ js" (или любое другое имя, которое вы хотите использовать только для этих целей), и при инициализации страницы я делаю:

$('body').on('click.a[href="#_js"]', function() {
    return false;
});

Это подойдет

2 голосов
/ 19 февраля 2010

Установка window.location.hash на пустое или несуществующее имя привязки всегда заставит страницу перейти наверх. Единственный способ предотвратить это - захватить положение прокрутки окна и снова установить его в это положение после изменения хеша.

Это также приведет к перерисовке страницы (не могу этого избежать), хотя, поскольку она выполняется в одном js-процессе, она не будет перепрыгивать (теоретически).

$('<a href="#123">').text('link').click(function(e) {
    e.preventDefault();
    window.location.hash = this.hash;
}).appendTo('body');

$('<a href="#">').text('unlink').click(function(e) {
    e.preventDefault();
    var pos = $(window).scrollTop(); // get scroll position
    window.location.hash = '';
    $(window).scrollTop(pos); // set scroll position back
}).appendTo('body');

Надеюсь, это поможет.

1 голос
/ 19 февраля 2010

Вы пробовали return false; в обработчике событий? jQuery делает что-то особенное, когда вы делаете это, похоже, но AFAIK более эффектно, чем e.preventDefault.

1 голос
/ 19 февраля 2010

Я не уверен, что это даст желаемый результат, попробуйте:

$('<a href="#">').text('unlink').click(function(e) {
    e.preventDefault();
    var st = parseInt($(window).scrollTop())
    window.location.hash = '';
    $('html,body').css( { scrollTop: st });  
});

В основном сохраните смещение прокрутки и восстановите его после назначения пустого хеша.

0 голосов
/ 03 мая 2015

Надеюсь, это поможет

HTML

<div class="tabs">
  <ul>
    <li><a href="#content1">Tab 1</a></li>
    <li><a href="#content2">Tab 2</a></li>
    <li><a href="#content3">Tab 3</a></li>
  </ul>
</div>
<div class="content content1">
    <p>1. Content goes here</p>
</div>
<div class="content content2">
    <p>2. Content goes here</p>
</div>
<div class="content content3">
    <p>3. Content goes here</p>
</div>

JS

function tabs(){
  $(".content").hide();

  if (location.hash !== "") {
    $('.tabs ul li:has(a[href="' + location.hash + '"])').addClass("active");
    var hash = window.location.hash.substr(1);
    var contentClass = "." + hash;
    $(contentClass).fadeIn();
  } else {
    $(".tabs ul li").first().addClass("active");
    $('.tabs').next().css("display", "block");
  }
}
tabs();

$(".tabs ul li").click(function(e) {
  $(".tabs ul li").removeAttr("class");
  $(this).addClass("active");
  $(".content").hide();
  var contentClass = "." + $(this).find("a").attr("href").substr(1);
  $(contentClass).fadeIn();
  window.location.hash = $(this).find("a").attr("href");
  e.preventDefault();
  return false;
});

URL без хэша.
http://output.jsbin.com/tojeja

URL с хэштегом, который не переходит на привязку.
http://output.jsbin.com/tojeja#content1

...