整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

JavaScript对象

JavaScript对象

avaScript对象分类

  • 内置对象:包括string,number,boolean等
  • BOM: Browser Object Model, 浏览器对象模型, 包括和浏览器相关的内容
  • DOM: Document Object Model, 文档对象模型,包括和页面标签相关的内容

BOM浏览器对象模型

  • window: 此对象里面的属性和方法称为全局的属性和方法,访问时可以省略掉window.
  • window中常见的方法:
  1. alert("xxx")弹出提示框
  2. confirm("xxx") 弹出确认框
  3. prompt("xxx") 弹出文本框
  4. isNaN(x) 判断变量是否是
  5. NaNparseInt()和parseFloat() 把字符串转成整数或小数
  6. console.log() 控制台输出
  7. let timer=setInterval(方法,时间间隔) 开启定时器
  8. clearInterval(timer) 停止定时器
  9. setTimeout(方法,时间间隔) 开启只执行一次的定时器
  • window对象中常见的属性

location位置

  1. location.href 获取和修改浏览器的请求地址
  2. location.reload() 刷新页面

history历史

  1. history.length 获取历史页面数量
  2. history.back() 返回上一页面
  3. history.forward() 前往下一页面
  4. history.go(n) n=1是前往下1页面 n=-1 返回上一页面 n=2 前往下2个页面 n=0代表刷新
<h1>0</h1>
<h2>0</h2>
<script>
    setInterval(f,1000);
    let  i=document.querySelector("h1");
    let count=0;
    function f() {
        count++;
        i.innerText=count;
    }
    let num=0;
    let  j=document.querySelector("h2");
    let  timer=setInterval(function () {
        num++;
        j.innerText=num;
        if(num==50){
            clearInterval(timer)
        }
    },200)
    //只执行一次
    setTimeout(function () {
        alert("时间到")
    },5000)
</script>

DOM文档对象模型

包含和页面元素相关的内容

  • 通过选择器获取页面中的元素对象
  1. let 元素对象=document.querySelector("选择器")
  • 获取和修改元素的文本内容
  1. 元素对象.innerText="xxx"; 修改文本内容
  2. 元素对象.innerText 获取文本内容
  • 获取和修改input控件的值
  1. 控件对象.value="xxx"; 修改
  2. 控件对象.value 获取
  • 创建元素对象
  1. let 元素对象=document.createElement("标签名");
  • 添加元素对象到某个元素里面
  1. document.body.appendChild(元素对象);
  2. 父元素.appendChild(元素对象);
  3. 父元素.append(元素对象,元素对象,元素对象);
<input type="text" id="i1">
<input type="button" value="飞机" onclick="f(1)">
<input type="button" value="炸弹" onclick="f(2)">
<script>
    let num=document.querySelector("#i1");
    function f(x) {
        if(isNaN(num.value)){
            let error=document.createElement("div");
            error.innerText="请输入数字"
            document.body.appendChild(error)
            return;
        }
        let imgNum=x==1?"../airplane.png":"../bom3.png";
        for(i=0;i<num.value;i++){
            let computer=document.createElement("img");
            computer.src=imgNum;
            document.body.append(computer);
        }
    }
</script>
//======--------------=========<input type="text" id="i1" placeholder="姓名">
<input type="text" id="i2" placeholder="工资">
<input type="text" id="i3" placeholder="工作">
<input type="button" value="添加" onclick="f()">
<table border="1">
    <tr>
        <th>姓名</th>
        <th>工资</th>
        <th>工作</th>
    </tr>
</table>
<script>
     //通过标签名获取table
     let table=document.querySelector("table");
     function f() {
        //创建 tr 和td
        let trs=document.createElement("tr")
        let td_name=document.createElement("td")
        let td_salary=document.createElement("td")
        let td_work=document.createElement("td")
        td_name.innerText=i1.value;
        td_salary.innerText=i2.value;
        td_work.innerText=i3.value;
        //td 装入 tr
        trs.append(td_name,td_salary,td_work);
        //tr 装进table
        table.append(trs);
    }
</script>

什么是 JSON?

  • JSON 英文全称 JavaScript Object Notation
  • JSON 是一种轻量级的数据交换格式。
  • JSON是独立的语言 *
  • JSON 易于理解。

