HTML5历史禁用转发按钮
HTML5 history disabling forward button
我正在使用HTML5 History API编写一个单页javascript应用程序。应用程序通过Ajax加载内容,并使用屏幕堆栈在前台屏幕上内部维护状态信息。
我想使用后退按钮启用导航,但从不希望启用前进按钮
几条快速信息:
- 用户应该只能返回,而不能前进
- 按下浏览器后退按钮关闭用户所在的当前页面屏幕并重新加载上一个页面
- Project仅针对最新版本的Chrome,因此其他浏览器的实现并不重要
- 我只使用原生JavaScript和jQuery,我想在没有History.js的情况下完成这项工作
当我加载一个新屏幕时,我运行以下行:
history.pushState(screenData, window.document.title, "#");
我通过jQuery:绑定到popstate事件
$(window).bind("popstate", function(event) {
if (event.originalEvent.state != null) {
// Logic that loads the previous screen using my screen stack
}
});
我的应用程序的历史记录管理正在工作,但是当我返回时,前进按钮被启用。我需要弄清楚如何在popstate
事件上从history
中删除数据。
我可以使用replaceState执行此操作吗?我不知道该怎么做。。。
接受的答案解决了禁用转发按钮的问题,但却产生了一个新的令人讨厌的问题"导航回的页面"被重复插入到历史记录中(如答案注释中所示)。
以下是如何解决"禁用的前进按钮"问题,以及如何避免"重复"后退按钮问题。
//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);
坏零件
要真正禁用转发按钮,您必须能够删除浏览器历史记录,这是所有javascript实现都不允许的,因为它允许网站删除整个历史记录,而这永远不符合用户的利益。
好零件
这有点棘手,但我想如果你想做自定义历史记录,它可以工作。您可以在popstate
事件中使用pushState
,使实际页面成为最顶部的历史记录条目。我想你处理历史的方式,你的窗口永远不会卸载。这允许您自己跟踪用户历史:
var customHistory = [];
像以前一样,使用history.pushState(screenData, window.document.title, "#");
推送您加载的每个页面。只有您也将状态添加到自定义历史记录中:
history.pushState(screenData, window.document.title, "#");
customHistory.push({data: screenData, title: window.document.title, location: '#'});
现在,如果您有一个popstate
事件,您只需弹出自定义历史记录并将其推送到最上面的条目:
window.onpopstate = function(e) {
var lastEntry = customHistory.pop();
history.pushState(lastEntry.data, lastEntry.title, lastEntry.location);
// load the last entry
}
或者在jQuery 中
$(window).on('popstate', function(e) {
var lastEntry = customHistory.pop();
history.pushState(lastEntry.data, lastEntry.title, lastEntry.location);
// load the last entry
});
只需使用以下jquery禁用转发按钮:
$( document ).ready( function(){
history.pushState(null, document.title, location.href);
});
注意:
- 然而,该代码经过测试,运行良好,没有出现任何问题我会鼓励开发人员在代码投入生产之前对其进行更多的测试
- 如果HTML5history.replaceState()在应用程序中的任何位置使用,下面的代码现在可能可以工作了
我创建了一个自定义功能来禁用前进按钮。
以下是代码(它不适用于哈希路由策略):
<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>
正如Redrif在接受答案的评论中指出的那样,问题是你必须双击后退按钮才能导航回页面,这既乏味又不切实际。
代码说明:每次单击后退按钮时,您都需要创建一个额外的历史元素,以便您所在的当前页面指向新创建的历史页面。这样就没有可前进的页面,因为pushState
是最后一个状态(将其想象为数组中的最后一个元素),因此您的前进按钮将始终被禁用。
之所以必须引入循环变量,是因为您可以在这样的场景中返回到某个页面,出现pushState
代码,该代码创建了最后一个历史元素,而不是再次返回,您选择一次又一次地单击某个链接,返回到上一个页面,该页面现在创建了一个额外的历史元素。换句话说,你有这样的东西:
[第1、第2、第2和第2页]
现在,在page2
(索引3元素)上单击一次,然后再次单击后退按钮,您将再次进入page2
索引1元素,但您不希望这样。请记住,您可以有一个x
page2
元素的数组,因此引入了循环false变量来解决该特定情况,使用它,无论数组中有多少page2
元素,您都可以从page2
跳到第1页。
- 创建一个类似链接的按钮,并通过Javascript函数打开一个新的弹出窗口
- 正在添加'X'按钮,在文本字段旁边使用javascript
- 多个单选按钮组相互干扰
- JavaScript下拉菜单-点击按钮并根据所选值重定向到url
- Javascript按钮下拉列表
- jquery试图按名称获取按钮位置
- 漂亮照片图片库中的Facebook赞按钮
- 扩展移相器按钮类不工作
- 通过单击表单中的按钮,在代码生成中使用javascript生成字母数字代码
- 单击按钮以等待单击按钮
- 剑道UI内联编辑:如何在点击其他按钮时隐藏按钮
- 单击按钮后如何逐个调用分区,上一个分区将隐藏
- HTML5历史禁用转发按钮
- JavaScript 哈希更改转发按钮上的奇怪问题
- 如何使用 HTML5 历史记录使转发按钮在此示例中工作
- 如何使用jquery添加转发和收藏按钮
- 带有框架的浏览器中的按钮返回(历史记录转发不起作用)
- 如何停止浏览器转发按钮重定向到页面
- event.preventDefault ();导航,同时仍允许返回&要使用的转发按钮
- 单击按钮执行类似于表中“转发”的操作