Javascript 如何更新window.location.hash而不跳过文档?
我在我的网站上设置了一个滑动面板 当它完成动画制作后,我像这样设置散列Javascript 如何更新window.location.hash而不跳过文档?,javascript,jquery,hash,scrollto,Javascript,Jquery,Hash,Scrollto,我在我的网站上设置了一个滑动面板 当它完成动画制作后,我像这样设置散列 function() { window.location.hash = id; } (这是一个回调,id在前面分配) 这很好,允许用户为面板添加书签,也允许非JavaScript版本工作 但是,当我更新散列时,浏览器会跳转到该位置。我想这是意料之中的行为 我的问题是:我如何防止这种情况?也就是说,如何更改窗口的哈希值,但不如果哈希值存在,如何让浏览器滚动到元素?某种类型的event.preventDefault()之
function() {
window.location.hash = id;
}
(这是一个回调,id
在前面分配)
这很好,允许用户为面板添加书签,也允许非JavaScript版本工作
但是,当我更新散列时,浏览器会跳转到该位置。我想这是意料之中的行为
我的问题是:我如何防止这种情况?也就是说,如何更改窗口的哈希值,但不如果哈希值存在,如何让浏览器滚动到元素?某种类型的event.preventDefault()
之类的东西
我正在使用jQuery1.4和
非常感谢
更新
下面是更改面板的代码
$('#something a').click(function(event) {
event.preventDefault();
var link = $(this);
var id = link[0].hash;
$('#slider').scrollTo(id, 800, {
onAfter: function() {
link.parents('li').siblings().removeClass('active');
link.parent().addClass('active');
window.location.hash = id;
}
});
});
问题是您正在将window.location.hash设置为元素的ID属性。无论是否使用“preventDefault()”,浏览器都会跳转到该元素 解决此问题的一种方法是使用任意值作为哈希的前缀,如下所示:
window.location.hash = 'panel-' + id.replace('#', '');
然后,您只需在页面加载时检查前缀哈希。作为额外的好处,您甚至可以平滑滚动到它,因为您现在可以控制哈希值
$(function(){
var h = window.location.hash.replace('panel-', '');
if (h) {
$('#slider').scrollTo(h, 800);
}
});
如果您需要它在任何时候都能工作(而不仅仅是在初始页面加载时),您可以使用一个函数来监视哈希值的更改,并动态跳转到正确的元素:
var foundHash;
setInterval(function() {
var h = window.location.hash.replace('panel-', '');
if (h && h !== foundHash) {
$('#slider').scrollTo(h, 800);
foundHash = h;
}
}, 100);
为什么不获取当前滚动位置,将其放入一个变量中,然后分配散列并将页面滚动回到原来的位置:
var yScroll=document.body.scrollTop;
window.location.hash = id;
document.body.scrollTop=yScroll;
这应该是可行的在现代浏览器上使用历史API,并在旧浏览器上使用回退,有一个解决方法:
if(history.pushState) {
history.pushState(null, null, '#myhash');
}
else {
location.hash = '#myhash';
}
这归功于廉价而肮脏的解决方案。。使用丑陋的#!风格 要设置它,请执行以下操作:
window.location.hash = '#!' + id;
阅读:
id = window.location.hash.replace(/^#!/, '');
因为它不匹配并且在页面中锚定或id,所以它不会跳转。我不确定是否可以更改原始元素,但是如何从使用id attr切换到其他类似数据id的内容?然后只需读取哈希值的数据id值,它就不会跳转。我使用了针对现代浏览器的Attila Fulop(Lea Verou)解决方案和针对旧浏览器的Gavin Brock解决方案的组合,如下所示:
if (history.pushState) {
// IE10, Firefox, Chrome, etc.
window.history.pushState(null, null, '#' + id);
} else {
// IE9, IE8, etc
window.location.hash = '#!' + id;
}
id = window.location.hash.replace(/^#!?/, '');
正如Gavin Brock所观察到的,要捕获回id,您必须按如下方式处理字符串(在本例中,该字符串可以有“!”),也可以没有“!”:
if (history.pushState) {
// IE10, Firefox, Chrome, etc.
window.history.pushState(null, null, '#' + id);
} else {
// IE9, IE8, etc
window.location.hash = '#!' + id;
}
id = window.location.hash.replace(/^#!?/, '');
在此之前,我尝试了一个类似于user706270提出的解决方案,但它在Internet Explorer中运行不太好:因为它的Javascript引擎不是很快,你可以注意到滚动的增加和减少,这会产生令人讨厌的视觉效果。这个解决方案对我很有效 设置
location.hash
的问题是,如果在页面上找到该id,页面将跳转到该id
window.history.pushState的问题在于,它为用户单击的每个选项卡的历史添加了一个条目。然后,当用户单击back
按钮时,他们进入上一个选项卡。(这可能不是你想要的,也可能不是我想要的)
对我来说,replaceState
是更好的选择,因为它只替换当前历史记录,所以当用户单击back
按钮时,他们会转到上一页
$('#tab-selector').tabs({
activate: function(e, ui) {
window.history.replaceState(null, null, ui.newPanel.selector);
}
});
查看MDN上的。在使用laravel框架时,我在使用route->back()函数时遇到了一些问题,因为它删除了我的哈希。为了保留哈希,我创建了一个简单的函数:
$(function() {
if (localStorage.getItem("hash") ){
location.hash = localStorage.getItem("hash");
}
});
我在另一个JS函数中设置如下:
localStorage.setItem("hash", myvalue);
您可以任意命名本地存储值;名为散列的矿井
因此,如果在第1页设置哈希,然后导航到第2页;当您在第2页单击“上一步”时,将在第1页重新创建哈希。此解决方案对我有效
// store the currently selected tab in the hash value
if(history.pushState) {
window.history.pushState(null, null, '#' + id);
}
else {
window.location.hash = id;
}
// on load of the page: switch to the currently selected tab
var hash = window.location.hash;
$('#myTab a[href="' + hash + '"]').tab('show');
我的完整js代码是
$('#myTab a').click(function(e) {
e.preventDefault();
$(this).tab('show');
});
// store the currently selected tab in the hash value
$("ul.nav-tabs > li > a").on("shown.bs.tab", function(e) {
var id = $(e.target).attr("href").substr(1);
if(history.pushState) {
window.history.pushState(null, null, '#' + id);
}
else {
window.location.hash = id;
}
// window.location.hash = '#!' + id;
});
// on load of the page: switch to the currently selected tab
var hash = window.location.hash;
// console.log(hash);
$('#myTab a[href="' + hash + '"]').tab('show');
我想你已经试过event.preventDefault()
:)@Marko我不知道该放在哪里!你能发布你剩下的代码吗?@Marko Ivanovski我认为这不相关,但我会看看我能做些什么。@Gareth我不认为有地方放它,因为我一更新哈希就发生了。嗯,这对我来说已经有一段时间了,但在过去几个月的某个时候,firefox已经停止运行……我不得不保持与IE7和该网站的一些移动版本的兼容性。这个解决方案对我来说是最干净的。通常情况下,我会在pushState解决方案中进行设置。使用:window.location.hash='#/'+id然后将其替换为:window.location.hash.replace(/^#\/,“#”)
会稍微美化url->projects/#/tab1
我认为这是更好的答案。请注意,pushState具有向浏览器历史堆栈添加状态的副作用(缩进)。换句话说,当用户单击“上一步”按钮时,除非同时添加popstate事件监听器,否则不会发生任何事情。@davidOK-我们还可以使用history.replaceState
(对于哈希更改,这可能更有意义)来避免使用popstate
事件监听器。这对我很有用。我喜欢历史变化的影响。我想补充一点,这不会触发hashchange
事件。这是我必须解决的问题。警告!这不会触发hashchange
事件这是唯一真正回答问题的解决方案-允许不跳转的哈希这真正回答了解释添加和删除哈希的任意值以避免按照默认浏览器行为跳转的问题。好的解决方案,但是削弱了OPs解决方案,因为它否定了书签部分的使用