我有一个自定义弹出功能。我想要的是使浏览器后退按钮关闭此弹出窗口。
我的理想情况是不要在网址栏中显示井号标签。
我尝试将window.history.pushState('forward', null, '');
放入我的showPopup()
函数中,然后执行以下操作:
$(window).on('popstate', function () {
closePopup();
});
这确实有效,但是问题是当我手动关闭弹出窗口时,我必须按两次后退按钮才能导航回到上一页(显然是因为打开弹出窗口时添加了浏览器历史记录条目)。
做到这一点的最佳方法是什么?是否可以在不添加浏览器历史记录条目的情况下完成?本质上,我想做的是复制移动应用程序的行为。在移动应用中按返回按钮通常会关闭所有打开的模式或上下文菜单。
$('.popup-link').click(function() {
showPopup();
});
$('.popup-close').click(function() {
hidePopup();
});
function showPopup() {
$('.popup').addClass('active');
}
function hidePopup() {
$('.popup').removeClass('active');
}
.popup {
background-color: #ccc;
width: 300px;
height: 300px;
display: none;
}
.popup.active {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="popup-link">Click</button>
<div class="popup">
<button class="popup-close">x</button>
<!-- popup content here -->
</div>
答案 0 :(得分:10)
如果不添加浏览器历史记录条目,则无法执行此操作,因为您无法覆盖后退按钮的行为,请参见Intercepting call to the back button in my AJAX application: I don't want it to do anything
Sujumayas答案是一个不错的选择,尽管应该避免打开多个弹出窗口(例如,多次单击按钮时)的历史记录问题,但您应该引入一些其他变量
以下是一些可能的示例代码:
let popupOpen = false;
$(".popup-link").click(function() {
showPopup();
});
$(".popup-close").click(function() {
window.history.back();
});
function showPopup() {
if (popupOpen) {
window.history.back();
}
popupOpen = true;
window.history.pushState("forward", null, "");
$(".popup").addClass("active");
}
function hidePopup() {
popupOpen = false;
$(".popup").removeClass("active");
}
$(window).on("popstate", function() {
hidePopup();
});
另外请注意,您可能会遇到Opera Mini的问题:https://caniuse.com/#search=history
答案 1 :(得分:4)
我不建议您覆盖常规的浏览器历史记录管理(后退按钮)以随便使用它。...
我认为您在示例中唯一遗漏的是关闭按钮不应自行关闭模式,而应仅执行backbutton事件(最终将关闭模式)。
该简单修复程序将按您希望的方式工作。
答案 2 :(得分:1)
您将有两种选择来实现此目的:
选项1::使用window.beforeunload
事件。 reference
$('.popup-link').click(function() {
showPopup();
$(window).on("beforeunload", hidePopup);
});
$('.popup-close').click(hidePopup);
function hidePopup() {
$(window).off("beforeunload", hidePopup);
$('.popup').removeClass('active');
}
选项2::使用HTML5历史记录API。 reference
$('.popup-link').click(function() {
showPopup();
window.history.pushState('popup-open', null, '');
$(window).on('popstate', hidePopup);
});
$('.popup-close').click(function() {
if(history.state == 'popup-open') {
window.history.back();
}
hidePopup();
});
function hidePopup() {
$(window).off('popstate', hidePopup);
$('.popup').removeClass('active');
}
编辑:sujumayas的想法也很不错。 Demo
此外,我建议仅在必要时注册popstate
/ beforeunload
事件,并在不再需要使用em来避免开销时注销它们。
答案 3 :(得分:0)
我已经在做类似的事情了,它可以很好地与浏览器后退按钮配合使用,也可以通过按下android后退按钮来实现。我也没有在网址栏中显示主题标签。
这是存根(我只是尝试将其应用于您的情况):
function freezeHistory() {
window.history.pushState({}, window.document.title, window.location.href);
}
function goBack() {
/*
Custom history back actions: close panel, close popup, close drop-down menu
*/
var popupOpen = $(".popup.active").length > 0;
if(popupOpen) {
hidePopup();
return false;
}
window.history.back();
return true;
}
function showPopup() {
$('.popup').addClass('active');
freezeHistory();
}
function hidePopup() {
$('.popup').removeClass('active');
}
$(window).on("popstate", function(e) {
/*
Browsers tend to handle the popstate event differently on page load.
Chrome (prior to v34) and Safari always emit a popstate event on page load,
but Firefox doesn’t.
*/
goBack();
})
如果这对于您开箱即用不起作用,是因为恕我直言,您可能需要澄清一点,您希望如何管理页面历史记录。如果您的问题现在没有按您期望的那样进行,请随时为您的问题添加更多细节,但是无论如何,我坚信您已经有了这个主意,并且可以将其应用到您的网络应用场景中。>
答案 4 :(得分:0)
打开弹出窗口,然后尝试使用浏览器历史记录按钮来回浏览
$(document).ready(function () {
// manage popup state
var poped = false;
$('.popup-link').click(function () {
// prevent unwanted state changtes
if(!poped){
showPopup();
}
});
$('.popup-close').click(function () {
// prevent unwanted state changtes
if(poped){
hidePopup();
}
});
function showPopup() {
poped = true;
$('.popup').addClass('active');
// push a new state. Also note that this does not trigger onpopstate
window.history.pushState({'poped': poped}, null, '');
}
function hidePopup() {
poped = false;
// go back to previous state. Also note that this does not trigger onpopstate
history.back();
$('.popup').removeClass('active');
}
});
// triggers when browser history is changed via browser
window.onpopstate = function(event) {
// show/hide popup based on poped state
if(event.state && event.state.poped){
$('.popup').addClass('active');
} else {
$('.popup').removeClass('active');
}
};
.popup {
background-color: #ccc;
width: 300px;
height: 300px;
display: none;
}
.popup.active {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="popup-link">Click</button>
<div class="popup">
<button class="popup-close">x</button>
<!-- popup content here -->
</div>
答案 5 :(得分:0)
您可以将window.history.go(-2)添加到popstate。这应该使您返回两次,这将是模式之前的原始页面,因为pushState向您的历史对象添加了一个条目。
相反,您可以使用history.back(2) Use window.location.href to go 2 pages back and reload
答案 6 :(得分:0)
只需运行window.history.back();当关闭弹出窗口时。
$('.popup-close').click(function() {
hidePopup();
window.history.back();
});