javascript HTML5历史禁用前进按钮
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11548558/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
HTML5 history disabling forward button
提问by dmck
I am writing a single page javascript application using the HTML5 History API. The application loads content via Ajax and internally maintains state information on the foreground screen using a screen stack.
我正在使用 HTML5 History API 编写一个单页 javascript 应用程序。应用程序通过 Ajax 加载内容,并使用屏幕堆栈在前台屏幕上内部维护状态信息。
I want to enable navigation with the back button, but I never want to the forward button to be enabled.
我想使用后退按钮启用导航,但我不想启用前进按钮。
A couple quick bits of information:
一些快速的信息:
- The user should only ever be able to go back, never forward
- Pressing browser back button closes the current page screen user is on and reloads the previous one
- Project is targeted towards the latest version of Chrome only, so other browsers implementations are not important
- I am using native JavaScript and jQuery only, I would like to do this without History.js
- 用户应该只能返回,不能前进
- 按浏览器后退按钮关闭当前页面屏幕用户打开并重新加载上一个
- 项目仅针对最新版本的 Chrome,因此其他浏览器的实现并不重要
- 我只使用原生 JavaScript 和 jQuery,我想在没有 History.js 的情况下做到这一点
When I load a new screen I run the following line:
当我加载一个新屏幕时,我运行以下行:
history.pushState(screenData, window.document.title, "#");
I bind to the popstate event via jQuery:
我通过 jQuery 绑定到 popstate 事件:
$(window).bind("popstate", function(event) {
if (event.originalEvent.state != null) {
// Logic that loads the previous screen using my screen stack
}
});
My application's history management is working, however when I go back the forward button is enabled. I need to figure out how to remove data from history
on the popstate
event.
我的应用程序的历史管理工作正常,但是当我返回时,前进按钮被启用。我需要弄清楚如何从删除数据history
的popstate
事件。
Can I do this with replaceState? I'm not sure how to go about doing this...
我可以用 replaceState 做到这一点吗?我不知道如何去做这件事......
采纳答案by Beat Richartz
Bad Part
坏零件
To really disable the forward button, you would have to be able to delete browser history, which is not allowed by all javascript implementations because it would allow sites to delete the entire history, which would never be in the interest of the user.
要真正禁用前进按钮,您必须能够删除浏览器历史记录,这是所有 javascript 实现都不允许的,因为它允许站点删除整个历史记录,这永远不会符合用户的利益。
Good Part
好零件
This is a bit tricky, but I guess it could work if you want to do custom history. You could just use pushState
in the popstate
event to make your actual page the topmost history entry. I assume the way you handle your history, your window will never unload. This allows you to keep track of the user history yourself:
这有点棘手,但我想如果您想做自定义历史记录,它可能会起作用。您可以pushState
在popstate
事件中使用,使您的实际页面成为最顶层的历史条目。我假设你处理你的历史的方式,你的窗口永远不会卸载。这允许您自己跟踪用户历史记录:
var customHistory = [];
Push every page you load with history.pushState(screenData, window.document.title, "#");
, like you did before. Only you add the state to your custom history, too:
history.pushState(screenData, window.document.title, "#");
像以前一样推送您加载的每个页面。只有您也将状态添加到自定义历史记录中:
history.pushState(screenData, window.document.title, "#");
customHistory.push({data: screenData, title: window.document.title, location: '#'});
now if you have a popstate
event, you just pop you custom history and push it to the topmost entry:
现在如果你有一个popstate
事件,你只需弹出你的自定义历史并将其推送到最上面的条目:
window.onpopstate = function(e) {
var lastEntry = customHistory.pop();
history.pushState(lastEntry.data, lastEntry.title, lastEntry.location);
// load the last entry
}
Or in jQuery
或者在 jQuery 中
$(window).on('popstate', function(e) {
var lastEntry = customHistory.pop();
history.pushState(lastEntry.data, lastEntry.title, lastEntry.location);
// load the last entry
});
回答by humanityANDpeace
The accepted answer solves the problem to disable the forward button, but creates a new annoying issue "the page navigated back to" is inserted in duplicate into the history (as indicated in the answers comments).
接受的答案解决了禁用前进按钮的问题,但会产生一个新的烦人问题“导航回的页面”被重复插入到历史记录中(如答案评论中所示)。
Here is how solve the question "diabled forward button" and to avoidthe "duplicate" back-button-issue.
这是解决“禁用前进按钮”问题并避免“重复”后退按钮问题的方法。
//setup the popstate EventListener that reacts to browser history events
window.addEventListener("popstate",function(event){
// In order to remove any "forward"-history (i.e. disable forward
// button), this popstate's event history state (having been navigated
// back to) must be insert _again_ as a new history state, thereby
// making it the new most forwad history state.
// This leaves the problem that to have this popstate event's history
// state to become the new top, it would now be multiple in the history
//
// Effectively history would be:
// * [states before..] ->
// * [popstate's event.state] ->
// * [*newly pushed _duplicate_ of popstate's event.state ]
//
// To remove the annoyance/confusion for the user to have duplicate
// history states, meaning it has to be clicked at least twice to go
// back, we pursue the strategy of marking the current history state
// as "obsolete", as it has been inserted _again_ as to be the most
// forward history entry.
//
// the popstate EventListener will hence have to distinguish 2 cases:
//
// case A) "popstate event is _not_ an obsolete duplicate"...
if( typeof event.state == "object"
&& event.state.obsolete !== true)
{
//...so we _firstly_ mark this state as to from now on "obsolete",
// which can be done using the history API's replaceState method
history.replaceState({"obsolete":true},"");
// and _secondly_ push this state _one_more_time_ to the history
// which will solve the OP's desired "disable forward button" issue
history.pushState(event.state,"");
}
// case B: there is the other case that the user clicked "back" and
// encounters one of the duplicate history event entries that are
// "obsolete" now.
if( typeof event.state == "object"
&& event.state.obsolete === true)
{
//...in which case we simply go "back" once more
history.back()
// by this resolving the issue/problem that the user would
// be counter-intuively needing to click back multiple times.
// > we skip over the obsolete duplicates, that have been the
// the result of necessarily pushing a history state to "disable
// forward navigation"
}
},false);
回答by Rizwan Syed
Just use following jquery to disable forward button:
只需使用以下 jquery 禁用前进按钮:
$( document ).ready( function(){
history.pushState(null, document.title, location.href);
});
回答by Eugen Sunic
NOTE:
笔记:
- This code was tested and worked fine without showing any problems, however I would incentivize developers to test it more before going to production with the code.
- If HTML5 history.replaceState()is used anywhere in your application, the code below might now work.
- 这段代码已经过测试并且运行良好,没有出现任何问题,但是我会鼓励开发人员在将代码投入生产之前对其进行更多测试。
- 如果 HTML5 history.replaceState()在您的应用程序中的任何地方使用,下面的代码现在可能会起作用。
I created a custom function in order to disable the forward button.
我创建了一个自定义函数来禁用前进按钮。
Here is the code (it doesn't work with the hash routing strategy):
这是代码(它不适用于散列路由策略):
<script>
(function() {
// function called after the DOM has loaded
disableForwardButton();
})();
function disableForwardButton() {
var flag, loop = false;
window.addEventListener('popstate', function(event) {
if (flag) {
if (history.state && history.state.hasOwnProperty('page')) {
loop = true;
history.go(-1);
} else {
loop = false;
history.go(-1);
}
} else {
history.pushState({
page: true
},
null,
null
);
}
flag = loop ? true : !flag;
});
window.onclick = function(event) {
flag = false;
};
}
</script>
As Redrifpointed out in the comments of the accepted answer, the problem is that you have to double click the back button in order to navigate back to the page which is tedious and impractical.
正如Redrif在已接受答案的评论中指出的那样,问题在于您必须双击后退按钮才能导航回乏味且不切实际的页面。
Code explanation:each time you click the back button you need to create an additional history element so that the the current page which you are located on
points to the newly created history page. In that way there is no page to go forward to since the pushState
is the last state (picture it as the last element in the array) therefore your forward button will always be disabled.
代码说明:每次点击后退按钮都需要创建一个额外的历史元素,让你所在的当前页面指向新创建的历史页面。这样就没有要前进的页面,因为它pushState
是最后一个状态(将其描绘为数组中的最后一个元素),因此您的前进按钮将始终处于禁用状态。
The reason why it was mandatory to introduce the loop variable is because you can have a scenario where you go back to a certain page and the pushState
code occurs which creates the last history element and instead going back again you choose to click on some link again and again go back the previous page which now creates an additional history element. In other words, you have something like this:
必须引入循环变量的原因是因为你可以有一个场景,你回到某个页面,pushState
代码发生,它创建了最后一个历史元素,而不是再次返回,你选择再次点击某个链接,然后再次返回上一页,现在创建了一个额外的历史元素。换句话说,你有这样的事情:
[page1, page2, page2, page2]
[第1页,第2页,第2页,第2页]
now, once on page2
(index 3 element) and you click the back button again you will get to the page2
again index 1 element and you do not want that. Remember that you can have an array of x
page2
elements hence the loop false variable was introduced to resolve that particular case, with it you jump all the way from page2
to page 1 no matter how many page2
elements are their in the array.
现在,一旦打开page2
(索引 3 元素)并再次单击后退按钮,您将再次到达page2
索引 1 元素,而您不希望那样。请记住,您可以拥有一个x
page2
元素数组,因此引入了循环 false 变量来解决该特定情况,page2
无论page2
数组中有多少元素,您都可以一直跳到第 1 页。