如何在不导致页面滚动的情况下删除位置哈希?


76

是否可以在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 ”时,哈希标签被修改而没有任何页面跳转,因此可以正常工作。

但是,当用户单击“取消链接”时,has标记将被删除,页面滚动跳转到顶部。我需要删除没有这种副作用的哈希。


让我猜:您的客户认为哈希值很丑陋,并且正在污染漂亮的URL,而URL干净:http:// www.example.com/(不带空格)?
anddoutoi 2010年

好猜,但没有。我有基于哈希URL的可收藏的模式窗口,当用户关闭窗口时,哈希就需要去了。
David Hellsing,2010年

1
我知道这个问题将近2年了,但是这个评论可能会对将来的读者有所帮助。如果您确实要删除哈希,则可以使用history.pushState()更改URL。 developer.mozilla.org/en/DOM/...
ambiguousmouse

@joshli,可惜它无法正常工作IE9
Tsukimoto Mitsumasa 2012年

Answers:


96

我相信,如果您只放入一个虚拟哈希,它将不会滚动,因为没有匹配项可滚动到。

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

要么

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

"#"本身等效于"_top"因此导致滚动到页面顶部


12
不是最佳,但足够好。我使用了“#/”,结果相同。
David Hellsing,2010年

window.location.hash = (new_hash === '') ? '_' : new_hash;
测试人员

对这种解决方案不满意,该怎么办:stackoverflow.com/questions/19728020/…–
stephen

21
我使用window.location.hash = "💩";
Aeyoun 2015年

37

我在一些网站上使用以下内容,没有页面跳转!

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

12
history.replaceState可能更可取,因为按下后将返回上一个有效的URL。
Orlade

另外,应该注意,此代码正在设置,以对导航历史记录进行两次更改。结果是,当用户按下“后退”按钮时,他们将首先通过[url]#进行路由,然后需要再次单击才能进入不带#的[url]。如果您正在开发后退按钮体验,请考虑采用有条件的方法,以免两次设置状态。
尼·凯利2014年

18

window.location的hash属性在几种方面都很愚蠢。这就是其中之一;另一个是具有不同的获取和设置值:

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(/#.*$/, '#'); 
}

2
不对。支持的浏览器使window.history您可以做到这一点。
Blazemonger

@Blazemonger没错!您可以使用history.pushState('',document.title,window.location.pathname);
Deepak Thomas

但是话又说回来,此评论是在2010年2月发布的,浏览器在2011
Deepak Thomas

上面的代码不保留查询字符串。使用window.history.pushState('', '', window.location.pathname + window.location.search);
dipole_moment,

3

这是一篇旧文章,但我想分享我的解决方案由JS处理的项目中的所有链接都具有href =“ #_ js”属性(或仅用于此目的的任何名称),并在页面上进行初始化我做:

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

这样就可以了


2

将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
并非完全正确...将哈希值设置为“”会滚动到顶部,但是如果没有具有匹配id属性的命名锚点或元素,浏览器将不会滚动。
scunliffe 2010年

1

我不确定这是否会产生所需的结果,请试一下:

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

基本上保存滚动偏移量,并在分配空哈希之后将其还原。


1
它对我有用,除了我用它$(window).scrollTop(st)代替.css()
Thomas Joulin 2011年

尝试过此操作,因为我需要将哈希更改为现有的#id。一切正常,但是当我尝试使用鼠标滚动时,更改哈希值后,滚动跳到零。关于什么可能导致此的任何想法?
lucascaro 2011年

1

您是否尝试return false;过事件处理程序?这样做时,jQuery会执行一些特殊的操作,类似于,但AFAIK的影响更大e.preventDefault


2
return false;在jQuery和兼容浏览器中的本机事件处理程序中,等同于e.preventDefault(); e.stopPropagation();。我认为停止传播不会解决此问题。
杰西·哈莱特

0

希望这可以帮助

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

不含任何哈希的网址。
http://output.jsbin.com/tojeja

带有#标签的URL不会跳转到锚点。
http://output.jsbin.com/tojeja#content1

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.