zoukankan      html  css  js  c++  java
  • [翻译]HTML5

            原文为:https://w3c.github.io/html/browsers.html#session-history-and-navigation

    一、浏览上下文的会话历史记录

            浏览上下文中的文档(Document)序列构成了它的会话历史。每一个浏览上下文,包含嵌套的浏览上下文,拥有各自独特的会话历史。浏览上下文的会话历史表示为一个平坦的会话历史入口的列表。会话历史列表中的每个条目,至少包含一个URL,可能还有一个序列化的状态(state object),一个标题,一个文档对象,表单数据,一个滚动位置信息和其他相关信息。

            注意:会话历史列表中的每个条目第一次被创建时,拥有一个文档。然而,当文档未激活时,它可能用来描述一个空的资源。如果用户代理发现自己不得不重新激活文档,URL和其他在会话历史列表条目的数据被用来传递给新的文档,并有该文档去替换原来的文档。

            注意:会话历史列表条目中的标题不需要与当前文档的标题有任何关系。一个会话历史列表条目的标题是为了解释那一时刻文档的状态,以让用户能够导航文档的历史。

            当用户(或脚本)在页面之间导航时,没有相关序列化状态的URL将被添加到会话历史记录中。

            每个在浏览上下文的回话历史中的Document对象与一个唯一的History对象相关联,它们必须以相同的基础会话历史为模板。

            Window接口的history属性必须返回根据Window对象最新的Document来实现的History接口的对象。

            序列化状态是表示用户界面状态的对象的序列化 (通过 StructuredSerializeForStorage)。有时, 我们非正式地将“状态对象”表示为作者提供的用户界面状态,或者是通过反序列化 (通过 StructuredDeserialize) 已被序列化的状态所创建的对象。

            页面可以将序列化状态添加到会话历史记录中。然后,当用户 (或脚本) 返回到历史记录中时,这些将再被反序列化并返回到脚本中,从而使作者即使在单页应用中也可以使用 “导航” 功能。

             注意:使用序列化状态主要有两个目的:首先,在 URL 关联的状态中存储之前已解析的描述,以便在简单的情况下,作者不需要再进行解析 (尽管您仍然需要解析需要处理的用户传递的URL,所以它只是一个小的优化),第二,作者可以存储的状态,但不会存储在 URL中,它只适用于当前的Document实例,如果一个新的文档打开,它需要重新建立。

            后面的一个例子是跟踪精确的坐标,以在特定位置使用动画弹出 div,如果用户返回,可以在相同的位置使用动画。或者,它可用一个指针指向数据缓存,其中存储通过URL中的信息从服务器上获取的数据,以便在前进和后退时不需要再次从服务器中获取信息。

            在任何时候,会话历史记录中的条目都是当前条目。这是表示浏览上下文活动文档的条目。至于哪个条目是当前条目是由本规范中定义的算法 (例如,在会话历史遍历期间) 更改的。

    二、History接口

    enum ScrollRestoration { "auto", "manual" }'
    interface History {
    
      readonly attribute unsigned long length;
    
      attribute ScrollRestoration scrollRestoration;
    
      readonly attribute any state;
    
      void go(optional long delta = 0);
    
      void back();
    
      void forward();
    
      void pushState(any data, DOMString title, optional DOMString? url = null);
    
      void replaceState(any data, DOMString title, optional DOMString? url = null);
    
    };

    window.history.length

      返回会话历史列表中条目数量

    window.history.state

      返回当前的状态对象

    window.history.go([delta])

      在会话历史集中向后或向前步进指定的量
      如果delta为0则重新加载当前页面
      如果delta超过了允许的范围,什么也不做

    window.history.back()

      在会话历史集中向后步进1
      如果没有前一页,则什么也不做

    window.history.forward()

      在会话历史集中向前步进1
      如果没有下一页,则什么也不做

    window.history.pushState(data, title [,url])

      将给定的数据,按指定的标题及可选的URL压入会话历史中

    window.history.replaceState(data, title [,url])

      更新会话历史中的当前条目,使之持有给定的数据、标题和可选的URL

            历史记录集是指共享History对象的顶级浏览上下文的那些活动Document对象所持有的浏览上下文中的会话历史的集合,并从中清除每个会话历史的当前条目,但保留历史记录集的当前条目。

            历史记录集的当前条目是指最后一个变为会话历史中的当前条目的条目。

            历史记录集中的条目是按其加入到各自会话历史的时间顺序排列的。(由于这些浏览上下文在概念上共享一个事件循环,它们的会话历史中添加项的顺序始终是明确的)每一项都有一个索引,最早的一项索引为0,后续项的索引为依次递增的整型(1、2、3,等)。

            History接口的Length属性必须返回历史记录集中历史项的数量。

            无法通过脚本访问真正的历史项。

            History接口的State属性必须返回用户代码最后一次为其赋的值。对于一个初始的History接口,其值必须为null。

            当调用go(delat)方法时,如果没有传递参数或者参数值为0,则用户代理必须按调用location.reload()的方式进行。其他情况下,用户代理必须以方法参数指定的值为差值遍历历史。

            当调用back()方法时,用户代理必须以-1为差值遍历历史。

            当调用forward()方法时,用户代理必须以1为差值遍历历史。

            例子:考虑一个游戏,用户可以沿着一条直线导航,这样用户总是在某一坐标上。这样用户就可以将对应于某个特定坐标的页面加入书签,以便以后返回。

            在这样的游戏中实现 x=5 位置的静态页面可能如下所示:

    <!DOCTYPE HTML>
    <!-- this is https://example.com/line?x=5 -->
    <title>Line Game - 5</title>
    <p>You are at coordinate 5 on the line.</p>
    <p>
    <a href="?x=6">Advance to 6</a> or
    <a href="?x=4">retreat to 4</a>?
    </p>

            这样的系统的问题是,用户每次点击,整个页面必须重新加载。下面是使用脚本的另一种方法:

    <!DOCTYPE HTML>
    <!-- this starts off as https://example.com/line?x=5 -->
    <title>Line Game - 5</title>
    <p>You are at coordinate <span id="coord">5</span> on the line.</p>
    <p>
    <a href="?x=6" onclick="go(1); return false;">Advance to 6</a> or
    <a href="?x=4" onclick="go(-1); return false;">retreat to 4</a>?
    </p>
    <script>
    var currentPage = 5;//prefilled by server
    function 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=' + (currentPage + 1);
        document.links[0].textContent = 'Advance to ' + (currentPage + 1);
        document.links[1].href = '?x=' + (currentPage - 1);
        document.links[1].textContent = 'retreat to ' + (currentPage - 1);
    }
    </script>

            在不支持脚本的系统中,它仍然像前面的示例一样工作。但是,支持脚本的用户现在可以更快地进行导航,因为在相同的体验下不需要请求网络。此外,书签和导航的会话历史仍然可用。

            在上面的示例中,pushState () 方法的data参数与将发送到服务器的信息相同,但采用更方便的形式,因此脚本不必在每次用户导航时解析 URL。

            例子:应用程序可能不使用会话历史条目de 标题作为该文档<title>元素的值。例如,这里有一个简单的页面,它显示title元素。显然,当向后导航到以前的状态时,用户不会及时返回,因此将时间放在会话历史标题中是不合适的。

    <!DOCTYPE HTML>
    <TITLE>Line</TITLE>
    <SCRIPT>
    setInterval(function() {
        document.title = 'Line - ' + new Date();
    }, 1000);
    var i = 1;
    function inc() {
        set(i + 1);
        history.pushState(i, 'Line - ' + i);
    }
    function set(newI) {
        i = newI;
        document.forms.F.I.value = newI;
    }
    </SCRIPT>
    <BODY ONPOPSTATE="set(event.state)">
    <FORM NAME=F>
    State: <OUTPUT NAME=I>1</OUTPUT> <INPUT VALUE="Increment" TYPE=BUTTON ONCLICK="inc()">
    </FORM>

            例子:大多数应用程序都希望对其所有历史记录项使用相同的滚动还原模式值。为了实现这一点,他们应该尽快设置 scrollRestoration 属性 (例如,在文档的 head 元素中的第一个脚本元素中),以确保添加到历史会话中的任何条目都获得所需的滚动恢复模式。

    <head>
      <script>
        if ('scrollRestoration' in history)
          history.scrollRestoration = 'manual';
      </script>
    </head>
  • 相关阅读:
    厦门主要IT企业名单(至20071205)
    空,无
    扩展TextBox控件 荣
    我写的C++控件基类 荣
    扩展DataGrid 荣
    对重构的理解 荣
    C#中的委托与事件 荣
    CommunityServer中的代码页面分离 荣
    Oracle创建表空间,导出数据库,导入数据库 荣
    C#中的修饰符 荣
  • 原文地址:https://www.cnblogs.com/SyMind/p/7607998.html
Copyright © 2011-2022 走看看