文档对象模型(Document Object Model,简称 DOM),是 W3C 组织推荐的处理可扩展标记语言的标准编程接口。
它是一种与平台和语言无关的应用程序接口(API),它可以动态地访问程序和脚本,更新其内容、结构和 www 文档的风格(目前,HTML 和 XML 文档是通过说明部分定义的)。文档可以进一步被处理,处理的结果可以加入到当前的页面。
DOM 是一 种基于树的 API 文档,它要求在处理过程中整个文档都表示在存储器中。
总结:W3C 已经定义了一系列的DOM接口,通过这些DOM接口可以改变网页的内容、结构、样式。
DOM 又称为文档树模型
(1)文档:一个网页可以称为文档,DOM中使用 document 表示
(2)节点:网页中的所有内容都是节点 (标签、属性、文本、注释等),DOM中用 node 表示
(3)元素:网页中的标签,DOM中使用 element 表示
(4)属性:标签的属性
注:DOM 把文档、节点、元素都看作是对象
(1)获取元素
(2)对元素进行操作(设置其属性或调用其方法)
(3)动态创建元素
(4)事件(什么时机做相应的操作)
获取页面元素
我们想要操作页面上的某部分(显示/隐藏,动画),需要先获取到该部分对应的元素,才进行后续操作。
(1)方法:调用 document 对象的 getElementById 方法。
(2)参数:字符串类型的 id 的属性值。
(3)返回值:对应 id 名的元素对象。
(4)注意1:由于 id 名具有唯一性,部分浏览器支持直接使用 id 名访问元素,但不是标准方式, 不推荐使用。
(5)注意2:代码执行顺序,如果 js 在 html 结构之前,会导致结构未加载,不能获取对应id的元素
text
text1
text2
(1)方法:调用 document 对象的 getElementsByTagName 方法。(普通元素对象也可调用获取内部的元素)
(2)参数:字符串类型的标签名。
(3)返回值:同名的元素对象组成的集合(以伪数组的形式存储)。
(4)注意1:操作数据时需要按照操作数组的方法进行。
(5)注意2:getElementsByTagName 方法内部获取的元素是动态增加的
text1
text2
text3
text4
text5
(1)获取的元素对象内部,本身也可以调用根据标签获取元素方法,例如 div 元素对象也可以调用 getElementsByTagName 方法。
(2)目的:缩小选择元素的范围,类似 css 中的后代选择器
(3)父元素必须是单个对象(必须指明是哪一个元素对象),获取时不包括父元素自己。
text1
text2
(1)方法:调用 document 对象的 getElementsByName 方法。
(2)参数:字符串类型的 name 属性值。
(3)返回值:name 属性值相同的元素对象组成的集合(伪数组形式)。
(4)不建议使用:在 IE 和 Opera 中有兼容问题,会多选中 id 属性值相同的元素
(1)方法:调用 document 对象的 getElementsByClassName 方法。(普通元素对象也可调用获取内部的元素)
(2)参数:字符串类型的 class 属性值。
(3)返回值:class 属性值相同的元素对象组成的动态集合(伪数组)。
(4)此方法内部获取的元素是动态增加的
(5)浏览器兼容问题:不支持 IE8 及以下的浏览器
1
2
(1)方法1:调用 document 对象的 querySelector 方法,通过 css 中的选择器去选取第一个符合条件的标签元素。
(2)方法2:调用 document 对象的 querySelectorAll 方法,通过 css 中的选择器去选取所有符合条件的标签元素集合(伪数组)。
(3)参数:字符串类型的 css 中的选择器。 (例如:.box / #nav)
(4)浏览器兼容问题:不支持 IE8
(5)需要将 js 代码写在 html 结构之后;不会动态增加
1
2
3
(1)获取 body 元素
document.body
(2)获取 html 元素
document.documentElement
(1)掌握,没有兼容问题
getElementById()
getElementsByTagName()
(2)了解
getElementsByName()
getElementsByClassName()
querySelector()
querySelectorAll()
JavaScript 使我们有能力创建动态页面,而事件是可以被 JavaScript 侦测到的行为,网页中的每个元素都可以产生某些可以触发 JavaScript 的事件。
(1)事件:在什么时候做什么事
(2)执行机制:触发–响应机制 (例:轮播图、下拉菜单)
(3)绑定事件(注册事件)三要素:
事件源:给谁绑定事件
事件类型:绑定什么类型的事件 (例:click 单击 )
事件函数:事件发生后执行什么内容,写在函数内部(采用函数赋值形式)
JavaScript 解析器会给有绑定事件的元素添加一个监听,解析器会一直监测这个元素,只要 触发对应的绑定事件,会立刻执行事件函数。
(1)绑定 HTML 元素属性。
(2)绑定 DOM 对象属性。
onclick → 鼠标左键单击触发
ondbclick → 鼠标左键双击触发
onmousedown → 鼠标按键按下触发
onmouseup → 鼠标按键放开时触发
onmousemove → 鼠标在元素上移动触发
onmouseover → 鼠标移动到元素上触发
onmouseout → 鼠标移出元素边界触发
onfocus → 获得鼠标焦点触发
onblur → 失去鼠标焦点触发
例如:href、title、id、src 等。
(1)调用方式:元素对象打点调用属性名,例如 obj.href。
(2)注意:部分的属性名跟关键字和保留字冲突,会更换写法。
class → className
for → htmlFor
rowspan → rowSpan
(3)属性赋值:给元素属性赋值,等号右侧的赋值都是字符串格式。
跳转
案例:点击切换图片
案例:点击按钮显示隐藏元素
/* CSS 代码 */
* {
margin: 0;
padding: 0;
}
div {
width: 200px;
height: 200px;
background-color: pink;
}
.hide {
display: none;
}
.show {
display: block;
}
补充:不同函数内部 this 的指向
(1)普通函数 → 指向 window 对象
(2)构造函数 → 指向生成的实例对象
(3)对象的方法 → 指向对象本身
(4)事件函数 → 指向事件源
案例:人物画廊
人物画廊
选择一个图片
/* CSS 代码 */
body {
background-color: #ccc;
margin: 1em 10%;
font-family: "Helvetica", "Arial", serif;
color: #333;
}
h2 {
background-color: transparent;
color: #333;
}
a {
background-color: transparent;
color: #c60;
font-weight: bold;
text-decoration: none;
}
#imagegallery a {
display: inline;
padding: 0px;
margin-right: 10px;
}
#imagegallery a img {
border: 0;
}
// js 代码
var imagegallery = document.getElementById("imagegallery");
var links = imagegallery.getElementsByTagName("a");
var image = document.getElementById("image");
var des = document.getElementById("des");
// 遍历数组 添加点击事件
for (var i = 0; i < links.length; i++) {
links[i].onclick = function () {
// this 关键字指代的是触发事件的真正事件源,此处写 links[i] 会出错
image.src = this.href;
des.innerText = this.title;
// 取消 a 标签的默认跳转效果
return false;
};
}
// for 循环内部添加的绑定事件,在触发时,所有的批量添加事件已经成功,触发事件时都是在循环结束之后
// 批量绑定的事件的事件函数内部如果有 i 变量,要注意,函数执行时已经是在循环结束后
// 循环内部定义的变量是一个全局变量,在循环后执行的 i 变量的值是 i 跳出循环时的值
// 若在循环内写 image.src = links[i].href; 此时的 i 的值是4,所以会出错
(1)innerHTML属性,在获取标签内部内容时,如果包含标签,获取的内容会包含标签,获取的内容包括空白换行等。
(2)innerText属性,在获取标签内部内容时,如果包含标签,获取的内容会过滤标签,获取的内容会去掉换行和缩进等空白。
(1)innerHTML 设置属性值,有标签的字符串,会按照 HTML 语法中的标签加载。 (在设置有内部子标签结构时使用)
(2)innerText 设置属性值,有标签的字符串,会按照普通的字符加载。(在设置纯字符串时使用)
这是一个 div 标签
这是一个 span 标签
总结:innerText 不识别 html 标签,非标准,去除空格和换行。
总结:innerHTML 识别 html 标签,W3C标准,保留空格和换行。
(1)value → 用于大部分表单元素的内容获取(option除外)
(2)type → 可以获取input标签的类型(输入框或复选框等)
(3)disabled → 禁用属性
(4)checked → 复选框选中属性
(5)selected →下拉菜单选中属性
* 注意:在 DOM 中元素对象的属性值只有一个时,会被转成布尔值显示。 例如:txt.disabled = true;
案例:随机设置下拉菜单中的选中项
案例:搜索文本框
/* CSS 代码 */
.gray {
color: gray;
}
.black {
color: black;
}
案例:全选与反选
商品
价钱
iPhone8
8000
iPad Pro
5000
iPad Air
2000
Apple Watch
2000
/* CSS 代码 */
* {
margin: 0;
padding: 0;
}
.wrap {
width: 300px;
margin: 100px auto 0;
}
table {
width: 300px;
border: 1px solid #c0c0c0;
border-collapse: collapse;
border-spacing: 0;
}
th,
td {
padding: 10px;
border: 1px solid #d0d0d0;
color: #404060;
}
th {
background-color: #09c;
color: #fff;
font: bold 16px "微软雅黑";
}
td {
font: 14px "微软雅黑";
}
tbody tr {
background-color: #f0f0f0;
}
tbody tr:hover {
cursor: pointer;
background-color: #fafafa;
}
(1)getAttribute(name) → 获取标签行内属性
(2)setAttribute(name,value) → 设置标签行内属性
(3)removeAttribute(name) → 移除标签行内属性
(4)与element.属性的区别: 上述三个方法用于获取任意的行内属性,包括自定义的属性。
(5)注意:
以上方法的参数都是字符串格式。
setAttribute 中传的参数 name 不需要进行属性名的修改,因为参数是字符串格式,和标识符不会有冲突。(例如:class 写作 class 就好,不用写成 className)
小明
补充:可以定义一个获取元素的函数,之后调用即可
function my$(id){
return document.getElementById(id);
}
// 存入变量中的原因:只调用一次函数,这个对象就可以反复使用
var btn = my$("btn"); // 获取 id 名为 btn 的元素
element.style (样式修改比较少或功能简单时使用)
(1)使用 style 属性方式设置的样式显示在标签行内。
(2)element.style 属性的值,是所有行内样式组成的一个样式对象。 (外联式和内嵌式获取不到)
(3)样式对象可以继续点语法调用或更改 css 的行内样式属性,例如 width、height 等属性。
(4)注意1:类似 background-color 这种复合属性的单一属性写法,是由多个单词组成的,要修改为驼峰命名方式书写 backgroundColor。
(5)注意2:通过样式属性设置宽高、位置的属性类型是字符串,需要加上 px 等单位
文字
element.className (样式修改比较多或功能复杂时使用)
(1)修改元素的 className 属性相当于直接修改标签的类名。
(2)如果需要修改多条 css 样式,可以提前将修改后的样式设置到一个类选择器中,后续通过 修改类名的方式,批量修改 css 样式
test.onclick = function () {
this.className = "first change";
// 多类名选择器:保留原先类名first,加上修改后的类名change(样式写在CSS代码中)
};
注:className 会直接更改元素的类名,会覆盖原先的类名,若要保留,则使用多类名选择器。
案例:显示隐藏二维码
/* CSS 代码 */
.box {
position: fixed;
right: 10px;
top: 40%;
width: 50px;
height: 50px;
background: url(images/bgs.png) no-repeat -159px -51px;
}
.erweima {
position: absolute;
top: 0;
left: -150px;
}
.hide {
display: none;
}
.show {
display: block;
}
若有同一组元素,我们想要某一个元素实现某种样式,其他不需要,则用到循环的排他思想算法
所有元素全部清除样式
给当前元素设置样式
注意顺序不能颠倒,首先 for 循环排除所有,再设置自己
案例:文本框高亮显示
// js 代码
// 获取所有input文本框
var txts = document.getElementsByTagName("input");
for (var i = 0; i < txts.length; i++) {
// 排他思想:1.排除其他 2.保留自己
txts[i].onfocus = function () {
// 排除其他的方法:将所有的项包含自己都设置为默认样式
// 遍历数组,让所有的样式恢复默认
for (var j = 0; j < txts.length; j++) {
txts[j].style.backgroundColor = "";
}
// 保留自己的特殊样式
this.style.backgroundColor = "pink";
};
}
案例:开关灯案例
案例:表格隔行变色和高亮显示
表格 table 分为 thead 和 tbody,变色只有 tbody ,第一行 thead 不参与,所以只有 tbody 里的行 tr 变化。
// 获取 tbody
var tb = document.getElementById("tb");
// 获取 tbody 里的所有的 tr
var trs = tb.getElementsByTagName("tr");
// 1.隔行变色
for (var i = 0; i < trs.length; i++) {
// 下标为偶数的行显示粉色
// 下标为奇数的行显示灰色
if (i % 2 == 0) {
trs[i].style.backgroundColor = "pink";
} else {
trs[i].style.backgroundColor = "lightgray";
}
// 全局变量
var bgc;
// 鼠标移上高亮显示
trs[i].onmouseover = function () {
// 定义变量记录 tr 原来的颜色
bgc = this.style.backgroundColor;
this.style.backgroundColor = "skyblue";
};
// 鼠标离开恢复默认
trs[i].onmouseout = function () {
this.style.backgroundColor = bgc;
};
}
案例:tab 选项卡切换
体育
娱乐
新闻
综合
我是体育模块
我是娱乐模块
我是新闻模块
我是综合模块
/* css 代码 */
* {
margin: 0;
padding: 0;
}
.box {
width: 400px;
height: 300px;
border: 1px solid #ccc;
margin: 100px auto;
}
.box .hd {
height: 45px;
}
.hd span {
display: inline-block;
width: 90px;
height: 100%;
background-color: pink;
line-height: 45px;
text-align: center;
}
.hd span.current {
background-color: skyblue;
}
.bd div {
display: none;
height: 255px;
background-color: skyblue;
}
.bd div.current {
display: block;
}
目的:为了保存并使用数据。有些数据可以保存到页面中而不用保存到数据库中
因为有些自定义属性很容易引起歧义,不容易判断是元素的内置属性还是自定义属性,所以H5新增了自定义属性
(1)设置 H5 自定义属性
H5 规定自定义属性 data- 开头作为属性名并且赋值
或者在 JS 中设置 div.setAttribute("data-index",2);
(2)获取 H5 自定义属性
兼容性获取:`element.getAttribute(“data-index”)(兼容性好)
H5 新增:element.dataset.index / element.dataset["index"](IE11 才开始支持)(只能获取 data- 开头,dataset 是一个集合,里面存放了所有以 data 开头的自定义属性 )
注:如果自定义属性里面有多个 - 连接的单词,获取时采取驼峰命名法