跳转至

简介

请点击这里,边看视频,边学习教程

Web API

前面我们学习的主要是 js 语言本身的特性,和浏览器没有关系

那么我们怎么用 js 语言实现 浏览器相关 的 操作呢?

比如,打开新的页面、网页内容的获取和改变、和网站服务端通信 ?


浏览器运行环境 提供了 丰富了 js语言编程接口 , 称之为 Web API 接口。

通过它,我们的js代码就可以 操控浏览器(网址跳转、改变窗口大小等)、操控网页的内容和行为

浏览器内置window对象

浏览器里面的js引擎内置了js 变量 window

这个window 变量 对应的是一个 Window 类型的对象,它代表了 js 运行的这个浏览器窗口环境。


由于它代表的就是整个浏览器js运行环境,所以这个对象的属性方法可以直接在js代码中使用,不需要加上 window. 作为前缀

比如,我们前面学过的 prompt、alert、confirm 其实就是 window的方法

window.alert(
  `相等吗? 
  ${window.prompt === prompt}
  ${window.alert === alert}
  ${window.confirm === confirm} `)


window对象的属性,也就是浏览器内置对象和函数有很多,我们先了解一些常用的

history、location

history 对应 就是 当前浏览器的 浏览历史对象

可以通过该对象的属性和方法进行一些操作,

比如

// 返回上次浏览地址,等于点击浏览器的返回按钮
history.back();

// 也是 返回上次浏览地址
history.go(-1);

// 前进到返回前面的地址,等于点击浏览器的前进按钮
history.forward();     



location 对应 就是 当前浏览器的 地址对象

可以通过该对象的属性和方法进行一些操作,如下

// 设置当前浏览地址
location.href = '/main.html'


// 重新加载网页,等于刷新网页
location.reload()

localStorage、sessionStorage

localStorage 可以看作一个 本地键值对数据库,

它是当前网站的 前端存储,关闭浏览器窗口后也不会丢失数据

比如

// 存入/修改 数据
localStorage.setItem('myCat', 'Tom');

// 获取数据
const cat = localStorage.getItem('myCat');

// 清除localStorage 数据
localStorage.clear();



sessionStorage 也是一个 本地键值对数据库,

它也是当前网站的 前端存储

localStorage 的差别是, 它的数据是和session相关的。

关闭浏览器窗口后,数据就会丢掉。

比如

// 清除 sessionStorage 数据
sessionStorage.clear();

// 存入/修改 数据
sessionStorage.setItem('myCat', 'Tom');

// 获取数据
const cat = sessionStorage.getItem('myCat');

prompt、alert、confirm

前面讲过,不再赘述

close、open

close() 方法可以 关闭当前窗口,比如

close()



open() 方法可以 打开一个新的窗口,比如

// 打开新空窗口
open()

// 打开新窗口,访问指定url
open('https://www.byhy.net')

// 直接本窗口打开访问指定url
open('https://www.byhy.net', '_self')

DOM 文档对象模型

浏览器加载网页(根据html文档和一些代码) 后, 会在浏览器内部(内存中)创建一个文档对象模型 (document object model) 简称 DOM 对象 , 对应 树状的 文档结构。

比如像下面这样的一个html网页

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Simple DOM example</title>
  </head>
  <body>
      <section>
        <img src="dinosaur.png" alt="A red Tyrannosaurus Rex: A two legged dinosaur standing upright like a human, with small arms, and a large head with lots of sharp teeth.">
        <p>Here we will add a link to the <a href="https://www.mozilla.org/">Mozilla homepage</a></p>
      </section>
  </body>
</html>

浏览器加载后,内部形成如下这样的 树状数据结构 DOM 对象

image


可以发现,每个html元素以及每段字符串,都会对应DOM对象的一个 节点(node) ,它们的上下层关系和html文档对应。

有如下一些DOM 相关的术语:

这个树状文档的 根节点(root node) 是 HTML节点

每个html元素 都对应一个 元素节点(Element node)

有的元素节点,有其 子节点(Child node) ,相对而言,它就是其子节点的 父节点(Parent node)

某个元素节点 分支下面所有的子节点、子节点的子节点,等等, 都是它的 后代节点(Descendant node)

相同父节点的节点 之间是 兄弟节点(Sibling nodes) 的关系

只包含一段文本字符串的节点是 文本节点(Text node)


特别要注意的是名词 元素(Element)节点(Node) 的区别

任何 DOM对象都是一个 节点 , 包括 元素节点、 注释节点、 文本节点、属性节点

具体说有下面这些节点类型

节点类型 节点值
ELEMENT_NODE 1
ATTRIBUTE_NODE 2
TEXT_NODE 3
CDATA_SECTION_NODE 4
PROCESSING_INSTRUCTION_NODE 7
COMMENT_NODE 8
DOCUMENT_NODE 9
DOCUMENT_TYPE_NODE 10
DOCUMENT_FRAGMENT_NODE 11


元素(也叫元素节点) 只是其中一种 节点,它们是对应一个html元素的, 比如 body、p、span、div 这些节点。

其它的,比如注释节点、文本节点 就不是 元素节点


