网站开发主要学什么,东营优化公司,郑州网站建设 云极,青云 wordpress加速2019独角兽企业重金招聘Python工程师标准 History API 这里不细说每一个 API 的用法#xff0c;大家可以看 MDN 的文档#xff1a;https://developer.mozilla.org... 重点说其中的两个新增的API history.pushState 和 history.replaceState 这两个 API 都接收三… 2019独角兽企业重金招聘Python工程师标准 History API 这里不细说每一个 API 的用法大家可以看 MDN 的文档https://developer.mozilla.org... 重点说其中的两个新增的API history.pushState 和 history.replaceState 这两个 API 都接收三个参数分别是 状态对象state object — 一个JavaScript对象与用pushState()方法创建的新历史记录条目关联。无论何时用户导航到新创建的状态popstate事件都会被触发并且事件对象的state属性都包含历史记录条目的状态对象的拷贝。 标题title — FireFox浏览器目前会忽略该参数虽然以后可能会用上。考虑到未来可能会对该方法进行修改传一个空字符串会比较安全。或者你也可以传入一个简短的标题标明将要进入的状态。 地址URL — 新的历史记录条目的地址。浏览器不会在调用pushState()方法后加载该地址但之后可能会试图加载例如用户重启浏览器。新的URL不一定是绝对路径如果是相对路径它将以当前URL为基准传入的URL与当前URL应该是同源的否则pushState()会抛出异常。该参数是可选的不指定的话则为文档当前URL。 相同之处是两个 API 都会操作浏览器的历史记录而不会引起页面的刷新。 不同之处在于pushState会增加一条新的历史记录而replaceState则会替换当前的历史记录。 我们拿大百度的控制台举例子具体说是我的浏览器在百度首页打开控制台。。。 我们在控制台输入 window.history.pushState(null, null, https://www.baidu.com/?nameorange); 好我们观察此时的 url 变成了这样 我们这里不一一测试直接给出其它用法大家自行尝试 window.history.pushState(null, null, https://www.baidu.com/name/orange);
//url: https://www.baidu.com/name/orangewindow.history.pushState(null, null, ?nameorange);
//url: https://www.baidu.com?nameorangewindow.history.pushState(null, null, nameorange);
//url: https://www.baidu.com/nameorangewindow.history.pushState(null, null, /name/orange);
//url: https://www.baidu.com/name/orangewindow.history.pushState(null, null, name/orange);
//url: https://www.baidu.com/name/orange 注意:这里的 url 不支持跨域当我们把 www.baidu.com 换成 baidu.com 时就会报错。 Uncaught DOMException: Failed to execute pushState on History: A history state object with URL https://baidu.com/?nameorange cannot be created in a document with origin https://www.baidu.com and URL https://www.baidu.com/?nameorange. 回到上面例子中每次改变 url 页面并没有刷新同样根据上文所述浏览器会产生历史记录 这就是实现页面无刷新情况下改变 url 的前提下面我们说下第一个参数 状态对象 如果运行 history.pushState() 方法历史栈对应的纪录就会存入 状态对象我们可以随时主动调用历史条目 此处引用 mozilla 的例子 !DOCTYPE HTML
!-- this starts off as http://example.com/line?x5 --
titleLine Game - 5/title
pYou are at coordinate span idcoord5/span on the line./p
pa href?x6 onclickgo(1); return false;Advance to 6/a ora href?x4 onclickgo(-1); return false;retreat to 4/a?
/p
scriptvar currentPage 5; // prefilled by serverfunction go(d) {setupPage(currentPage d);history.pushState(currentPage, document.title, ?x currentPage);}onpopstate function(event) {setupPage(event.state);}function setupPage(page) {currentPage page;document.title Line Game - currentPage;document.getElementById(coord).textContent currentPage;document.links[0].href ?x (currentPage1);document.links[0].textContent Advance to (currentPage1);document.links[1].href ?x (currentPage-1);document.links[1].textContent retreat to (currentPage-1);}
/script 我们点击 Advance to 对应的 url 与模版都会 1反之点击 retreat to 就会都 -1这就满足了 url 与模版视图同时变化的需求 实际当中我们不需要去模拟 onpopstate 事件官方文档提供了 popstate 事件当我们在历史记录中切换时就会产生 popstate 事件。对于触发 popstate 事件的方式各浏览器实现也有差异我们可以根据不同浏览器做兼容处理。 hash 我们经常在 url 中看到 #这个 # 有两种情况一个是我们所谓的锚点比如典型的回到顶部按钮原理、Github 上各个标题之间的跳转等路由里的 # 不叫锚点我们称之为 hash大型框架的路由系统大多都是哈希实现的。 同样我们需要一个根据监听哈希变化触发的事件 —— hashchange 事件 我们用 window.location 处理哈希的改变时不会重新渲染页面而是当作新页面加到历史记录中这样我们跳转页面就可以在 hashchange 事件中注册 ajax 从而改变页面内容。 这里我在 codepen 上模拟了一下原理: http://codepen.io/orangexc/pe...点击预览 hashchange 在低版本 IE 需要通过轮询监听 url 变化来实现我们可以模拟如下 (function(window) {// 如果浏览器不支持原生实现的事件则开始模拟否则退出。if ( onhashchange in window.document.body ) { return; }var location window.location,oldURL location.href,oldHash location.hash;// 每隔100ms检查hash是否发生变化setInterval(function() {var newURL location.href,newHash location.hash;// hash发生变化且全局注册有onhashchange方法这个名字是为了和模拟的事件名保持统一if ( newHash ! oldHash typeof window.onhashchange function ) {// 执行方法window.onhashchange({type: hashchange,oldURL: oldURL,newURL: newURL});oldURL newURL;oldHash newHash;}}, 100);
})(window); 大型框架的路由当然不会这么简单angular 1.x 的路由对哈希、模版、处理器进行关联大致如下 app.config([$routeProvider, $locationProvider, function ($routeProvider, $locationProvider) {$routeProvider.when(/article, {templateUrl: /article.html,controller: ArticleController}).otherwise({redirectTo: /index});$locationProvider.html5Mode(true);
}]) 这套路由方案默认是以 # 开头的哈希方式如果不考虑低版本浏览器就可以直接调用 $locationProvider.html5Mode(true) 利用 H5 的方案而不用哈希方案。 总结 两种方案我推荐 hash 方案因为照顾到低级浏览器就是不美观多了一个 #两者兼顾也不是不可只能判断浏览器给出对应方案啦不过也只支持 IE8更低版本兼容见上文 这个链接的 demo 含有判断方法http://sandbox.runjs.cn/show/... 。同时给出 Github 仓库地址: minrouter推荐大家读下源码仅仅 117 行精辟 如果在上面链接测试时你的 url 里多了一个 #说明你的浏览器该更新啦。 文章出自 orange 的 个人博客 http://orangexc.xyz/ 转载于:https://my.oschina.net/ZhenyuanLiu/blog/1802350