pushstate

时间:2024-10-13 23:22:19编辑:分享君

了解什么是hash路由和history路由

hash 路由:监听 url 中 hash 的变化,然后渲染不同的内容,这种路由不向服务器发送请求,不需要服务端的支持;
history 路由:监听 url 中的路径变化,需要客户端和服务端共同的支持;
我们一步步实现这两种路由,来深入理解下底层的实现原理。我们主要实现以下几个简单的功能:

1.监听路由的变化,当路由发生变化时,可以作出动作;
2.可以前进或者后退;
3.可以配置路由;

当页面中的 hash 发生变化时,会触发hashchange事件,因此我们可以监听这个事件,来判断路由是否发生了变化。

事件hashchange只会在 hash 发生变化时才能触发,而第一次进入到页面时并不会触发这个事件,因此我们还需要监听load事件。

在 history 路由中,我们一定会使用window.history中的方法,常见的操作有:

back():后退到上一个路由;
forward():前进到下一个路由,如果有的话;
go(number):进入到任意一个路由,正数为前进,负数为后退;
pushState(obj, title, url):前进到指定的 URL,不刷新页面;
replaceState(obj, title, url):用 url 替换当前的路由,不刷新页面;
调用这几种方式时,都会只是修改了当前页面的 URL,页面的内容没有任何的变化。但前 3 个方法只是路由历史记录的前进或者后退,无法跳转到指定的 URL;而pushState和replaceState可以跳转到指定的 URL。如果有面试官问起这个问题“如何仅修改页面的 URL,而不发送请求”,那么答案就是这 5 种方法。

如果服务端没有新更新的 url 时,一刷新浏览器就会报错,因为刷新浏览器后,是真实地向服务器发送了一个 http 的网页请求。因此若要使用 history 路由,需要服务端的支持。

当我们用 history 的路由时,必然要能监听到路由的变化才行。全局有个 popstate 事件,别看这个事件名称中有个 state 关键词,但 pushState 和 replaceState 被调用时,是不会触发触发 popstate 事件的,只有上面列举的前 3 个方法会触发

针对这种情况,我们可以使用 window.dispatchEvent 添加事件:

然后就可以添加对这两个方法的监听了:


hash和history两种路由模式的区别

hash 就是指 url 尾巴后的 # 号以及后面的字符 。这里的 # 和 css 里的 # 是一个意思。hash 也 称作 锚点,本身是用来做页面定位的,她可以使对应 id 的元素显示在可视区域内。 由于 hash 值变化不会导致浏览器向服务器发出请求 ,而且 hash 改变会触发 hashchange 事件,hashChange事件中获取当前的hash值,并根据hash值来修改页面内容,则达到了前端路由的目的。浏览器的进后退也能对其进行控制,所以人们在 html5 的 history 出现前,基本都是使用 hash 来实现前端路由的。 hash模式背后的原理是onhashchange事件,可以在window对象上监听这个事件: 关键的一点是,因为hash发生变化的url都会被浏览器记录下来,从而你会发现浏览器的前进后退都可以用了,同时点击后退时,页面字体颜色也会发生变化。这样一来,尽管浏览器没有请求服务器,但是页面状态和url一一关联起来。 已经有 hash 模式了,而且 hash 能兼容到IE8, history 只能兼容到 IE10,为什么还要搞个 history 呢? 首先,hash 本来是拿来做页面定位的,如果拿来做路由的话,原来的锚点功能就不能用了。其次, hash 的传参是基于 url 的 ,如果要传递复杂的数据,会有体积的限制,而 history 模式不仅可以在url里放参数,还可以将数据存放在一个特定的对象中 。 hash的hashchange,你只能改变#后面的url片段,而history api则给了前端完全的自由。 通过pushstate把页面的状态保存在state对象中,当页面的url再变回这个url时,可以通过event.state取到这个state对象,从而可以对页面状态进行还原,其实滚动条的位置,阅读进度,组件的开关的这些页面状态都可以存储到state的里面。 在hash模式下,前端路由修改的是#中的信息,而浏览器请求时是不带它玩的,所以没有问题.但是在history下,你可以自由的修改path,当刷新时,如果服务器中没有相应的响应或者资源,会分分钟刷出一个404来。 history 模式改变 url 的方式会导致浏览器向服务器发送请求,这不是我们想看到的,我们需要在服务器端做处理:如果匹配不到任何静态资源,则应该始终返回同一个 html 页面。 hash模式和history模式的区别

上一篇:泰国最大的岛

下一篇:没有了