history.go方法改变页面的应用

  Go 方法

  如果您想向前或向后移动 n 个页面,那么您可以使用 go 方法:

  <pre class="has">history.go(-2) // 倒退 2 页 history.go(2) // 前进 2 页</pre>

  所以history.go(1)和history.forward()效果是相同的,history.go(-1)和history.go(-1)效果是相同的。history.go方法的默认值为 0,如果不传任何数字,则当前页面会被刷新。

  <pre class="has">window.history.go(0) window.history.go()</pre>

  PushState

  你也可以使用pushState和replaceState方法改变页面的 URL。pushState会改变页面的 URLjs查看浏览器历史记录,并将改变后的 URL 添加到history对象的 URL 栈顶部。语法如下:

  <pre class="has">history.pushState(state, title, [url][1])</pre>

  参数 state 是状态数据,它将被存储在 history.state 变量中。参数 title 是标题文本,不过它对大多数浏览器都没有效果,所以一般传空字符串("")或传 null 就可以了。

  让我们在控制台中尝试一下,在执行之前,比如打开 baidu.com,然后在控制台输入:

  <pre class="has">history.pushState(&#39;123&#39;, &#39;&#39;, &#39;new-url&#39;)</pre>

  执行上面的代码后,它会将页面地址栏中的 URL 改为 baidu.com/new-url,同时将 URL 添加到 history 对象中。此时检查history.length会增加 1。

  除此之外,我们还可以为每个 URL 存储状态(当前页面的数据)。在上面的例子中,你会把 "123" 存储在history.state变量中,当你返回到这个页面时,你就可以history.state再次拿到到这些数据。例如:

  <pre class="has">history.pushState(&#39;temp data 1&#39;, &#39;title&#39;, &#39;new-url-1&#39;) history.state //"temp data 1" history.pushState(&#39;temp data 2&#39;, &#39;title&#39;, &#39;new-url-2&#39;) history.state //"temp data 2" history.back() history.state // "temp data 1"</pre>

  每当通过 pushState 返回到之前被添加到历史记录的页面时,浏览器就会触发一个名为 popstate 的事件,并将 state 数据作为参数。比如在浏览器打开一个新标签页,进入某个网页(比如 baidu.com),先监听 popstate 事件:

  <pre class="has">window.addEventListener(&#39;popstate&#39;, (e) => console.log(e))</pre>

  然后调用 pushState:

  <pre class="has">history.pushState({ name: &#39;test1&#39; }, &#39;title&#39;, &#39;test1&#39;)</pre>

  然后按下返回按钮,popstate 事件就会被触发,你可以在监听事件中查看打印出来的数据。在打印的数据中,可以找到 history.state 的值。

  注册 pushState 中的 url 可以是完整的 url,但必须和当前页面是相同的域名,否则会抛出跨域异常。

  浏览器还有一个replaceStateAPI,和pushState的区别是,它只改变了 URL,不会将 URL 添加到历史记录,这里就不再累述了。

  实例演示

  现在我们做一个小的网页应用,这个应用将实现如下功能:

  显示用户列表

  可以通过下拉框筛选“先生”和“女士”

  当下列列表发生变化时,URL 也会相应的变化

  我们先不关心 history API,先实现功能。下面是 html 关键代码:

  <pre class="has"> 全部option> 先生option> 女士option> select> 张先生li> 李女士li> 王女士li> ul></pre>

  下面是 javascript 关键代码:

  <pre class="has">let selectBox = document.getElementById(&#39;selectBox&#39;) let usersList = document.getElementById(&#39;usersList&#39;) selectBox.addEventListener(&#39;change&#39;, onSelectBoxChange) function onSelectBoxChange(ev) { let val = this.value filterList(val) } function filterList(val) { let users = usersList.children for (let i = 0; i < users.length; i++) { let user = users[i] let gender = user.getAttribute(&#39;gender&#39;) if (gender === val || val === &#39;both&#39;) { user.style.display = &#39;&#39; } else { user.style.display = &#39;none&#39; } } }</pre>

  实现后的效果如下:

  当修改下拉列表时,为了使浏览器地址也发生变化,需要使用pushSate方法:

  <pre class="has">function onSelectBoxChange(ev) { let val = this.value filterList(val) history.pushState({ gender: val }, null, val) }</pre>

  当我们在下拉框选择“先生”时,浏览器的地址会变成:localhost:5000/male。效果如下:

  此时会有个问题,当我们点击前进/后退时,浏览器地址变了js查看浏览器历史记录,但对应的数据却不对。因此,当进行前进/后退时,我们需要监听 popstate 重新过滤数据:

  <pre class="has">window.addEventListener(&#39;popstate&#39;, onPopState) function onPopState(ev) { let state = ev.state filterList(state.gender) }</pre>

  我们还需要处理页面刷新的问题。当刷新页面时,历史记录不会改变,history.state的状态值也保持不变。所以我们可以从history.state中取出当前的状态数据,利用state.gender的值就可以在load事件中来过虑出当前 URL 对应的用户列表:

  <pre class="has">window.addEventListener(&#39;load&#39;, function () { let gender = history.state ? history.state.gender : &#39;both&#39; filterList(gender) })</pre>

  这是个简单的示例,你也可以继续进一步优化。今天的分享就到这里,有问题请在下面留言哦~~

文章由官网发布,如若转载,请注明出处:https://www.veimoz.com/1593
0 评论
723

发表评论

!