在IE10中,HTML5的历史

分享于 

8分钟阅读

Web开发

  繁體 雙語

在10天内开发 Windows 8应用程序。

构建快速和功能性网站是一个挑战,大多数网络开发人员。 每次用户单击链接时加载新网页都是缓慢的。 动态获取所有内容将禁用后退按钮。 使用散列更好,但仍不理想。 通过添加对历史支持的adding, Windows 开发人员预览版中的IE 10消除了这种折衷。pushState 和api对后退按钮行为和呈现给用户的动态内容提供了细粒度的控制。 结合这些api可以帮助你改善站点的性能,而不会牺牲可用性。

如果你不熟悉HTML5历史的api,想象 pushState 是导航到另一个页面的动态等效项。 类似地,replaceState 很像 location.replace。 区别在于,这些api在更新会话历史记录时保持当前页面不变,而不是将状态存储到页面。pushStatereplaceState 都采用三个参数: 数据对象,标题和可选的URL。

history.pushState(data, title, url);
history.replaceState(data, title, url);

注意,pushStatereplaceState的标题参数被大多数浏览器( 包括 IE10 ) 忽略。 如果你愿意,你仍然可以提供这些信息,因为将来浏览器可以将它作为它的历史界面。

设置自定义 url

可以使用 pushStatereplaceState的URL参数来更新页面的URL,而无需进行导航。 要说明,请考虑使用哈希更改加载"http://www.contoso.com/index.html.",只能追加到 URL:

// Change to"http://www.contoso.com/index.html#about.html"location.hash = "about.html";

但是使用 pushStatereplaceState,你可以在站点上指向完全不同的页面,而无需实际去那里:

// Change to"http://www.contoso.com/about.html"history.pushState(null, "About", "/about.html");

确保服务器能够处理你创建的所有动态 url,这样favorites仍然可以工作。 你还可以向状态对象添加一些数据,这样以后无需解析完整的URL即可恢复状态:

history.pushState("about.html", "About", "/about.html");

协议。主机名和端口必须 MATCH,但路径。查询和 fragment 是定制的公平游戏。 这使得动态状态与url相关联,可以轻松地支持服务器,甚至在脚本被禁用时。 在保持用户体验不变的情况下,最终可以动态获取和只显示从页面更改到页面的数据。

还原保存状态

你应该在浏览历史记录( 例如当用户按下后退按钮时) 或者重新加载页面之后还原状态。 还原状态是通过侦听 popstate event 完成的。 当历史导航结果发生变化时,popstate event 会激发。 此时,可以通过 history.state 检索目标状态的数据对象。 在重新加载页面的情况下,popstate event 不会发生火灾,但是 history.state 仍然可以在任何时候访问。 这样,下面的代码可以在适当的时间还原状态:

function init() {/*.. . */// Handle page load and reloadloadState();// Listen for history navigations (e.g. the back button)window.addEventListener("popstate", loadState, false);
}
function loadState() {// Grab the data for the current state so we can restore itvar state = history.state;/*.. . */}
init();

存储复杂的动态数据

存储在状态中的数据对象可以大于字符串。 自定义JavaScript对象,甚至一些本机类型( 如 ImageData ) 也可以使用。 提供的数据使用结构化克隆算法保存,它保留了循环和对同一对象的多个引用的复杂关系。 这使得保存和恢复复杂的对象变得轻而易举,如所示。 在演示中,捕获画布的快照以使用如下代码创建撤消堆栈:

function init() {/*.. . */// Handle page load and reloadloadState();// Listen for history navigations (e.g. the back button)window.addEventListener("popstate", loadState, false);
}/*.. . */function stopDrawing() {// Take a snapshot of the current state as an ImageData instancevar state = context.getImageData(0, 0, canvas.width, canvas.height);
history.pushState(state, "");/*.. . */}
function loadState() {// Grab the data for the current state so we can restore itvar state = history.state;/*.. . */if (state) {// Restore the canvas to our saved ImageData statecontext.putImageData(state, 0, 0);
}
}

要更改这里状态以跟踪当前状态而不跟踪每个更改,你可以使用 replaceState 而不是 pushState

尺寸注意事项

HTML5历史将大量数据推到栈上,如果你不小心的话。 例如撤销演示 上面 存储每个状态的~0.5MB,如果画布更大,可以轻松使用更多的。 只要关联状态条目保留在会话历史中,这些数据就会消耗内存,这会在用户离开你的站点后很长时间。 存储的数据越多,浏览器就越早开始清除你的条目以节省空间。 另外,一些浏览器还强制对可以通过单调 pushState 或者 replaceState 存储的数据量进行硬限制。

跨浏览器-注意事项

一如既往,使用功能检测来处理跨浏览器支持的差异。 由于大多数HTML5历史涉及事件和属性,真正需要检测的新部分是对 pushStatereplaceState的调用:

function stopDrawing() {
 var state = context.getImageData(0, 0, canvas.width, canvas.height);
 if (history.pushState)
 history.pushState(state, "");
 /*.. . */}

这样的检测至少会使你的脚本在旧浏览器中不会出现故障。 根据你的场景,你可以能需要从全页导航开始,并在HTML5历史记录支持时升级到动态内容。 或者,可以使用历史框架或者 polyfill插件保持后退按钮,但记住不是所有的东西都能被模拟。 例如通过 pushStatereplaceState,对URL的路径和查询组件的动态控制只能通过实现。

注意,有些浏览器支持早期的HTML5历史记录,其中有两个与当前草稿显著不同的差异:

  • 即使在页面加载期间,popstate 事件也会触发
  • history.state 属性不存在

为了支持这些浏览器,你可以回退到 popstate 事件本身中的状态信息。

包起来

总的来说,HTML5历史api为构建响应性和可用的网站提供了极大的灵活性。 对于遗留浏览器,现在可以使用这些api来取得巨大的效果。 开始使用 IE10 Windows 开发人员预览插件在中测试他们,并通过连接发送反馈。


相关文章