【注】JSON 使用 JavaScript 语法,但是 JSON 格式仅仅是一个文本。文本可以被任何编程语言读取及作为数据格式传递。

//json实例
{"sites":[
    {"name":"Runoob", "url":"www.runoob.com"}, 
    {"name":"Google", "url":"www.google.com"},
    {"name":"Taobao", "url":"www.taobao.com"}
]}

JSON 语法规则

  1. 数据为 键/值 对。
  2. 数据由逗号分隔。
  3. 大括号保存对象
  4. 方括号保存数组

JSON 对象

JSON 对象保存在大括号内。

//就像在 JavaScript 中, 对象可以保存多个 键/值 对:
{"name":"Wong", "url":"www.celinf.cn"}

JSON函数

  • JSON.parse() 用于将一个 JSON 字符串转换为 JavaScript 对象。
  • JSON.stringify() 用于将 JavaScript 值转换为 JSON 字符串。
var text='{ "sites" : [' +
    '{ "name":"celinf" , "url":"www.celinf.com" },' +
    '{ "name":"Google" , "url":"www.google.com" },' +
    '{ "name":"Taobao" , "url":"www.taobao.com" } ]}';
obj=JSON.parse(text);
document.getElementById("demo").innerHTML=obj.sites[1].name + " " + obj.sites[1].url;

HTML 事件属性

  • onclick 点击事件:
  • onload 用户进入页面时被触发
  • onunload 用户离开页面时被触发
  • onchange 事件常结合对输入字段的验证来使用。
//使用 onchange 的例子。当用户改变输入字段的内容时,会调用 upperCase() 函数。
<input type="text" id="fname" onchange="upperCase()">
  • onmouseover 鼠标移至 HTML 元素上方触发函数
  • onmouseout 鼠标移出元素时触发函数。

练习Demo

<table border="1">
    <caption>个人信息</caption>
    <tr>
        <td>照片</td>
        <td><img src="head.jpg" width="50px" alt="" id="head_img"></td>
    </tr>
    <tr>
        <td>名字:</td>
        <td id="name_td">XXX</td>
    </tr>
    <tr>
        <td>年龄:</td>
        <td id="age_td">XXX</td>
    </tr>
    <tr>
        <td>好友</td>
        <td>
            <ul id="firend_ul">
            </ul></td>
    </tr>
</table>
<input type="button" value="请求数据" onclick="f()">

<script>
let person={name:"张三",url:"../bee.png",age:20,friend:["李四","王五","赵六"]}
    function f() {
        head_img.src=person.url;
        name_td.innerText=person.name;
        age_td.innerText=person.age;
        for (let p of person.friend) {
            let li=document.createElement("li")
            li.innerText=p;
            firend_ul.append(li)
        }
    }
</script>

学习记录,如有侵权请联系删除

览器对象

一、参考资料

  • 浏览器对象模型
  • 聊聊 H5 的 pushState 与 replaceState
  • 用 Javascript 获取页面元素的位置
  • js 获取操作元素位置

二、认识浏览器运行态下的 js

1.问:是否了解浏览器的执行态(分层设计)?

  • ECMAScript - 基础逻辑、数据处理,js 语法块
  • BOM - 浏览器本身的能力操作
  • Browser Object Model(浏览器对象模型)
  • 浏览器模型提供了独立于内容的、可以与浏览器窗口进行滑动的对象结构,就是浏览器提供的 API
  • DOM - 浏览器文本的操作

2.BOM

1.location

提供当前窗口中的加载的文档有关的信息和一些导航功能。 既是 window 对象属性,也是 document 的对象属性

window.location===document.location; //true

// https://www.zhihu.com/search?type=content&q=123

location.href='https://www.zhihu.com/search?type=content&q=123'.origin=// 完整的url
  'https://www.zhihu.com'.host=// 页面的标准域名
  'www.zhihu.com'.hash=// 服务器名称+端口 例如:‘www.zhihu.com:8080’
  '#hash'.pathname=// url中#号后面的哈希值
  '/search'.search=// url中[/]后面内容
  '?type=content&q=123'.protocol=// url中[?]后面内容
  'https:'.port=// 协议[http:]
    ''; //端口号:[ 80 | 8080 | ... ]

