关于 DOM (文档对象模型)

1. DOM 概念

文档对象模型(Document Object Model,简称 DOM),是 W3C 组织推荐的处理可扩展标记语言的标准编程接口。

它是一种与平台和语言无关的应用程序接口(API),它可以动态地访问程序和脚本,更新其内容、结构和 www 文档的风格(目前,HTML 和 XML 文档是通过说明部分定义的)。文档可以进一步被处理,处理的结果可以加入到当前的页面。

DOM 是一 种基于树的 API 文档,它要求在处理过程中整个文档都表示在存储器中。

总结:W3C 已经定义了一系列的DOM接口,通过这些DOM接口可以改变网页的内容、结构、样式。


2. DOM 树

关于 DOM (文档对象模型)_第1张图片

DOM 又称为文档树模型

(1)文档:一个网页可以称为文档,DOM中使用 document 表示

(2)节点:网页中的所有内容都是节点 (标签、属性、文本、注释等),DOM中用 node 表示

(3)元素:网页中的标签,DOM中使用 element 表示

(4)属性:标签的属性

注:DOM 把文档、节点、元素都看作是对象


 DOM 经常进行的操作

(1)获取元素

(2)对元素进行操作(设置其属性或调用其方法)

(3)动态创建元素

(4)事件(什么时机做相应的操作)

3.1.DOM 获取页面元素

获取页面元素

我们想要操作页面上的某部分(显示/隐藏,动画),需要先获取到该部分对应的元素,才进行后续操作。


3.1. 根据 id 获取元素

(1)方法:调用 document 对象的 getElementById 方法。

(2)参数:字符串类型的 id 的属性值。

(3)返回值:对应 id 名的元素对象。

(4)注意1:由于 id 名具有唯一性,部分浏览器支持直接使用 id 名访问元素,但不是标准方式, 不推荐使用。

(5)注意2:代码执行顺序,如果 js 在 html 结构之前,会导致结构未加载,不能获取对应id的元素


    

text

text1

text2

3.2. 根据标签名获取元素

(1)方法:调用 document 对象的 getElementsByTagName 方法。(普通元素对象也可调用获取内部的元素)

(2)参数:字符串类型的标签名。

(3)返回值:同名的元素对象组成的集合(以伪数组的形式存储)。

(4)注意1:操作数据时需要按照操作数组的方法进行。

(5)注意2:getElementsByTagName 方法内部获取的元素是动态增加的


    

text1

text2

text3

text4

text5

3.3. 元素对象内部获取标签元素

(1)获取的元素对象内部,本身也可以调用根据标签获取元素方法,例如 div 元素对象也可以调用 getElementsByTagName 方法。

(2)目的:缩小选择元素的范围,类似 css 中的后代选择器

(3)父元素必须是单个对象(必须指明是哪一个元素对象),获取时不包括父元素自己。


    

text1

text2

3.4. 根据 name 获取元素

(1)方法:调用 document 对象的 getElementsByName 方法。

(2)参数:字符串类型的 name 属性值。

(3)返回值:name 属性值相同的元素对象组成的集合(伪数组形式)。

(4)不建议使用:在 IE 和 Opera 中有兼容问题,会多选中 id 属性值相同的元素


    
0~10
11~20
21~30

3.5. 根据类名获取元素

(1)方法:调用 document 对象的 getElementsByClassName 方法。(普通元素对象也可调用获取内部的元素)

(2)参数:字符串类型的 class 属性值。

(3)返回值:class 属性值相同的元素对象组成的动态集合(伪数组)。

(4)此方法内部获取的元素是动态增加的

(5)浏览器兼容问题:不支持 IE8 及以下的浏览器


    

1

2

3.6. 根据选择器获取元素

(1)方法1:调用 document 对象的 querySelector 方法,通过 css 中的选择器去选取第一个符合条件的标签元素。

(2)方法2:调用 document 对象的 querySelectorAll 方法,通过 css 中的选择器去选取所有符合条件的标签元素集合(伪数组)。

