更新:-如Akansh Gulati
指出,如果用户在单击“后退”按钮之前与页面有任何交互,将按预期工作,并且如果用户与页面并按返回按钮,那么历史记录中的任何条目(通过哈希更改或history.push / replace)都将被忽略,这是Google Chrome update will stop websites hijacking your browser back button
这是有效且合乎逻辑的答案,所以我接受他的答案
我正在尝试在页面加载后显示成功弹出窗口,并且如果用户按下android后退按钮(在这种情况下等效于浏览器后退按钮),我只想关闭弹出窗口(不希望在付款时重定向回去)页)
我在打开弹出窗口时在url中添加哈希,但是当用户按返回按钮chrome时,忽略哈希并重定向回上一页,而不仅仅是删除哈希(在Firefox中可以正常工作)
我有一个有效的示例here
a)用Chrome打开此页面
b)等到哈希更改为“ #c”
c)然后按浏览器后退按钮
预期的行为是它应将散列更改回“ #b”,然后再更改回“ #a” 但它会忽略所有哈希更改,然后重定向回新标签页
这是code
window.location.hash = 'a';
setTimeout(function() {
writeLength();
window.location.hash = 'b';
setTimeout(function() {
writeLength();
window.location.hash = 'c';
setTimeout(function() {
writeLength();
}, 1500);
}, 1500);
}, 1500);
如何模拟正确的行为(如果可以的话)?
我在Mac上使用的是Chrome版本77.0.3865.90(正式版本)(64位)
这是行为的GIF图片
答案 0 :(得分:4)
在此浏览器中,您需要通过History API在历史记录中至少设置一个状态(虽然不确定为什么)。
即使在此iframe中,该示例也应适用。
history.replaceState( {}, '' );
window.location.hash = 'a';
setTimeout(function() {
console.log( location.hash );
window.location.hash = 'b';
setTimeout(function() {
console.log( location.hash );
window.location.hash = 'c';
setTimeout(function() {
console.log( location.hash );
console.log( "You can now use your browser's back button" );
onpopstate = e => console.log( location.hash );
}, 150);
}, 150);
}, 150);
答案 1 :(得分:1)
我尝试使用pushState进行进一步的位置更改,并且问题似乎已解决。无需replaceState。条件是用户必须至少在屏幕上单击/交互一次。
function test() {
window.location.hash = 'a';
setTimeout(function () {
writeLength();
window.history.pushState(null, null, `${window.location.pathname}#b`);
setTimeout(function () {
writeLength();
window.history.pushState(null, null, `${window.location.pathname}#c`);
setTimeout(function () {
writeLength();
}, 1500);
}, 1500);
}, 1500);
}
答案 2 :(得分:0)
您必须显式设置状态,然后单击后退按钮即可执行一些代码,如下所示:
添加一个函数以获取不包含哈希部分的window.location.href
(因为我们将对其进行显式添加):
function getUrlWithoutTheHash() {
let url = window.location.href;
let hash = window.location.hash;
let index_of_hash = url.indexOf(hash) || url.length;
return url.substr(0, index_of_hash);
}
添加一个用于推送状态的函数(而不是使用位置来更改哈希,而是使用状态API进行更改),并且我们将向状态添加属性is-my-state
来知道这是否是我们的状态:
function pushTheState(url) {
history.pushState({'is-my-state': true, 'url': url}, null, url);
}
并在打开状态时添加处理程序,如果这是您的状态之一,则可以执行所需的代码:
window.onpopstate = function(e){
if(e.state){
if(e.state.hasOwnProperty('is-my-state')){
writeLength();
}
}
};
最后,您需要像这样更改功能:
function test() {
pushTheState(getUrlWithoutTheHash() + '#a'); // pushing url with #a
setTimeout(function() {
writeLength();
pushTheState(getUrlWithoutTheHash() + '#b'); // pushing url with #b
setTimeout(function() {
writeLength();
pushTheState(getUrlWithoutTheHash() + '#c'); // pushing url with #c
setTimeout(function() {
writeLength();
}, 1500);
}, 1500);
}, 1500);
}
答案 3 :(得分:0)
我能够在Windows 10的同一版本的Chrome上使用您提供的代码,但是如果仍然遇到问题,则应该可以使用以下代码。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body onload="test()">
<div id="url"></div>
<button type="button" onclick="window.history.back();">Back</button>
</body>
<script type="text/javascript">
setInterval(function(){
document.getElementById('url').innerHTML = window.location.href;
}, 500);
function writeLength() {
document.body.appendChild(document.createTextNode(window.history.length));
}
function test() {
history.pushState({},'','#a');
setTimeout(function() {
writeLength();
history.pushState({},'','#b');
setTimeout(function() {
writeLength();
history.pushState({},'','#c');
setTimeout(function() {
writeLength();
}, 1500);
}, 1500);
}, 1500);
}
</script>
</html>
这应该起作用,因为window.pushState
应该将哈希更改强制添加到浏览器的历史记录中。如果要更新导航更改的页面,则可以使用window.onpopstate
事件。例如:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body onload="test()">
<div id="url"></div>
<button type="button" onclick="window.history.back();">Back</button>
<span id="lengths"></span>
</body>
<script type="text/javascript">
setInterval(function(){
document.getElementById('url').innerHTML = window.location.href;
}, 500);
var last = false;
var items = [];
function writeLength() {
items.push(window.history.length);
document.getElementById('lengths').appendChild(document.createTextNode(window.history.length));
}
function test() {
history.pushState({},'','#a');
setTimeout(function() {
writeLength();
history.pushState({},'','#b');
setTimeout(function() {
writeLength();
history.pushState({},'','#c');
setTimeout(function() {
writeLength();
last = true;
}, 1500);
}, 1500);
}, 1500);
}
window.onpopstate = function(){
if (last) {
if (window.location.hash == '#a') document.getElementById('lengths').innerHTML = items[0];
else if (window.location.hash == '#b') document.getElementById('lengths').innerHTML = '' + items[0] + items[1];
else if (window.location.hash == '#c') document.getElementById('lengths').innerHTML = '' + items[0] + items[1]+ items[2];
}
}
</script>
</html
上面的代码允许用户在将最终长度写到文档之后导航到页面的不同“状态”。