浏览器 是根据 DOM对象 展示可见内容在界面上的。

其中整个DOM对象, 可以通过 js引擎内置对象 window.document 或者直接 document 访问到。

DOM对象中每个节点对象 都是可以通过 document对象 的一些内置方法获取到。

比如,F12打开 DevTools Console,执行

var link = document.querySelector('a')

就可以通过一个css选择表达式 获取到 标签名为 a 的第一个 的DOM元素对象。

然后,就可以通过该对象的属性,来改变对象的内部内容。

link.textContent = '白月黑羽'
link.href = 'https://www.byhy.net'


我们写的js代码 通过 操作这个 DOM 对象,从而动态 获取浏览器界面的信息,改变浏览器的界面展示。

后面的教程会有这些方面的详细讲解和示例。


// 根据id属性获取元素对象
document.getElementById('password')

// 返回 body元素对象
document.body

// 返回 head元素对象
document.head

// 返回 当前窗口的标题
document.title

// 返回 当前窗口的url地址
document.URL

网页程序示例

现代的网站不仅仅只是富文本信息的呈现,可以 网页聊天、邮件交互、甚至可以在网页上打游戏

所以现在很多网页,其实 就是一个真正的 应用程序 ,而不是传统意义上的 网页 了。


网页成为应用程序 的关键 就是 js 语言对网页内容的操作能力,

主要就是: 得知网页事件、获取网页内容,改变网页内容


看一个例子:

现在我们要开发一个网页程序,让用户输入一段文本包含:员工姓名、薪资、年龄。

格式如下:

薛蟠     4560 25
薛蝌     4460 25
薛宝钗   35776 23
薛宝琴   14346 18
王夫人   43360 45
王熙凤   24460 25
王子腾   55660 45
王仁     15034 65
尤二姐   5324 24
贾芹     5663 25
贾兰     13443 35
贾芸     4522 25
尤三姐   5905 22
贾珍     54603 35

该程序可以把薪资在 2万 以上、以下的人员名单分别打印出来。


我们可先写好对应的html界面,如下

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>白月黑羽web教学:薪资统计</title>  
</head>

<body style="display: flex; 
  flex-direction: column; 
  align-items: center;
  gap:1rem">

  <p>请输入员工薪资记录</p> 

  <textarea id="salary" rows="12" cols="60"></textarea>

  <button id='go'>统计</button>

  <p style='color:blue'>统计结果</p> 

  <div>
    <pre id="result"></pre>
  </div>

</body>
</html>

获取元素对象

网页应用程序,要管理界面,其实就是管理界面的一个个元素对应 的 DOM 对象。

而要控制这些对象(获取信息、修改信息), 首先得能在代码中 获取这些DOM对象 ,然后才能调用它们的方法对其进行控制。


选择对象,最灵活的方法就是使用 querySelectorquerySelectorAll 方法,

参数是 CSS 选择表达式

比如,要选择 分类结果 的 span 这个元素,可以有好几种写法

Console 中运行如下代码

//  tag名选择
document.querySelector('textarea')

//  id选择
document.querySelector('#result')
// 还可以 使用 getElementById
document.getElementById('result')


//  范围选择
document.querySelector('div pre')

css 选择器,前面有专门讲解,这里就不赘述了。


querySelector 方法,返回的是HTML中第一个符合 选择表达式的 元素。

如果要选择所有符合 选择表达式的元素, 可以使用 querySelectorAll 方法

该方法返回的是一个类似数组的对象里面存放了所有符合条件的 DOM 对象

// 返回数组
document.querySelectorAll('p')

// 数组里面的第2个元素
document.querySelectorAll('p')[1]

// 遍历
ps = document.querySelectorAll('p')
for (let p of ps) { 
  console.log(p) 
}

事件和处理

什么时候网页 应该 执行我们写的代码?

通常是某个事件发生的时候,比如用户输入数据后,按回车、 点击某个按钮、鼠标移动到某个元素上、等等。

比如上面的 薪资分类程序, 我们要能够在用户完成输入薪资表后,点击统计按钮,调用我们的代码来处理。


那么怎么告知浏览器,当某个事件发生,回调我们的代码呢?

使用 DOM 对象的 addEventListener 方法。

比如:文本输入框中,键盘按键 Ctrl + 回车

执行 salaryStats 函数

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>白月黑羽web教学:薪资统计</title>  
</head>

<body style="display: flex; 
  flex-direction: column; 
  align-items: center;
  gap:1rem">

  <p>请输入员工薪资记录</p> 

  <textarea id="salary" rows="12" cols="60"></textarea>

  <button id='go'>统计</button>

  <p style='color:blue'>统计结果</p> 

  <div>
    <pre id="result"></pre>
  </div>

  <script>    
  function salaryStats(event){
    alert('执行salaryStats') 
  }

  // 注册事件回调函数
  document.querySelector('#go').addEventListener("click", salaryStats );
  </script>
</body>
</html>


其中 注册事件回调函数的代码 ,在 id 为 go 的元素上,使用 addEventListener 方法,注册了点击的事件, 当这种事件发生的时候,就回调执行函数 salaryStats 来处理这个事件。