方法:

  1. assign()
  2. 不会打开新窗口,把请求 url 中的资源,加载到当前窗口
  3. 会给浏览器的History中增加一条历史记录
  4. replace(url)
  5. 用 url 中的内容,替换掉当前的 location 资源
  6. 不会在浏览器的History中增加记录,意味着用户不能使用回退按钮
  7. reload()
  8. 重新加载当前 url 的内容
  9. 当 reload(true)时,会强制从服务器获取所有内容
  10. 若没有参数,重新加载时,可能从浏览器缓存加载页面

拓展方向:

  • location 本身 api 操作
  • assign VS replace 的区别
  • 解析 url 中的查询字符串,返回一个对象
  • 思路:
  • 可以通过正则的方式获取,或者通过字符串分割的方式
  • 通过location.search获取查询字符串内容,如果有[?]就截取[?]后面的内容
  • 然后通过[&]进行分割成为['key=val1','key=val2']的形式
  • 通过[=]对数组进行分割,使用decodeURIComponent对 key 和 val 进行解码,存放到对象中
  • 路由相关: 跳转、参数、操作
  • 页面能否返回(history)
  • 页面是否刷新(hash)
  • reload、assign、replace 参数等
  • URI or URL 的区别?
  • URI Uniform Resource Identifier - 统一资源标识符
  • URL Uniform Resource Locator - 统一资源定位符

2.History

history.state.length; // 当前页面的状态 // 返回当前 `会话` 中的 history 个数

方法:

  • pushState(state, title, url)
  • 给当前的 history 中添加一个状态
  • 浏览器地址会改变,但是不会加载页面,本质上页面还是停留在原来的页面
  • replaceState()
  • 与 pushState 方法类似,但是不会添加一个新的 state 到 history 中,而是直接修改当前state

相关联的方法

  • window.onpopstate()
  • 每当处于激活状态的历史记录条目发生变化时,popstate事件就会在对应 window 对象上触发
  • 调用history.pushState() 或者 history.replaceState() 不会触发 popstate 事件。
  • popstate 事件只会在浏览器某些行为下触发
  • 比如点击后退、前进按钮(或者在 JavaScript 中调用 history.back()、history.forward()、history.go()方法)

例子:

window.onpopstate=function (event) {
  alert(
    'location: ' +
      document.location +
      ', state: ' +
      JSON.stringify(event.state),
  );
};
//绑定事件处理函数.
history.pushState({ page: 1 }, 'title 1', '?page=1'); //添加并激活一个历史记录条目 http://example.com/example.html?page=1,条目索引为1
history.pushState({ page: 2 }, 'title 2', '?page=2'); //添加并激活一个历史记录条目 http://example.com/example.html?page=2,条目索引为2
history.replaceState({ page: 3 }, 'title 3', '?page=3'); //修改当前激活的历史记录条目 http://ex..?page=2 变为 http://ex..?page=3,条目索引为3
history.back(); // 弹出 "location: http://example.com/example.html?page=1, state: {"page":1}"
history.back(); // 弹出 "location: http://example.com/example.html, state: null
history.go(2); // 弹出 "location: http://example.com/example.html?page=3, state: {"page":3}

3.navigator

浏览器系统信息大集合

  • clipboard
  • 系统剪切板相关信息
  • userAgent
  • 当前用户的设备信息
  • onLine
  • 返回浏览器的在线状态
  • serial
  • 返回串口对象,Web Serial API 的入口点
  • bluetooth
  • 系统蓝牙相关 …

4.screen

用来表示浏览器窗口外部的显示器的信息等

window.screen.deviceXDPI/deviceYDPI 屏幕实际的水平 DPI、垂直 DPI

三、浏览器事件

浏览器事件模型主要分为三个阶段:

  • 捕获阶段(IE)
  • 事件由最外层元素(window),层层向内传递,直到最具体的元素
  • 目标阶段
  • 冒泡阶段(网景)
  • 事件由最具体的元素(事件的触发者),层层向外传递(传递给父节点),直到 window 对象停止

1.addEventListener 第三个参数

el.addEventListener(event, function, useCapture)
// useCapture默认值false,也就是默认冒泡
// true为捕获阶段

2.阻断事件传播

  • event.stopPropagation()
  • 阻断事件的传播
  • 但是无法阻止默认事件
  • event.stopImmediatePropagation()
  • 如果有多个相同类型的事件监听函数绑定到同一个元素
  • 当该类型的事件触发时,它们会按照被添加的顺序执行
  • 如果其中某个监听函数执行了此方法,则当前元素剩下的监听函数将不会被执行

