作者:xch236 | 来源:互联网 | 2023-05-19 18:59
popstate是HTML5的History系列中的事件,但是这玩意儿在webkit中的行为相当让人蛋疼。虽然官方的文档中对popstate的描述也没有细节上的描述,不过以我的逻辑来判断,
popstate是HTML5的History系列中的事件,但是这玩意儿在webkit中的行为相当让人蛋疼。
虽然官方的文档中对popstate的描述也没有细节上的描述,不过以我的逻辑来判断,这货是就webkit的BUG。 HTML5的这一套HistoryAPI和传统的History不同,或者说这一套HistoryAPI是“session history entries”。虽然官方的文档并没有强调它与传统的History不同,但是在使用上就会发现很大差异。
HTML5中的HistoryAPI是不会使页面跳转的,只是操作地址栏和相应的state属性而已,而且它是手动操作的。浏览器默认的History还是传统的那一套,虽然它们在浏览器上都使用同一个“历史记录堆栈”。 对这个差异的认知就是webkit中诡异行为的原因。webkit并没有把HTML5的History和传统的区分开,而根据官方文档对popstate的描述,只要访问历史记录就会触发popstate。而传统的History中访问页面和生产历史记录是同时的。
所以在webkit中,无论是刷新还是访问一个新网页都会触发popstate。而其它浏览器中这个popstate仅作用于HTML5的History,并不响应传统的History,更不用说刷新和访问新网页的情况了。
网络上看到的能解决这个问题的貌似也只有一个对popstate延迟绑定的方法,因为popstate会在页面加载完成之后不久触发,所以在 setTimeout一段时间后再绑定事件,popstate的第一次就不会轻易被webkit夺走了←_← 。
不过延迟这种东西我一直都觉得不太靠谱,所以还是果断放弃这种方法了。最后只好使用烂方法,判断浏览器再做调整,直接针对webkit在页面加载完成后第一次触发的popstate屏蔽了。不过毕竟是针对浏览器的东西,虽然目前是可以使用,但是如果以后webkit修复了这个BUG就需要修改代码了
changeHistory: function () {
var self = this;
if (window.history && window.history.pushState) {
$(window).on('popstate', function () {
var hashLocation = location.hash;
var hashSplit = hashLocation.split('#!/');
var hashName = hashSplit[1];
var hash = window.location.hash;
self.showDetentionActivity();
self.doExit();
});
if (window.history.state != 'only') {
window.history.pushState('only', null, document.URL);
}
}
}
changeHistory: function () {
var self = this;
if (window.history && window.history.pushState) {
function historyEvent() {
$(window).on('popstate', function () {
var hashLocation = location.hash;
var hashSplit = hashLocation.split('#!/');
var hashName = hashSplit[1];
var hash = window.location.hash;
self.showDetentionActivity();
self.doExit();
});
}
setTimeout(historyEvent, 2000);
if (window.history.state != 'only') {
window.history.pushState('only', null, document.URL);
}
}
},