salaryStats定义的时候,知道,浏览器回调自己的时候,会传入一个 MouseEvent(鼠标事件)类型的对象。


事件类型 除了鼠标事件外,还有 键盘事件,滚轮事件、拖拽事件、剪贴板事件 等等。

后续章节有详细的讲解

获取网页内容

继续上面的案例,我们已经能够获取到DOM 对象了

那么我们的代码怎么获取DOM 对象对应的信息呢?

主要就是要通过DOM 对象的 属性

不同类型的html元素,对应的DOM 对象的类型是不同的

a 对应的DOM对象类型是 HTMLAnchorElement

p 对应的DOM对象类型是 HTMLParagraphElement

textarea 对应的DOM对象类型是 HTMLTextAreaElement

button 对应的DOM对象类型是 HTMLButtonElement

等等

完整的对应关系可以点击这里查看


比如,本例中,是要从 textarea 元素中获取文本框里面的内容。

这时,应该使用这个DOM对象的属性获取。

HTMLTextAreaElement的属性表,可以查看这个文档

通过这个文档得知,textarea文本框里面的内容 对应的是属性 value ,如下所示

document.querySelector('#salary').value

改变网页内容

和获取网页内容一样,要改变网页内容,首先要获取 对应的 DOM对象

然后通过对象的属性方法,改变其内容

通常有如下几类

添加元素

我们可以给某个节点添加新节点,比如

document.querySelector('div')
  .insertAdjacentHTML("beforeend", "<p id='test1'>薪资20K以上的有:xxx、yyy</p>")

insertAdjacentHTML 方法就是在DOM 对象的某个位置插入新的html节点。

第2个参数 就是要插入的节点对应的HTML 内容

第1个参数 指定插入节点的位置,这里 beforeend 就是 指 插入节点作为 当前节点的 最后一个子节点

删除元素

要删除元素,可以 先获取该元素,然后调用remove方法

比如

document.getElementById("test1").remove()


还可以这样删除

document.getElementById("myDiv").outerHTML="";

支持这种方式的浏览器更广泛,包括IE

改变元素内容和属性

改变元素内容和属性 , 同样也是通过DOM对象的方法

比如,

// 设置 id 为 salary的textarea 里面的内容 
document.querySelector('#salary').value = `
薛蟠     4560 25
薛蝌     4460 25
`

document.querySelector('#salary').value = ''

// 改变 id为result元素的内部文本
document.querySelector('#result').innerText = '薪资20K以上的有:xxx、yyy'

// 改变id为result元素的文本颜色为红色
document.querySelector('#result').style.color = 'red'

// 改变button按钮文本
let addOneBtn = document.querySelector('button')
addOneBtn.innerText = addOneBtn.innerText === '隐藏' ? '添加' : '隐藏';


那么到底一个元素对应的DOM对象有哪些属性方法呢?

还是要看DOM对象的 类型

不同类型的HTML元素对应的 HTMLElement 对象不同, 属性也会有差异,具体看下一章的讲解


至此,统计薪资的代码就可以写出来了

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>白月黑羽web教学:薪资统计</title>  
</head>

<body style="display: flex; 
  flex-direction: column; 
  align-items: center;
  gap:1rem">

  <p>请输入员工薪资记录</p> 

  <textarea id="salary" rows="12" cols="60"></textarea>

  <button id='go'>统计</button>

  <p style='color:blue'>统计结果</p> 

  <div>
    <pre id="result"></pre>
  </div>

  <script>    
  function salaryStats(event){
    let info = document.querySelector('#salary').value

    // 薪资20000 以上 和 以下 的人员名单
    let salary_above_20k = []
    let salary_below_20k = []
    for (let line of info.split('\n')){
      if (!line.trim())
          continue
      let parts = line.split(' ')
      let newparts = []
      for (let one of parts) 
        if (one) newparts.push(one)

      let [name,salary,age] = newparts
      if (parseInt(salary) >= 20000)
          salary_above_20k.push(name)
      else
          salary_below_20k.push(name)
    }

    document.querySelector('pre').innerText  = 
    `
    薪资20000 以上的有:
    ${salary_above_20k.join(' ')}

    薪资20000 以下的有:
    ${salary_below_20k.join(' ')}
    `
  }

  // 注册事件回调函数
  document.querySelector('#go').addEventListener("click", salaryStats );
  </script>
</body>
</html>

控制元素是否显示

控制元素是否显示,可以根据元素的CSS样式里面的 display 属性 ,

display 的值为 none ,元素不显示

比如

let pnEle = document.querySelector('.paginator')
if(pd.pagecount === 0){
  pnEle.style.display = 'none'
  return
}

其它能力

浏览器 Web API编程接口还提供了其它能力,比如:

  • 和服务器通信能力

包括HTTP/WebSocket等

  • 浏览器端存储能力

包括Local Storage, Session Storage, Cookie, IndexedDB等等

  • 本地文件访问能力

  • 定位能力

等等

完整的编程接口,点击参考这里

这些js编程接口的API 提供了底层能力,我们运用好它们,就可以开发各种功能的网页应用程序