假设我有一个页面: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();
});
我的问题是: 在用户单击“转到步骤2”链接后,如何在用户单击浏览器的后退按钮时使用HTML历史记录api隐藏第二步并显示第一步?
答案 0 :(得分:0)
让我们将浏览器的历史视为一个堆栈。每次单击链接或向前导航时,都会将项目推送到堆栈中。无论何时你想要倒退,浏览器都会弹出&#34;一个项目离开堆栈。让我们将这些项目中的每一个称为“状态”#34;浏览器保存有关每个州的一些信息,例如URL,标题和状态对象&#34;如果需要的话。总而言之,当你前进时,新状态会被推到堆栈中,当你想要倒退时,最新状态会从最后状态弹出。
考虑到这一点,你想要完成的是手动将状态推入堆栈。通过这种方式,用户实际上无法在任何地方导航 - HTML5 History API使我们能够在不更改页面的情况下推送/弹出/替换浏览器历史堆栈中的状态。
在click
事件监听器中,您需要添加一些代码以向历史堆栈添加新状态。类似于:window.history.pushState({}, 'Step 2', '/step-2');
这会向历史记录堆栈添加新状态,您的网址将更改为/step-2
。现在,当您单击后退按钮时,它将pop
从堆栈状态退出并返回到先前的状态。两个状态都是相同的页面和DOM。
现在,当用户在浏览器中导航back
时,您必须考虑更改页面上这两个项目的可见性。这可以通过每次状态更改时在popstate
上触发的window
事件来检测。看看this plunkr example我放在一起。在click事件侦听器中,DOM被更改(隐藏并显示项目),并且新的历史状态被推入堆栈,其中一个整数表示应该在该历史状态中显示哪个步骤。然后,在popstate
事件上,用户向后导航,在事件对象中,我们将获得正在弹出的状态。我们知道我们应该倒退,所以如果弹出的步骤是第2步,我们将要显示第1步。
我对html进行了一些小改动,以便能够简洁地编写代码,并且这里有很多模块化空间 - 无需在javascript中对步骤编号进行硬编码。
这有意义吗?
答案 1 :(得分:0)
以下代码可以解决您在问题中提出的问题。使用Using MySQL UNIQUE Index To Prevent Duplicates,我们可以像这样扩展您的示例代码(注释描述了已添加到您的代码中的三个部分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();
});