web api概述
标准库:ECMAScript中的对象和函数
Web Api:浏览器宿主环境中的对象和函数
- 知识繁杂
- 成体系的知识
- 程序思维:知识+程序思维 = 应用
- 兼容性:了解,不记忆
Web Api:
- BOM:Browser Object Model,浏览器对象模型
- DOM:Document Object Model,文档对象模型
BOM:控制浏览器本身 DOM:控制HTML文档
ES 由 ECMAScript 规定的 WebApi 由 W3C(万维网联盟) 制定
关于DOM
- DOM 0
- DOM 1
- DOM 2
- DOM 3
- DOM 4 2015年
DOM是什么
DOM的核心理念,是将一个HTML或XML文档,用对象模型表示,每个对象称之为dom对象
dom对象又称之为节点Node
节点的类型:
- DocumentType,文档类型节点
- Document,文档节点,表示整个文档
- Comment,注释节点
- Element,元素节点
- Text,文本节点
- Attribute,属性节点
- DocumentFragment,文档片段节点
dom树:文档中不同的节点形成的树形结构。
下面是文档和对应的dom树。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>标题</title>
</head>
<body>
<!-- 注释 -->
<p>lorem</p>
</body>
</html>
获取dom节点
获取dom对象
全局对象 window 中有属性document,代表的是整个文档节点
旧的获取元素节点的方式
dom 0
- document.body:获取body元素节点
- document.head:获取head元素节点
- document.links:获取页面上所有的超链接元素节点,类数组
- document.anchors:获取页面上所有的锚链接(具有name属性)元素节点
- document.forms:获取页面中所有的form元素节点
新的获取元素节点的方式
通过方法获取
- document.getElementById:通过id获取对应id的元素
- document.getElementsByTagName: 通过元素名称获取元素
- document.getElementsByClassName:通过元素的类样式获取元素,IE9以下无效
- document.getElementsByName:通过元素的name属性值获取元素
- document.querySelector:通过CSS选择器(以字符串的形式传入选择器)获取元素,得到匹配的第一个,IE8以下无效.注意这里,除了可以使用document调用querySelector,还可以使用某个元素querySelector,这代表的是从他的后代元素里面用选择器去选中某个元素。
element = baseElement.querySelector(selectors);
// 从divCenter选择data-myplugin-id 属性 = cancle的元素
btnCancel = divCenter.querySelector("[data-myplugin-id=cancel]")
- document.querySelectorAll:通过CSS选择器(以字符串的形式传入选择器)获取元素,得到所有匹配的结果,IE8以下无效
- document.documentElement: 获取根元素
细节:
- 在所有的得到类数组的方法中,除了querySelectorAll,其他的方法都是实时更新的。
- getElementById 得到元素执行效率最高。
- 书写了id的元素,会自动成为window对象的属性。它是一个实时的单对象。事实上的标准。不推荐使用。
<input type="text" id="txt1">
txt1.oninput = txt2.oninput = function(e) {
if (!this.value.trim()) {
console.log("请输入内容");
return;
}
console.log(this.value, e.bubbles);
}
其实就是说,如果你声明了一个id的元素,他会成为window的一个单对象,可以在一些特别小的系统里面使用txt1去获取dom元素。在一些大的系统里面使用已经不合适,他会因为挂在window里面导致一系列的问题,尽量不要去用。
- getElementsByTagName、getElementsByClassName、querySelector、querySelectorAll,可以作为其他元素节点对象的方法使用
- 最常用的是getElementById,querySelector,querySelectorAll的这个三个,getElementsByTagName偶尔会用一下。
根据节点关系获取节点
- parentNode:获取父节点(元素、文档)
- previousSibling:获取上一个兄弟节点
- nextSibling:获取下一个兄弟节点
- childNodes:获取所有的子节点
- firstChild:获取第一个子节点,是他的孩子节点,它本身的属性节点不是。
- lastChild:获取最后一个子节点
- attributes: 获取某个元素的属性节点
节点的API用的少是因为对于HTML来说,节点有可能是空白文本等这些,当我们发布代码的时候使用压缩工具,压缩一下代码,代码的执行可能就出问题了
特别需要注意的一个元素节点也属于节点,只是节点的一种情况而已,所以上面的节点的所有方法,元素节点都可以使用 打印节点对象,就是将节点对象里面的内容完全输出,比方说div,他就会将div 标签里面的内容输出
获取元素节点
- parentElement:获取父元素
- previousElementSibling:获取上一个兄弟元素
- nextElementSibling:获取下一个兄弟元素
- children:获取子元素,特别注意这个名字,没有带Element,也是获取的是子元素。
- firstElementChild:获取第一个子元素
- lastElementChild:获取最后一个子元素
获取节点和获取元素的API,大部分只是多了一个Element而已,特别需要注意的是children 这个情况,是获取子元素。
获取节点信息
- nodeName:获取节点名称
- nodeValue:获取节点的值
- nodeType:节点类型,是一个数字
这里重点记录下nodeName,nodeValue,nodeType这三个值。
每个节点都有一个 nodeType 属性,用于表明节点的类型,节点类型由 Node 类型中定义12个常量表示:

nodeName 属性 要了解节点的具体信息,可以使用 nodeName 和 nodeValue 这两个属性。这两个属性的值完全取决于节点的类型。
一般来说: 元素节点的 nodeName 是标签名称(大写)
属性节点的 nodeName 是属性名称
文本节点的 nodeName 永远是 #text
文档节点的 nodeName 永远是 #document
nodeValue 属性
- 对于文本节点,
nodeValue属性包含文本。 - 对于属性节点,
nodeValue属性包含属性值。 - 文档节点和元素节点,
nodeValue属性的值始终为null。
dom元素操作
初识元素事件
元素事件:某个元素发生一件事(被点击 click)
事件处理程序:是一个函数,发生了一件事,应该做什么事情
注册事件:将事件处理程序与某个事件关联
this关键字在事件处理程序中指代当前发生的事件元素
有点像iOS里面的按钮的点击事件就把按钮传过来的思路是一样的。
获取和设置元素属性
- 通用方式:getAttribute、setAttribute 正常的属性不建议使用上面的,有很多问题,自定义属性可以用。
可识别属性
正常的HTML属性
- dom对象.属性名:推荐
细节:
- 正常的属性即使没有赋值,也有默认值
<input type="text">
var input = document.querySelector("input[type=text]");
console.log(input.value);
此时input 的value没有赋值,获取的也是默认空的字符串。
- 布尔属性在dom对象中,得到的是boolean
<input type="checkbox" checked="checked">
上面的checked是bool属性,获取的是bool值,如果写checked="checked",那么得到的就是true,否则是false。
- 某些表单元素可以获取到某些不存在的属性
<select class="ssss">
<option value="chengdu">成都</option>
<option value="beijing">北京</option>
<option value="haerbin">哈尔滨</option>
</select>
由于select 默认情况是没有value这个属性,但是dom操作的时候提供了select这个属性。
<textarea>
啊手动阀手动阀三发射发生
</textarea>
类似上面的情况这里textarea也可以获取value的值
4.select元素的一些操作
<select name="" id="sel">
<option value="1">Lorem.</option>
<option value="2">Porro?</option>
<option value="3">A?</option>
<option value="4">Ad.</option>
<option value="5">Voluptates?</option>
<option value="6">Blanditiis!</option>
<option value="7">Dicta.</option>
<option value="8">Illum!</option>
<option value="9">Sint.</option>
<option value="10">Sunt.</option>
</select>
- 想要获取选中option的value值可以直接使用select的value属性获取即可。
- 想要获取option里面的文本,可以通过option子元素,去匹配他的value值和option的值是否一致也是可以的,还可以通过option的selected属性为true来判断。还可以通过select的selectedIndex来获取选中的序列。
- 另外sel还有一个options属性和sel.children获取到的一样。
- 书写了id的元素,会自动成为window对象的属性。它是一个实时的单对象,因此这里可以sel就是select对象了。
sel.onchange = function() {
Array.from(sel.children).forEach(function(item){
console.log(item.selected,item.innerText);
});
console.log(sel.value, sel.options[sel.selectedIndex].innerHTML);
}
5. 某些属性与标识符冲突,此时,需要更换属性名
for
<input id="cbgender" type="checkbox" checked="checked"> <label for="cbgender">男</label>
class
<select class="ssss">
<option value="chengdu">成都</option>
<option value="beijing">北京</option>
<option value="haerbin">哈尔滨</option>
</select>
自定义属性
HTML5 建议自定义属性使用data-作为前缀
如果遵从HTML5 自定义属性规范,可以使用dom对象.dataset.属性名控制属性
删除自定义属性
- removeAttribute("属性名");
- delete dom.dataset.属性名
自定义属性的读取和设置 getAttribute、setAttribute 这个通用方式去设置和获取。
当然也可以使用上面的dom对象.dataset.属性名控制属性
获取和设置元素内容
- innerHTML:获取和设置元素的内部HTML文本(HTML文本就是说内部的元素)
- innerText:获取和设置元素内部的纯文本,仅得到元素内部显示出来的文本(如果内部有子元素,这个属性不包括),隐藏的这个方法获取不到。
- textContent:获取和设置元素内部的纯文本,textContent得到的是内部源代码中的文本
元素结构重构
- 父元素.appendChild(元素):在某个元素末尾加入一个子元素
- 父元素.insertBefore(待插入的元素, 哪个元素之前)
- 父元素.replaceChild(替换的元素, 被替换的元素)
细节:
更改元素结构效率较低,尽量少用。 如果要循环添加元素,可以使用代码片段来解决,可以解决频繁改变元素结构引起的效率问题。
<script>
var ul = document.getElementById("ul1");
var frag = document.createDocumentFragment();
for (var i = 1; i <= 100; i++) {
var li = document.createElement("li");
li.innerText = "选项" + i;
frag.appendChild(li);
}
ul.appendChild(frag);
</script>
创建和删除元素
创建元素
-
document.createElement("元素名"):创建一个元素对象
-
document.createTextNode("文本")
-
document.createDocumentFragment(): 创建文档片段
var ul = document.getElementById("ul1");
var frag = document.createDocumentFragment();
for (var i = 1; i <= 100; i++) {
var li = document.createElement("li");
li.innerText = "选项" + i;
frag.appendChild(li);
}
ul.appendChild(frag);
- dom对象.cloneNode(是否深度克隆):复制一个新的dom对象并返回
- 什么算深度克隆呢?这里clone必然会产生了一个新的dom对象,并且里面包含了dom对象的自带的一些属性,但是被clone对象里面的子对象还有自己又写的属性,都不会clone。深度克隆就会将里面的也clone了。
实时集合
何为实时集合,实时集合就是说方法调了一次获取以后,比方说这个childNodes来说,我们一个变量引用着这个集合,而操作后系统内部又把这个集合进行了增加或者删除,最后我们这个变量实际是指向的这个集合,再去读的时候自然是变化的。 而非实时集合,说明的得到结果是克隆了一个新的组合出来,增加和删除只是修改了原来的组合,这个变量指向的组合和原来的不是同一个对象,自然非实时的。要么就是对节点的操作后并没有去操作数组,再去获取一下,才操作这个数组,也有这个可能。
在所有的得到类数组的方法中,除了querySelectorAll,其他的方法都是实时更新的 重点记忆的就是querySelectorAll获取不是实时更新的,其余的都是实时更新的。
childNodes也是实时集合,
删除元素
- removeChild:父元素调用,传入子元素
- remove:把自己删除
dom元素样式
控制dom元素的类样式
- className: 获取或设置元素的类名
- classList: dom4的新属性,是一个用于控制元素类名的对象
- add:用于添加一个类名
- remove:用于移除一个类名
- contains:用于判断一个类名是否存在
- toggle:用于添加/移除一个类名
获取样式
CSS的短横线命名,需要转换为小驼峰命名
- dom.style:得到行内样式对象
- window.getComputedStyle(dom元素):得到某个元素最终计算的样式
- 可以有第二个参数,用于得到某个元素的某个伪元素样式
设置样式
dom.style.样式名 = 值
设置的是行内样式。 上面获取样式的时候有一个计算样式,而这里设置样式只能设置行内样式。计算样式是最后计算的结果,自然无法设置。像外部样式是没办法设置的。而上面的值基本都是字符串。 如果本身是数字的,使用字符串不会出现问题。 详细可以看下面的解释。