利用HTML5的History API

  HTML5 History
API提供了一种意义,能让开发人员在不刷新整个页面的情形下修改站点的URL。那个职能很有用,例如通过一段JavaScript代码局地加载页面的内容,你指望通过改动近来页面的URL来影响出页面内容的成形,那时该功效可以派上用场。

  举个例子,当用户从首页进入协理页面时,大家因而Ajax来加载帮助页面的情节。然后这几个用户又转到产品页面,我们需求再一回经过Ajax请求来替换页面的内容。当用户想分享页面的URL时,通过History
API,大家可以变更页面的URL来反应内容的改动,那样不管是用户分享依然封存的URL都能和页面的情节对应起来。

基本知识

  要查阅那么些API提供了什么样作用万分简单,打开浏览器的Developer
Tools工具面板,然后在console中输入history。如若你的浏览器帮助History
API,你将会看出那一个目的上边附带了不少主意。

图片 1

  注意其中的pushStatereplaceState那七个情势。大家可以在console中举办部分粗略的测试,来探望当大家运用那多少个法鸡时URL会爆发什么变动。稍后我们将分析那两个点子中的所有参数,现在大家只必要关怀最终一个参数:

history.replaceState(null, null, 'hello');

  上面代码中的replaceState办法改变了当前页面的URL,在前面添加了一个’/hello’。然而并没有生出任何request请求,当前窗口依旧停留在前头的页面。可是那里有个难点,当您点击浏览器的退化按钮时,页面并不会回退到我们由此replaceState艺术修改以前的非凡URL,而是一向回退到了上一个页面(即我们进入到这一个页面之前的分外页面)。那是因为replaceState艺术不会修改浏览器的history,它只是简短地更迭了地方栏中的URL。

  要化解那个标题大家须要选取pushState方法:

history.pushState(null, null, 'hello');

  现在再点击浏览器的退化按钮,你会意识它和您预想的功效同样。因为pushState措施将我们传给它的URL添加到浏览器的history中,从而改变了浏览器的history。即使咱们将别的一个全体的站点URL传递给它会时有暴发哪些动静吗?例如大家在baidu.com的首页进行测试,然后在console中输入上面的情节。

history.pushState(null, null, 'https://twitter.com/hello');

  浏览器会报错。因为传递给pushState艺术的URl必须和脚下页面的URL属于同一个源(即无法跨域),否则会有很大的安全漏洞,开发人士可能会借用该意义来自欺欺人用户,让她们以为温馨是在走访一个通通分歧的站点,而实际并非如此。

  来探望传递给pushState办法的保有参数:

history.pushState([data], [title], [url]);
  1. 率先个参数用来传递大家需求的数码,当页面的情况暴发变化时大家得以接受到该数据。如用户点击浏览器的倒退和前进按钮。要求注意的是在Firefox中只同意传递最多640K的多寡。
  2. 其次个参数title是一个字符串,可是为止到当前,大致拥有的浏览器都忽视该参数。
  3. 末段一个参数是我们想要替换的URL。

简短回看一下

  那个History
API最重大的功效就是不重复加载页面。以往咱们只可以通过变更window.location的值来修改当前页面的URL,但是那会促成整个页面被重复加载。如果您改改的只是URL中的hash,则不会导致页面被刷新。 

  使用旧的hashbang艺术可以变更页面的URL而不刷新页面。知名的推特(TWTR.US)就是使用的该格局,不过也广受诟病,毕竟hash在location中并不被当做一个真正的资源来对待。

  作为History
API的初期匡助者,推特(Twitter)后来撇下了传统的hashbang办法。在二零一二年,推文(Tweet)的公司介绍了他们的新方法,并列出了内部的局地难点还要还详细地介绍了各浏览器应该怎么着兑现该标准。

一个使用pushState和Ajax的例子

https://css-tricks.com/examples/State/

  在该示例中,大家愿意用户通过大家的网站找到电影捉鬼敢死队(一部美利坚合众国电影)中的影星。当用户挑选一个图片时,我们必要在人世突显该影星对应的文字描述,同时给该图片一个被选中的效应。当点击后退按钮时,页面应该切换来上一个被选中的图样状态,同时图片下方的文字也要一并切换。当点击前进按钮时也同样。

  那里有一个职能图:

图片 2

  那么些示例的HTML代码万分简单:div.gallery中涵盖了有着的链接,每个链接里有一个图片。接下来大家放置了一个空的div.content,用来存放在当艺人图片被点击时呈现在下放的文字。

<div class="gallery">
  <a href="https://cdn.css-tricks.com/peter.html">
    <img src="bill.png" alt="Peter" class="peter" data-name="peter">
  </a>
  <a href="https://cdn.css-tricks.com/ray.html">
    <img src="ray.png" alt="Ray" class="ray" data-name="ray">
  </a>
  <a href="https://cdn.css-tricks.com/egon.html">
    <img src="egon.png" alt="Egon" class="egon" data-name="egon">
  </a>
  <a href="https://cdn.css-tricks.com/winston.html">
    <img src="winston.png" alt="Winston" class="winston" data-name="winston">
  </a>
</div>

<p class="selected">Ghostbusters</p>
<p class="highlight"></p>