(3)参数:字符串类型的 css 中的选择器。 (例如:.box / #nav)

(4)浏览器兼容问题:不支持 IE8

(5)需要将 js 代码写在 html 结构之后;不会动态增加


    

1

2

3

3.7. 获取特殊元素(body、html)

(1)获取 body 元素

document.body

(2)获取 html 元素

document.documentElement


3.8. 总结

(1)掌握,没有兼容问题

    getElementById()
    getElementsByTagName()

(2)了解

    getElementsByName()
    getElementsByClassName()
    querySelector()
    querySelectorAll()

4.DOM 事件基本应用

JavaScript 使我们有能力创建动态页面,而事件是可以被 JavaScript 侦测到的行为,网页中的每个元素都可以产生某些可以触发 JavaScript 的事件。

4.1. 事件

(1)事件:在什么时候做什么事

(2)执行机制:触发–响应机制 (例:轮播图、下拉菜单)

(3)绑定事件(注册事件)三要素:

    事件源:给谁绑定事件
    事件类型:绑定什么类型的事件 (例:click 单击 )
    事件函数:事件发生后执行什么内容,写在函数内部(采用函数赋值形式)

4.2. 事件监听

JavaScript 解析器会给有绑定事件的元素添加一个监听,解析器会一直监测这个元素,只要 触发对应的绑定事件,会立刻执行事件函数。

4.3. 常用事件监听方法

(1)绑定 HTML 元素属性。

(2)绑定 DOM 对象属性。


    
    

4.4. 常用的鼠标事件类型

    onclick → 鼠标左键单击触发
    ondbclick → 鼠标左键双击触发
    onmousedown → 鼠标按键按下触发
    onmouseup → 鼠标按键放开时触发
    onmousemove → 鼠标在元素上移动触发
    onmouseover → 鼠标移动到元素上触发
    onmouseout → 鼠标移出元素边界触发
    onfocus → 获得鼠标焦点触发
    onblur → 失去鼠标焦点触发

5.DOM 元素属性操作

5.1. 非表单元素的属性

例如: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,所以会出错

5.2. 获取标签内部内容的属性

(1)innerHTML属性,在获取标签内部内容时,如果包含标签,获取的内容会包含标签,获取的内容包括空白换行等。

(2)innerText属性,在获取标签内部内容时,如果包含标签,获取的内容会过滤标签,获取的内容会去掉换行和缩进等空白。

5.3. 更改标签内容

(1)innerHTML 设置属性值,有标签的字符串,会按照 HTML 语法中的标签加载。 (在设置有内部子标签结构时使用)

(2)innerText 设置属性值,有标签的字符串,会按照普通的字符加载。(在设置纯字符串时使用)

这是一个 div 标签 这是一个 span 标签

总结:innerText 不识别 html 标签,非标准,去除空格和换行。

总结:innerHTML 识别 html 标签,W3C标准,保留空格和换行。


5.4. 表单元素属性

(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;
}

5.5. 自定义属性操作

(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 的元素

5.6. style 样式属性操作

element.style (样式修改比较少或功能简单时使用)

(1)使用 style 属性方式设置的样式显示在标签行内。

(2)element.style 属性的值,是所有行内样式组成的一个样式对象。 (外联式和内嵌式获取不到)

(3)样式对象可以继续点语法调用或更改 css 的行内样式属性,例如 width、height 等属性。

(4)注意1:类似 background-color 这种复合属性的单一属性写法,是由多个单词组成的,要修改为驼峰命名方式书写 backgroundColor。

(5)注意2:通过样式属性设置宽高、位置的属性类型是字符串,需要加上 px 等单位


    
文字

5.7. className 样式属性操作

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;
}

5.8. 排他思想(算法)

若有同一组元素,我们想要某一个元素实现某种样式,其他不需要,则用到循环的排他思想算法

    所有元素全部清除样式
    给当前元素设置样式
    注意顺序不能颠倒,首先 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;
}

5.9. H5 自定义属性

目的:为了保存并使用数据。有些数据可以保存到页面中而不用保存到数据库中

因为有些自定义属性很容易引起歧义,不容易判断是元素的内置属性还是自定义属性,所以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 开头的自定义属性 )

注:如果自定义属性里面有多个 - 连接的单词,获取时采取驼峰命名法


 

你可能感兴趣的:(前端,javascript,html)