3.阻止默认行为

  • e.preventDefault()
  • e.preventDefault()可以阻止事件的默认行为发生
  • 默认行为是指:点击 a 标签就转跳到其他页面、拖拽一个图片到浏览器会自动打开、点击表单的提交按钮会提交表单等等,因为有的时候我们并不希望发生这些事情,所以需要阻止默认行为

拓展方向

性能方向

  • 如:事件委托的运用,一个 ul 和多个 li,点击 li 时,改变背景颜色
{
  /* 
<ul class="list">
    <li>1</li>
    <li>2</li>
    <li>3</li>
</ul>  
*/
}
var list=document.querySelector('list');

function onClick(e) {
  var e=e || window.event;
  if (e.target.tagName.toLowerCase()==='li') {
    // 业务逻辑...
    e.target.style.backgroundColor='pink';
  }
}

list.addEventListener('click', onClick, false);

兼容性方向

  • 如:写一个兼容 IE 的事件绑定

先区别 IE 的不同之处

  • 绑定事件的函数和传参不同: 使用 attachEvent绑定,事件名要加on
  • 解绑时使用的函数和参数不同: 使用detachEvent解绑
  • 阻断时的不同: event.cancelBubble=true
  • 阻止默认行为的不同: event.returnValue=false
class BindEvent {
  constructor(el) {
    this.el=el;
  }

  addEventListener(type, handler) {
    if (this.el.addEventListener) {
      this.el.addEventListener(type, handler, false);
    } else if (this.el.attachEvent) {
      this.el.attachEvent('on' + type, handler);
    } else {
      this.el['on' + type]=handler;
    }
  }

  removeEventListener(type, handler) {
    if (this.el.removeEventListener) {
      this.el.removeEventListener(type, handler, false);
    } else if (this.el.detachEvent) {
      this.el.detachEvent('on' + type, handler);
    } else {
      this.el['on' + type]=null;
    }
  }

  static stopPropagation() {
    if (e.stopPropagation) {
      e.stopPropagation();
    } else {
      e.cancelBubble=true;
    }
  }

  static preventDefault() {
    if (e.preventDefault) {
      e.preventDefault();
    } else {
      e.returnValue=false;
    }
  }
}

四、网络请求

1.XMLHttpRequest

  • 属性
  • responseText(服务端响应的文本数据)
  • responseXML(服务点响应的 xml 或者 html 类型数据)
  • status(响应 HTTP 状态)
  • statusText(响应 HTTP 状态描述)
  • readyState(发出请求的状态码)对应onreadystatechange事件0:创建成功,但是没有调用 open 方法1:open 方法被调用2:send 方法被调用3:loading,下载中4:下载操作完成
  • timeout(超时时间,对应超时事件ontimeout,ontimeout 事件被弃用)
  • upload(上传进度)
  • 方法
  • open() 初始化请求(method, url, async),async 表示是否异步操作,默认 true
  • send() 发送请求数据,get 请求时,send 可以不传或者 null
  • abort() 中止已经发出的请求
  • setRequestHeader() 设置请求头信息
  • getRequestHeader() 获取指定响应头信息
  • getAllResponseHeaders() 获取所有响应头信息

封装 XMLHttpRequest 请求

function ajax({ method='get', url='', params=undefined }) {
  return new Promise((resolve, reject)=> {
    let xhr=new XMLHttpRequest();
    if (method.toLowerCase()==='get' && params !==undefined) {
      url=url + '?' + params;
    }
    xhr.open(method, url, true);
    xhr.onreadystatechange=function () {
      if (xhr.readyState===4) {
        if (xhr.status===200) {
          resolve(xhr.responseText);
        } else {
          reject(xhr.status);
        }
      }
    };

    if (method.toLocaleLowerCase()==='get') {
      xhr.send();
    } else {
      xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
      xhr.send(params);
    }

    xhr.onerror=(err)=> reject(err);
    xhr.timeout=()=> reject('timeout');

    // progress事件可以报告长时间运行的文件上传
    xhr.upload.onprogress=(p)=> {
      console.log(Math.round((p.loaded / p.total) * 100) + '%');
    };
  });
}

