如何使用浏览器历史api在返回时调用函数&单击前进按钮
How to use the browser history api to invoke a function when back & forward buttons are clicked?
假设我有一个页面:http://www.example.com/foo.htm
我想放置一个按钮,显示页面的一部分并隐藏另一部分,例如:
HTML-
<p class="stepOne">Hi, I'm step one. <a id="doit" href="#">Go to Step 2</a></p>
<p class="stepTwo">And I'm step two</p>
JS-
$('#doit').on('click', function(){
$('.stepOne').hide();
$('.stepTwo').show();
});
我的问题是:在用户单击"转到第二步"链接后,当用户单击浏览器的后退按钮时,我如何使用HTML历史api来隐藏第二步并显示第一步?
让我们把浏览器的历史记录看作一个堆栈。每次单击链接或向前导航时,都会将项目推到堆栈上。每当你想后退时,浏览器就会从堆栈中"弹出"一个项目。让我们将这些项中的每一项称为"状态"。浏览器会保存一些关于每个状态的信息,如URL、标题和"状态对象"(如果需要(。总之,当你前进时,新的状态会被推到堆栈中,而当你想后退时,最近的状态会从末尾弹出。
考虑到这一点,您想要实现的是手动将状态推送到堆栈上。通过这种方式,用户实际上并不在任何地方导航——HTML5历史API使我们能够在不更改页面的情况下推送/弹出/替换浏览器历史堆栈中的状态。
在click
事件侦听器中,您需要添加一些代码来向历史堆栈添加新状态。类似于:window.history.pushState({}, 'Step 2', '/step-2');
这将向历史堆栈添加一个新状态,并且您的URL将更改为/step-2
。现在,当您单击后退按钮时,它将从堆栈中pop
此状态,并返回到以前的状态。这两种状态都是相同的页面和DOM。
现在,当用户在浏览器中导航back
时,您必须考虑更改页面上这两个项目的可见性。这可以通过每次状态更改时在window
上触发的popstate
事件来检测。看看我举的这个庞克的例子。在点击事件监听器中,DOM被更改(隐藏和显示项目(,并且一个新的历史状态被推送到堆栈上,其中一个整数表示应该在该历史状态中显示哪个步骤。然后,在popstate
事件中,用户向后导航,在事件对象中,我们得到了弹出的状态。我们知道我们应该向后走,所以如果弹出的步骤是步骤2,我们将显示步骤1。
我对html做了一些小的修改,以便能够简洁地编写代码,这里有很大的模块化空间——不需要在javascript中硬编码步骤号。
这有道理吗?
下面的代码用于解决您在问题中提出的问题。使用HTML5历史Api,我们像这样扩展您的示例代码(注释描述了添加到代码中的A、B、C三个部分(
// Part A: For the initial "step 1" we create a history state object
var historyStateObjectStep1 = {"step":"one"};
// which we tell the browser to use to represent the current state/step in
// history. Since the browser had an idea about the "now"-state in history
// already, which is now "replaced" this is done via history.replaceState
history.replaceState(historyStateObjectStep1,"");
// Part B: To react to history events like back-/forward-button pressed,
// we have to setup an EventListener for the "history"-popstate event.
window.addEventListener("popstate",function(event){
// the history state objects we have setup via replaceState/pushState
// before are provided via the event objects property event.state
var historyStateObject = event.state;
// if state object is "object" and as setup has an attribute "step"
// with value "one"
if(typeof historyStateObject == "object"
&& historyStateObject.step === "one" )
{
// then it means that the user used the browsers "back" button
// and since we are now at history state "stepOne" we show it
$('.stepOne').show();
// and hide stepTwo
$('.stepTwo').hide();
}
// in else case that the historyStateObject is an object and has an
// attribute step set to the value "two" then...
else if(typeof historyStateObject == "object"
&& historyStateObject.step === "two" )
{
//...the user has used the browser buttons (forward/back) to reach
// the state "stepTwo", hence we show it and
$('.stepTwo').show();
// hide stepOne
$('.stepOne').hide();
}
},false);
$('#doit').on('click', function(){
// PART C: Upon clicking the "doit"-button (to go to step two), we
// create an history state object for step 2
var historyStateObjectStep2 = {"step":"two"};
// which we then insert intto the browser history, or in other words
// "push" the newly created historyStateObejectStep2 to the history, via
// the function history.pushState
history.pushState(historyStateObjectStep2,"");
$('.stepOne').hide();
$('.stepTwo').show();
});
- 使用clickToggle并在单击另一个元素时关闭元素
- 单击时将焦点更改为元素
- 单击F5时如何停止页面加载
- 通过单击表单中的按钮,在代码生成中使用javascript生成字母数字代码
- 在单击任何位置时隐藏元素,而不检查每次DOM单击
- 单击jquery清除输入值
- 通过单击主菜单外部关闭子菜单'不适用于IE,但适用于Firefox&铬
- 在进行动画时防止多次单击(stopPropagation&:animated)
- 用于两个功能的Javascript按钮.提交&单击
- 获取已单击链接的ID&更改其类别
- 谷歌地图计算不同距离的内容框变化&单击按钮
- 触发器Ctrl+z&Ctrl+y键单击按钮
- 添加&单击按钮时减去TR(ID+1)
- 使用$.Ajax进行GET、Update&单击按钮时将JSON放回服务器
- 如何使用浏览器历史api在返回时调用函数&单击前进按钮
- 如何改变“;添加到购物车”"添加到愿望列表”&"将该产品“;单击时按钮边框颜色
- 显示&单击后隐藏元素
- 我该如何打开我的手风琴&字形图标在单击时旋转,在重新单击时反转
- 切换多个分区&单击时停用
- 点击即显示'Div 1'&隐藏'Div 2'&单击同一按钮显示'Di