<div class="content"></div>

  假使没有JavaScript该页面仍是可以健康干活,点击图片可以跳转到对应的页面,然后点击后退按钮也得以回来从前的页面。这是为着考虑页面的可访问行和优雅降级。

  接下去我们要添加JavaScript代码了。大家因此event
propagation
给div.gallery元素中的每一个link添加一个事件处理程序,像那样:

var container = document.querySelector('.gallery');

container.addEventListener('click', function(e) {
  if (e.target != e.currentTarget) {
    e.preventDefault();
    // e.target is the image inside the link we just clicked.
  }
  e.stopPropagation();
}, false);

  在if语句中,我们得到到被入选图片的data-name属性的值,然后将’.html’添加到前面拼成一个要拜访的页面地址,并将其当做第多个参数传递给pushState办法(但是在真实的例证中大家可能会在Ajax请求成功之后才会去修改URL)。

var data = e.target.getAttribute('data-name'),
url = data + ".html";
history.pushState(null, null, url);

// 此处更改当前的classes样式
// 然后使用data变量的值更新
// 并通过Ajax请求.content元素的内容
// 最后再更新当前文档的title

(当然,此处大家也得以平素利用link的href属性的值)

  我将忠实代码中的内容都替换成注释了,这样我们可以只关切pushState主意的使用。

  现在大家点击图片,URL和Ajax请求的始末会被自动更新,不过当大家点击后退按钮时并不会回退到后面入选的艺人图片。那里我们还索要在用户点击后退和升华按钮时行使别的一个Ajax请求来更新内容,并再四次选取pushState艺术来更新页面的URL。

  大家使用pushState主意中的第二个参数(其中的state)来保存情况新闻:

history.pushState(data, null, url);

  上边代码中的data参数在popstate事件触发时可以被拿走到。当浏览器的落伍和进化按钮被点击时会触发popstate事件。

window.addEventListener('popstate', function(e) {
  // e.state表示上一个被点击的图片的data-attribute
});

  大家得以经过该参数传递一些大家要求的信息,例如在该示例中大家将事先入选的捉鬼敢死队的影星作为参数传递给requestContent办法,在该方法中,我们利用jQuery的load方法开展一次Ajax请求。

function requestContent(file) {
  $('.content').load(file + ' .content');
}

window.addEventListener('popstate', function(e) {
  var character = e.state;

  if (character == null) {
    removeCurrentClass();
    textWrapper.innerHTML = " ";
    content.innerHTML = " ";
    document.title = defaultTitle;
  } else {
      updateText(character);
      requestContent(character + ".html");
      addCurrentClass(character);
      document.title = "Ghostbuster | " + character;
  }
});

  若是用户点击了影星Ray的图样,event
listener会被触发,然后在pushState事件中保留图片的data属性的值。当用户点击此外一个图形,并点击了浏览器的滞后按钮,此时popstate事件会被触发,从而再度加载ray.html页面。

  那代表怎么着啊?当大家点击一个影星的图形然后将被更改的URL分享出去,用户访问那一个URL时对应的HTML文件会被活动加载进来。这会带来一些更好的用户体验,并保管了URL和页面内容的一致性从而减弱了于是而带给用户的一对疑心。

  上边的演示只是简短地通过jQuery来动态加载内容,我们本来也足以在pushState艺术中传递一些越发错综复杂的靶子。但是这几个例子已经能充裕表达难点并支持大家初叶读书怎么使用History
API的法力。大家先要学会走,然后才能跑。

下一步

  假使大家想大范围地选拔那种技能,我们理应考虑使用部分专有的工具,例如pjax 它是一个jQuery的插件,使用它可以大大升高大家还要利用Ajax和pushState艺术进行付出的快慢,不过它只帮衬这么些使用History
API接口的现代浏览器。

  History
JS
可以匹配旧浏览器,对于不辅助History
API接口的浏览器,它依然选择旧的URL hash的措施来兑现均等的功力。

有关URLs

  那里我专门引用了凯尔 Neath有关URLs的辨证:

URLs是一个通用的定义,它可以干活在Firefox, Chrome, Safari, Internet
Explorer, curl, wget,甚至在您的金立,
Android以及便签纸上。它是web中的一个通用的语法。不要觉得那是理所当然的。任何一个稍微懂点技术的用户都得以浏览你的行使的90%上述的一对而不用去刻意记住那多少个URL的结构。要兑现那样的功能,你需求考虑URLs的实用性。

  那意味无论你想要举行哪些的hacks或质量优化,作为web开发人士,你应当尊崇URL。而随着HTML5
History API的增援,大家可以轻松地化解诸如上述示范中的一些问题。

科普难点

  • 将Ajax请求的地址嵌入到a标记的href属性中平时是个不错的主意。
  • 有限帮衬在JavaScript的click事件处理程序中return
    true,那样当有人使用中键点击或指令点击时不会招致程序被意外覆盖。

补充

浏览器辅助

Chrome Safari Firefox Opera IE Android iOS
31+ 7.1+ 34+ 11.50+ 10+ 4.3+ 7.1+

初稿地址:https://css-tricks.com/using-the-html5-history-api/

相关文章