2.fetch

  • 方法:fetch(url,{}| init 对象 ),返回 Promise 对象,只支持异步
  • 响应通过 response 对象获取:
  • fetch().then((response)=>{}).catch(()=>{})
  • response 对象混入了 body,提供了 5 个方法,将 ReadableStream 转存到缓冲区的内存里,将缓冲区转换为 js 对象,通过 Promise 返回
  • response.text() //转为 text
  • response.json() //转为 json
  • response.formData()
  • response.arrayBuffer()
  • response.blob()
  • 不支持超时设置
  • 但是可以使用promise+setTimeout进行控制
  • 默认不携带cookies,但是可以设置
  • fetch(url, {credentials: 'include'});
  • omit 不发送 cookie
  • same-origin 同源发送 cookie(默认)
  • include 都发送 cookie
  • resolve 若发生在网络通信正常(404,500)也是 resolve
  • .catch()也不会被执行。
  • reject 只发生在网络通信异常
  • 想要精确的判断 fetch 是否成功
  • 需要包含 promise resolved 的情况,此时再判断 response.ok 是不是为 true
  • 需要借用 AbortController 中止 fetch
// resolve若发生在网络通信正常(404,500)也是resolve
fetch('http://domain/service', {
  method: 'GET',
})
  .then((response)=> {
    // 想要精确的判断 fetch是否成功
    // 需要包含 promise resolved 的情况,此时再判断 response.ok是不是为 true
    if (response.ok) {
      return response.json();
    }
    throw new Error('Network response was not ok.');
  })
  .then((json)=> console.log(json))
  // .catch()也不会被执行
  .catch((error)=> console.error('error:', error));

// ************************************
// 不支持直接设置超时, 可以用promise
function fetchTimeout(url, init, timeout=3000) {
  return new Promise((resolve, reject)=> {
    fetch(url, init).then(resolve).catch(reject);
    setTimeout(reject, timeout);
  });
}
// ************************************
// 中止fetch
// signal用于支持AbortController中断请求
const controller=new AbortController();
// AbortController接口表示一个控制器对象
// 允许你根据需要中止一个或多个 Web请求
fetch('http://domain/service', {
  method: 'GET',
  signal: controller.signal,
})
  .then((response)=> response.json())
  .then((json)=> console.log(json))
  .catch((error)=> console.error('Error:', error));
controller.abort();

3.Http 状态码和 Header

1.状态码

100 信息性|200 成功|300 重定向|400 客户端错误|500 服务器错误

[1|2|3]xx

  • 101 切换协议
  • 200 Ok
  • 301 永久重定向(设备会缓存)
  • 302 临时重定向(以前是临时转移,已经不推荐使用了,建议使用 307)
  • 307 临时重定向
  • 如果是 POST/DELETE 过来的会继续使用
  • 302 只会使用 get
  • 304 (Not Modified)服务器文件未修改,协商缓存
  • 308 永久重定向

4xx

  • 400 客户端请求有语法错误,不能被服务器识别
  • 403 服务器受到请求,但是拒绝提供服务,可能是跨域也可是权限不够
  • 404 请求的资源不存在
  • 405 请求的 method 不允许

5xx

  • 500 服务器发生不可预期的错误

2.字段

  • Content-Length:? 发送给接收者给 Body 内容长度(字节)
  • ? 一个 Byte 是 8bit
  • utf-8 编码的字符是 1-4 个字节
  • ?User-Agent?:客户端特性的字符串
  • ?Content-Type:? 媒体类型
  • ?Origin?:描述请求来源地址
  • ?Accept
  • 建议服务端返回何种媒体类型?/表示所有类型(默认)?text/html,application/json?
  • Accept-Encoding
  • ? 建议服务端发送什么编码(压缩算法)
  • ?deflate,gzip;q=1.0,*;q=0.5
  • ?Accept-Language:? 建议服务端传递那种语言
  • ?Referer
  • 告诉服务端打开当前页面的上一张页面的 URL;
  • 如果是 ajax 请求那么就告诉服务端发送请求的 URL 的什么 ?
  • 非浏览器环境有时候不发生 Referer(或者虚拟 Referer,通常是爬虫)
  • 常用来做用户行为分析
  • ?Connection?
  • 决定链接是否在当前事务完成后关闭
  • ?http1.0 默认是 close
  • ?http1.1 默认是 keep-alive

4.拓展方向

如何应对网络不稳定(波动)的情况?

  • 失败了重发,指数补偿
const request=(url)=> {
  let resolved=false;
  let t=1;
  return new Promise((resolve, reject)=> {
    // Promise.race([
    //     fetch(url),
    //     wait(100, ()=> fetch(url)),
    //     wait(200, ()=> fetch(url)),
    //     wait(400, ()=> fetch(url)),
    //     wait(800, ()=> fetch(url)),
    //     wait(1600, ()=> fetch(url)),
    // ])
    function doFetch() {
      if (resolved || t > 16) return;
      fetch(url)
        .then((resp)=> resp.text())
        .then((data)=> {
          if (!resolved) {
            resolved=true;
            resolve(data);
          }
        });

      setTimeout(()=> {
        doFetch();
        t *=2;
      }, t * 100);
    }
    doFetch();
  });
};

如何处理并发请求?

  • 相同的请求,多次发送,会照成带宽的浪费
  • 处理思路:做缓存
  • 因为请求具有时效性,所以不能做永久缓存
  • 相同的请求在一定的时间内只发生一次
  • 使用w保存请求信息,若同一时间发送多次相同对请求
  • 使用w[hash].resolves保存 resolve 函数当请求函数w[hash].func发送成功,执行 resolves 中的函数,保证每次请求都有响应信息

端浏览器对象模型BOM常用对象介绍,BOM即Broswer Object Model 浏览器对象模型,在JavaScript中可以理解为window对象,用来进行与浏览器相关的一些操作,学习BOM就是学习 JavaScript中的window对象。


一、window对象

BOM的核心对象是 window,它代表浏览器的一个实例。在浏览器中,window有着双重的角色:JavaScript访问浏览器的接口对象,ES中的Global对象意味着网页中的任何一个对象,变量,函数都是以window作为其Global对象。

1、全局作用域,在ECMAScript中,window对象扮演着Global对象的角色,也就是说,所有在全局作用域声明的变量,函数都会变成window的属性和方法,都可以通过 window.属性名(或方法名) 直接调。

2、导航和打开窗口,通过 window.open() 既可以导航到一个特定的URL,也可以打开一个新的浏览器窗口

二、location对象

[^location 是最有用的BOM对象之一,它提供了与当前窗口中加载的文档有关的信息]: JavaScript高级程序设计。

注: window.location 和 document.location?引用的是同一个对象。location 既是 window 对象的属性,也是 document?对象的属性。

三、 navigator对象

navigator 对象主要用来获取浏览器的属性,区分浏览器类型;

navigator 对象属性较多,且兼容性比较复杂。

四、history对象

history 对象保存着用户上网的历史记录,从窗口被打开的那一刻算起,因为 history 是 window 对象的属性,因此每个浏览器窗口,每个标签乃至每个框架,都有自己的 history对象与特定的 window 对象关联。

总结浏览器对象模型BOM中常用的对象有navigator,window, location, history

window既是 JavaScript 的全局对象,也是BOM的一个实例,所有的全局方法,属性,BOM中的属性,都可以通过 window. 来调用;

window作为BOM的实例,最常用的几个方法分别是:window.open(),window.close(),,分别用来打开和关闭浏览器窗口页面,这里需要注意的是,通过 open 方法打开的页面,才能通过close 方法关闭;

location对象也是用的比较多的一个BOM对象,主要用来操作URL相关的一些信息,除了修改 Hash 之外的任何属性,页面都会重新加载,历史记录会多加一条历史记录;

location对象还有一个 reload() 方法用于手动重新加载页面,该方法接收一个可选参数,为 true 的时候表示从服务器重新加载,否则可能从浏览器缓存中重新加载页面;

location对象 还有一个比较特殊的方法,location.replace(),该方法可以覆盖当前页面并重新加载,同时不会在 history 中生成历史记录;

navigator对象主要用来获取浏览器相关的一些信息,使用的时候需要注意兼容性。可以用来获取浏览器类(Chrome,safrai,FireFox,Edge,IE)等;

history对象主要用来操作浏览器URL的历史记录,可以通过参数向前,向后,或者向指定URL跳转。可以通过 length 属性获取记录数,判断当前页面是否是打开的首个页面;