ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

dom介绍

2021-02-18 20:34:23  阅读:359  来源: 互联网

标签:dom 元素 介绍 查找 var td document 属性


一. 什么是DOM:.

Document Object Model

文档     对象    模型

 

1. 什么是: 一套专门操作网页中元素内容的对象和方法的集合。

 

 

2. 何时: 只要想操作网页中的内容,都要用DOM,其为操作网页的内容底层  jQuery  Vue 等等其底层也是经过了dom

 

3. DOM标准: W3C负责制定和维护了一套DOM标准,几乎所有浏览器100%兼容!  所以有兼容问题可以用dom来解决

4. 如何: 五件事: 增删改查+事件绑定

二. DOM树: 

1. DOM树: 内存中保存一个网页中所有内容的树型结构。

2. 为什么: 因为HTML的元素内容,都是上下级包含的嵌套结构。而树形结构是最直观的展现上下级包含关系的结构。

3.dom树构造:

 

 

 

三. 查找元素: 4种方式: 

1. 用很简单的方法就可直接获得的节点对象: 4个

(1). 树根对象: document

(2). <html>元素: document.documentElement

(3). <head>元素: document.head

(4). <body>元素: document.body

2. 按节点间关系查找元素: 2大类关系, 6个属性

(1). 节点树: 包含所有网页内容节点的完整树结构

a. 父子关系: 4个属性

1). 获得一个元素的父元素: 元素.parentNode

                                   父  节点/对象

说明: 因为一个元素的直接父元素,只能有一个,所以parentNode,总是返回一个元素对象

2). 获得一个元素下的所有直接子元素: 元素.childNodes

     子  节点/对象们

说明: 因为一个元素的直接子元素很可能有多个,所以childNodes总是返回一个类数组对象。其中包含当前元素下的多个直接子元素。

3). 获得一个元素下的第一个直接子元素: 元素.firstChild

  第一个孩子

4). 获得一个元素下的最后一个直接子元素: 元素.lastChild

  最后一个孩子

b. 兄弟关系: 2个属性

1). 获得当前元素相邻的前一个元素: 元素.previousSibling

     前一个 兄弟

2). 获得当前元素相邻的后一个元素: 元素.nextSibling

                       后一个 兄弟

(2). 问题: 节点树包含所有网页内容,甚至连看不见的换行和缩进,也当做树上的节点对象创建出来!因为程序员只关心元素,不关系换行和缩进等空字符,但是空字符却站着节点树上的位置。严重干扰了查找!——,几乎不用节点树的2大类关系和6个属性(所以可以忽略上面的内容)

(3). 解决: DOM标准又额外定义了一棵元素树。

a. 什么是: 只包含元素对象的树结构,不包含那些不是元素的文本节点。

b. 优点: 只包含元素,不包含文本,所以,不会干扰查找!——只要按节点间关系查找元素时,都用元素树,不用节点数。

(4). 元素树也包含2大类关系,6个属性: 

a. 父子关系: 

1). 获得元素的父元素: 元素.parentElement

  父   元素

2). 获得元素下的所有直接子元素: 元素.children

 孩子们

3). 获得元素下的第一个直接子元素: 元素.firstElementChild

第一个 元素 孩子

4). 获得元素下的最后一个直接子元素: 元素.lastElementChild

  最后一个  元素 孩子

b. 兄弟关系: 

1). 获得元素相邻的前一个兄弟元素: 元素.previousElementSibling

    前一个   元素  兄弟

2). 获得元素相邻的后一个兄弟元素: 元素.nextElementSibling

下一个 元素 兄弟

(5). 示例: 使用元素树关系属性查找页面中指定的元素: 

 1 <!DOCTYPE HTML>
 2 <html>
 3 
 4   <head>
 5     <title>DOM Tree</title>
 6     <meta charset="utf-8" />
 7   </head>
 8 
 9   <body>
10     <span id="s1">Hello</span>
11     <h1>标题一</h1>
12     <script>
13       console.log(document);
14       console.log(document.documentElement);
15       console.log(document.head);
16       console.log(document.body);
17       //DOM中: 
18       //console.log()输出的是DOM树结构,而不是当前元素在内存中的对象。
19       //如果想输出/查看当前元素的对象属性: 
20       console.dir(document);
21       console.dir(document.documentElement);
22       console.dir(document.head);
23       console.dir(document.body);
24 
25       //想获得span元素: body下的第一个直接子元素
26       var span=document.body.firstElementChild;
27       console.log(span);
28       //想获得h1元素:span的下一个兄弟 
29       var h1=span.nextElementSibling;
30       console.log(h1);
31 
32       //想获得span元素: body下的第一个直接子元素
33       var span=document.body.children[0];
34       console.log(span);
35       //想获得h1元素: body下第二个直接子元素
36       var h1=document.body.children[1];
37       console.log(h1);
38     </script>
39   </body>
40 
41 </html>
View Code

(6). 总结: 只要已经获得一个元素,想找他周围附件的元素时,才用节点间关系查找: 2大类关系,6个属性

关系图如下:

 

 

 

3. 按HTML特征查找: 4个函数: 

(1). 问题: 有些要找的元素,藏的很深,或离的很远,就不能用节点间关系查找了

(2). 解决: 可以用HTML特征查找元素

(3). 包括: 可以按4种特征查找: 

a. 按id查找一个元素对象

1). var 一个元素对象=document.getElementById("id名")

2). 意为:          在网页中  获得一个元素(通过id名)

3). 返回值:

i. 如果找到指定id名的元素,就返回这个元素对象

ii. 如果没找到指定id名的元素,则返回null

4). 强调: 

i. .前的主语必须是document

ii. 因为只找到一个元素,所以函数名中Element没有s结尾

5). 问题: id必须唯一,用id只能找到一个元素!

b. 按标签名查找多个元素

1). var 类数组对象=

任意父元素对象.getElementsByTagName("标签名")

2).意为: 

    在任意父元素下获得多个元素(通过标签名)

3). 返回值: 

i. 如果找到符合要求的元素,则返回一个类数组对象,其中包含多个符合要求的元素

ii. 如果没找到符合要求的元素,则返回一个空的类数组对象: 

{    length:0 }

4). 强调: 

i. .前的主语可以是任意父元素对象。而查找时,也只在指定的父元素下查找,不会超出指定的父元素的范围。

优化: 将查找范围限制在合理的范围内,可以提高查找效率。

当然!如果确实想在整个网页范围内查找,主语也可以时document对象。

ii. 因为极有可能找到多个元素,所以函数中的Elements是s结尾表示多个。而且返回值还是类数组对象。

iii. 不仅在直接子元素中查找,而且还会在所有后代中查找。

iv. 坑: 如果只找到一个符合要求的元素,也是默认放在一个类数组对象中返回的!但是,我们只想要这一个元素对象,而不想要整个类数组对象。

解决: 只要用[0],就能取出找到的唯一的一个元素对象.

示例: 按Id查找和按标签名查找元素

 1 <!DOCTYPE HTML>
 2 <html>
 3   <head>
 4     <title>遍历节点树</title>
 5     <meta charset="utf-8"/>
 6     
 7   </head>
 8   <body>
 9     <span>Hello World !</span>
10     <ul id="nav">
11       <li>电影</li>
12       <li>综艺
13         <ul>
14           <li>跑男</li>
15           <li>爸爸</li>
16           <li>极限</li>
17         </ul>
18       </li>
19       <li>剧集</li>
20     </ul> 
21     <script>
22       //想查找id为nav的一个元素
23       var ulNav=document.getElementById("nav");
24       console.log(ulNav);
25 
26       //想在ulNav下查找所有li元素
27       var lis=ulNav.getElementsByTagName("li");
28       console.log(lis);
29       //想在ulNav下查找所有a元素
30       var as=ulNav.getElementsByTagName("a");
31       console.log(as);
32 
33       //想找ulNav下的一个ul元素
34       //错误: 只能获得一个大的集合,无法精确获得一个元素对象
35       // var ulSub=ulNav.getElementsByTagName("ul")
36       //正确: 加[0];
37       var ulSub=ulNav.getElementsByTagName("ul")[0]
38       console.log(ulSub);
39     </script>
40   </body>
41 </html>
View Code

c.按class名查找多个元素:

 var 类数组对象=任意父元素.getElementsByClassName("class名")

意为:       在任意父元素下   获得多个元素  通过class名

 

 

返回值:

1). 如果找到符合要求的元素,就返回一个类数组对象

2). 如果没找到符合要求的元素,就返回空的类数组对象: {  length:0 }

强调: 

1). 可以在任意指定的父元素下查找。合理的设置查找范围,可以优化查找的效率!当然,如果确实需要在整个页面中查找,也可以写document开头。

2). 因为可能找到多个符合要求的元素,所以,函数名中的Elements是s结尾,表示多个元素。

3). 即使只找到一个元素,也会放在类数组对象中返回,所以,要想获得找到的唯一一个元素,必须加[0]

4). 不仅查找直接子元素,而且会在所有后代中查找符合要求的元素。

5). 即使一个元素上,同时被多个class名修饰,那么只需要其中一个class名就可以找到当前元素。

d. 按name名查找表单元素:

var 类数组对象=document.getElementsByName("name名")

意为:        在页面中 获得多个元素    通过Name名

返回值:

1). 如果找到符合要求的元素,就返回一个类数组对象

2). 如果没找到符合要求的元素,就返回空的类数组对象: {  length:0 }

强调: 

1). .前必须是document作为主语!

2). 因为可能找到多个符合要求的元素,所以,函数名中的Elements是s结尾,表示多个元素。

3). 即使只找到一个元素,也会放在类数组对象中返回,所以,要想获得找到的唯一一个元素,必须加[0]

示例:按HTML特征查找指定元素

 1 <!DOCTYPE HTML>
 2 <html>
 3   <head>
 4     <title>遍历节点树</title>
 5     <meta charset="utf-8"/>
 6     
 7   </head>
 8   <body>
 9     <span>Hello World !</span>
10     <ul id="nav">
11       <li class="item">电影</li>
12       <li class="item">综艺
13         <ul>
14           <li class="item active">跑男</li>
15           <li class="item">爸爸</li>
16           <li class="item">极限</li>
17         </ul>
18       </li>
19       <li class="item">剧集</li>
20     </ul> 
21     <form>
22       用户名:<input name="uname"></br>
23       性别:
24       <label><input type="radio" name="sex" value="1">男</label>
25       <label><input type="radio" name="sex" value="0">女</label>
26     </form>
27     <script>
28       //想查找id为nav的一个元素
29       var ulNav=document.getElementById("nav");
30       console.log(ulNav);
31 
32       //想在ulNav下查找所有li元素
33       var lis=ulNav.getElementsByTagName("li");
34       console.log(lis);
35       //想在ulNav下查找所有a元素
36       var as=ulNav.getElementsByTagName("a");
37       console.log(as);
38 
39       //想找ulNav下的一个ul元素
40       //错误: 只能获得一个大的集合,无法精确获得一个元素对象
41       // var ulSub=ulNav.getElementsByTagName("ul")
42       //正确: 加[0];
43       var ulSub=ulNav.getElementsByTagName("ul")[0]
44       console.log(ulSub);
45 
46       
47       //想查找ulNav下class为item的所有元素
48       var items=
49         ulNav.getElementsByClassName("item");
50       console.log(items);
51       //想查找class为active的一个元素
52       var liActive=
53         ulNav.getElementsByClassName("active")[0];
54       console.log(liActive);
55       //想找name为sex的多个单选按钮
56       var radios=
57         document.getElementsByName("sex");
58       console.log(radios);
59       //想查找name为uname的一个文本框
60       var txtName=
61         document.getElementsByName("uname")[0]
62       console.log(txtName);
63     </script>
64   </body>
65 </html>
View Code

4.按选择器查找: 今后只要查找条件非常复杂时,都用选择器查找: 2个函数

(1). 只查找一个符合要求的元素: 

a. var 一个元素对象=任意父元素.querySelector("css选择器")

b. 意为          在任意父元素下  用选择器  查找一个元素

 

 

c. 返回值:

1). 如果找到,返回一个元素对象

2). 如果没找到,返回null

d. 强调: 

1). 也可以在任意父元素范围内查找,当然也可以在整个网页范围内查找

(2). 查找多个符合要求的元素: 

a. var 类数组对象=任意父元素.querySelectorAll("css选择器");

b. 意为:        在任意父元素下   用选择器  查找       所有符合要求的元素

c. 返回值: 

1). 如果找到多个符合要求的元素,就放在一个类数组对象中返回

2). 如果没找到符合要求的元素,就返回一个空的类数组对象:{  length:0 }

d. 强调: 

1). 也可以在任意父元素范围内查找,当然也可以在整个网页范围内查找。

 (3)示例: 购物车

(1). 任何DOM效果,都要经历4步: 

 

a. 查找触发事件的元素

 

b. 为元素绑定事件处理函数

 

c. 查找要修改的元素

 

d. 修改元素

 

(2). 事件概述: 

 

a. 什么是事件: 浏览器自动触发的或用户手动触发的页面中元素状态的变化。

 

b. 什么是事件处理函数:提前保存在元素的事件属性上的,当事件发生时,自动执行的函数。

 

c. 何时使用事件处理函数:  ,只要希望当事件发生时,能自动执行一项任务时。

 

d. 如何使用事件处理函数: ——事件绑定,2种: 

 

1). 在HTML中: 2步: 

 

i. 在网页的<head>中,先定义一个事件处理函数

 

function 函数名(){

 

... ...

 

}

 

ii. 在元素的开始标签中:<元素  on事件名="函数名()">

 

iii. 问题: 是将js函数的调用和事件绑定,写在HTML中,不符合内容与行为分离的原则,不便于 的维护!

 

2). 在js中: 2步: 

 

i. 查找触发事件的元素

 

ii. 为元素绑定事件处理函数: 

 

元素对象.on事件名=function(){

 

... ...

 

}

 

iii. 原理: 

 

先将事件处理函数,暂存在元素对象身上的事件属性上,暂不执行

 

将来,当用户触发这个元素上的对应事件时,才自动找出之前暂存的事件处理函数,自动调用!

 

iv. 优点: 所有事件绑定的代码,都集中定义在js中,极其便于 的维护!

 

v. 说明: 如果在js中绑定事件,则js代码必须写在<body>元素的结尾!所有网页HTML内容之后。因为网页顺序执行,必须先创建HTML元素,才能在js中查找元素,绑定事件。

 

e. 如何在事件处理函数中,自动获得当前触发事件的元素: 

 

1). 错误: 用事件处理函数外的全局变量!

 

原因: 因为事件处理函数的定义和将来的触发之间是有时间差的!而全局变量很可能在这个时间差之内,被篡改为其它值。——不靠谱

 

2). 正确: 只要想在事件处理函数中获得正在触发事件的当前DOM元素对象,都用this!this可在事件发生时,自动指向当前正在触发的元素对象。

 

f1. 示例: 为购物车中每个按钮绑定单击事件: 

 

  1 <!DOCTYPE HTML>
  2 <html>
  3 
  4 <head>
  5   <title>使用Selector API实现购物车客户端计算</title>
  6   <meta charset="utf-8" />
  7   <style>
  8     table {
  9       width: 600px;
 10       text-align: center;
 11       border-collapse: collapse;
 12     }
 13 
 14     td,
 15     th {
 16       border: 1px solid black
 17     }
 18 
 19     td[colspan="3"] {
 20       text-align: right;
 21     }
 22   </style>
 23 
 24 </head>
 25 
 26 <body>
 27   <table id="data">
 28     <thead>
 29       <tr>
 30         <th>商品名称</th>
 31         <th>单价</th>
 32         <th>数量</th>
 33         <th>小计</th>
 34       </tr>
 35     </thead>
 36     <tbody>
 37       <tr>
 38         <td>iPhone6</td>
 39         <td>¥4488.00</td>
 40         <td>
 41           <button>-</button>
 42           <span>1</span>
 43           <button>+</button>
 44         </td>
 45         <td>¥4488.00</td>
 46       </tr>
 47       <tr>
 48         <td>iPhone6 plus</td>
 49         <td>¥5288.00</td>
 50         <td>
 51           <button>-</button>
 52           <span>1</span>
 53           <button>+</button>
 54         </td>
 55         <td>¥5288.00</td>
 56       </tr>
 57       <tr>
 58         <td>iPad Air 2</td>
 59         <td>¥4288.00</td>
 60         <td>
 61           <button>-</button>
 62           <span>1</span>
 63           <button>+</button>
 64         </td>
 65         <td>¥4288.00</td>
 66       </tr>
 67     </tbody>
 68     <tfoot>
 69       <tr>
 70         <td colspan="3">Total: </td>
 71         <td>¥14064.00</td>
 72       </tr>
 73     </tfoot>
 74   </table>
 75   <script>
 76     //1. 查找触发事件的元素
 77     //本例中: 用户点击table中的button触发变化
 78     //1.1 先查找id为data的table
 79     var table=document.getElementById("data")
 80     //1.2 再在table下查找所有的按钮
 81     var btns=
 82       table.getElementsByTagName("button")
 83     console.log(btns);
 84     //2. 绑定事件处理函数
 85     //本例中: 因为所有的按钮都要绑定单击事件,所以需要遍历找到的每个按钮
 86     for(var btn of btns){
 87       //每遍历一个按钮,就为这个按钮绑定单击事件处理函数
 88       btn.onclick=function(){
 89         // alert("疼!")
 90         //希望,点哪个按钮,就只让哪个按钮的内容变成❀
 91         //错误: 因为btn是全局变量,很可能发生变化
 92         // btn.innerHTML="❀";
 93         //正确: 
 94         this.innerHTML="❀";
 95       }
 96     }
 97 
 98       //3. 查找要修改的元素
 99       //4. 修改元素
100 
101   </script>
102 </body>
103 
104 </html>
View Code

f2. 点按钮,修改数量

 

  1 <!DOCTYPE HTML>
  2 <html>
  3 
  4 <head>
  5   <title>使用Selector API实现购物车客户端计算</title>
  6   <meta charset="utf-8" />
  7   <style>
  8     table {
  9       width: 600px;
 10       text-align: center;
 11       border-collapse: collapse;
 12     }
 13 
 14     td,
 15     th {
 16       border: 1px solid black
 17     }
 18 
 19     td[colspan="3"] {
 20       text-align: right;
 21     }
 22   </style>
 23 
 24 </head>
 25 
 26 <body>
 27   <table id="data">
 28     <thead>
 29       <tr>
 30         <th>商品名称</th>
 31         <th>单价</th>
 32         <th>数量</th>
 33         <th>小计</th>
 34       </tr>
 35     </thead>
 36     <tbody>
 37       <tr>
 38         <td>iPhone6</td>
 39         <td>¥4488.00</td>
 40         <td>
 41           <button>-</button>
 42           <span>1</span>
 43           <button>+</button>
 44         </td>
 45         <td>¥4488.00</td>
 46       </tr>
 47       <tr>
 48         <td>iPhone6 plus</td>
 49         <td>¥5288.00</td>
 50         <td>
 51           <button>-</button>
 52           <span>1</span>
 53           <button>+</button>
 54         </td>
 55         <td>¥5288.00</td>
 56       </tr>
 57       <tr>
 58         <td>iPad Air 2</td>
 59         <td>¥4288.00</td>
 60         <td>
 61           <button>-</button>
 62           <span>1</span>
 63           <button>+</button>
 64         </td>
 65         <td>¥4288.00</td>
 66       </tr>
 67     </tbody>
 68     <tfoot>
 69       <tr>
 70         <td colspan="3">Total: </td>
 71         <td>¥14064.00</td>
 72       </tr>
 73     </tfoot>
 74   </table>
 75   <script>
 76     //1. 查找触发事件的元素
 77     //本例中: 用户点击table中的button触发变化
 78     //1.1 先查找id为data的table
 79     var table=document.getElementById("data")
 80     //1.2 再在table下查找所有的按钮
 81     var btns=
 82       table.getElementsByTagName("button")
 83     console.log(btns);
 84     //2. 绑定事件处理函数
 85     //本例中: 因为所有的按钮都要绑定单击事件,所以需要遍历找到的每个按钮
 86     for(var btn of btns){
 87       //每遍历一个按钮,就为这个按钮绑定单击事件处理函数
 88       btn.onclick=function(){
 89         //this->当前正在触发事件的按钮元素对象
 90         //3. 查找要修改的元素
 91         //本例中: 点任何按钮,都是要修改旁边的span
 92         //    当前按钮的父元素      的孩子们中第二个
 93         var span=this.parentElement.children[1];
 94         //4. 修改元素
 95         //4.1 取出元素中现在的旧值,转为整数
 96         var n=parseInt(span.innerHTML);
 97         //4.2 计算出新值
 98         //如果点的按钮的内容是+
 99         if(this.innerHTML=="+"){
100           n++;//就将n+1
101         }else if(n>1){//否则如果点的按钮的内容是-,且只有n>1时
102           n--;//才将n-1
103         }
104         //4.3 再将新值放回元素中
105         span.innerHTML=n;
106       }
107     }
108   </script>
109 </body>
110 
111 </html>
View Code

 

f3.数量变,修改小计

 

  1 <!DOCTYPE HTML>
  2 <html>
  3 
  4 <head>
  5   <title>使用Selector API实现购物车客户端计算</title>
  6   <meta charset="utf-8" />
  7   <style>
  8     table {
  9       width: 600px;
 10       text-align: center;
 11       border-collapse: collapse;
 12     }
 13 
 14     td,
 15     th {
 16       border: 1px solid black
 17     }
 18 
 19     td[colspan="3"] {
 20       text-align: right;
 21     }
 22   </style>
 23 
 24 </head>
 25 
 26 <body>
 27   <table id="data">
 28     <thead>
 29       <tr>
 30         <th>商品名称</th>
 31         <th>单价</th>
 32         <th>数量</th>
 33         <th>小计</th>
 34       </tr>
 35     </thead>
 36     <tbody>
 37       <tr>
 38         <td>iPhone6</td>
 39         <td>¥4488.00</td>
 40         <td>
 41           <button>-</button>
 42           <span>1</span>
 43           <button>+</button>
 44         </td>
 45         <td>¥4488.00</td>
 46       </tr>
 47       <tr>
 48         <td>iPhone6 plus</td>
 49         <td>¥5288.00</td>
 50         <td>
 51           <button>-</button>
 52           <span>1</span>
 53           <button>+</button>
 54         </td>
 55         <td>¥5288.00</td>
 56       </tr>
 57       <tr>
 58         <td>iPad Air 2</td>
 59         <td>¥4288.00</td>
 60         <td>
 61           <button>-</button>
 62           <span>1</span>
 63           <button>+</button>
 64         </td>
 65         <td>¥4288.00</td>
 66       </tr>
 67     </tbody>
 68     <tfoot>
 69       <tr>
 70         <td colspan="3">Total: </td>
 71         <td>¥14064.00</td>
 72       </tr>
 73     </tfoot>
 74   </table>
 75   <script>
 76     //1. 查找触发事件的元素
 77     //本例中: 用户点击table中的button触发变化
 78     //1.1 先查找id为data的table
 79     var table=document.getElementById("data")
 80     //1.2 再在table下查找所有的按钮
 81     var btns=
 82       table.getElementsByTagName("button")
 83     console.log(btns);
 84     //2. 绑定事件处理函数
 85     //本例中: 因为所有的按钮都要绑定单击事件,所以需要遍历找到的每个按钮
 86     for(var btn of btns){
 87       //每遍历一个按钮,就为这个按钮绑定单击事件处理函数
 88       btn.onclick=function(){
 89         //this->当前正在触发事件的按钮元素对象
 90         //3. 查找要修改的元素
 91         //本例中: 点任何按钮,都是要修改旁边的span
 92         //    当前按钮的父元素      的孩子们中第二个
 93         var span=this.parentElement.children[1];
 94         //4. 修改元素
 95         //4.1 取出元素中现在的旧值,转为整数
 96         var n=parseInt(span.innerHTML);
 97         //4.2 计算出新值
 98         //如果点的按钮的内容是+
 99         if(this.innerHTML=="+"){
100           n++;//就将n+1
101         }else if(n>1){//否则如果点的按钮的内容是-,且只有n>1时
102           n--;//才将n-1
103         }
104         //4.3 再将新值放回元素中
105         span.innerHTML=n;
106 
107         /*数量修改,修改小计*/
108         //3. 查找要修改的元素
109         //本例中: 查找当前按钮所在行的最后一个td
110         var lastTd=
111           this.parentElement.nextElementSibling;
112         //当前按钮的父元素td 的下一个兄弟元素td
113         //4. 修改元素
114         //4.1 从当前按钮的父元素td的前一个兄弟元素td中获得单价字符串,去掉开头的¥,再转为小数,获得单价
115         var price=parseFloat(//转为小数
116           this.parentElement//当前按钮的父元素td
117               .previousElementSibling//的前一个兄弟元素td
118               .innerHTML//的内容
119               .slice(1)//去掉开头的¥符号
120         )
121         //4.2 用单价*数量=小计
122         var subTotal=price*n;
123         //4.3 将小计放回当前行最后一个td的内容中
124         lastTd.innerHTML=`¥${subTotal.toFixed(2)}`
125       }
126     }
127   </script>
128 </body>
129 
130 </html>
View Code

f5. 小计变,修改总计

  1 <!DOCTYPE HTML>
  2 <html>
  3 
  4 <head>
  5   <title>使用Selector API实现购物车客户端计算</title>
  6   <meta charset="utf-8" />
  7   <style>
  8     table {
  9       width: 600px;
 10       text-align: center;
 11       border-collapse: collapse;
 12     }
 13 
 14     td,
 15     th {
 16       border: 1px solid black
 17     }
 18 
 19     td[colspan="3"] {
 20       text-align: right;
 21     }
 22     /*想修改tfoot中最后一个td的背景颜色为黄色*/
 23     tfoot td:last-child{
 24       background-color: yellow;
 25     }
 26     /*想修改tbody中每行最后一个td的背景色为粉色*/
 27     tbody td:last-child{
 28       background-color: pink;
 29     }
 30   </style>
 31 
 32 </head>
 33 
 34 <body>
 35   <table id="data">
 36     <thead>
 37       <tr>
 38         <th>商品名称</th>
 39         <th>单价</th>
 40         <th>数量</th>
 41         <th>小计</th>
 42       </tr>
 43     </thead>
 44     <tbody>
 45       <tr>
 46         <td>iPhone6</td>
 47         <td>¥4488.00</td>
 48         <td>
 49           <button>-</button>
 50           <span>1</span>
 51           <button>+</button>
 52         </td>
 53         <td>¥4488.00</td>
 54       </tr>
 55       <tr>
 56         <td>iPhone6 plus</td>
 57         <td>¥5288.00</td>
 58         <td>
 59           <button>-</button>
 60           <span>1</span>
 61           <button>+</button>
 62         </td>
 63         <td>¥5288.00</td>
 64       </tr>
 65       <tr>
 66         <td>iPad Air 2</td>
 67         <td>¥4288.00</td>
 68         <td>
 69           <button>-</button>
 70           <span>1</span>
 71           <button>+</button>
 72         </td>
 73         <td>¥4288.00</td>
 74       </tr>
 75     </tbody>
 76     <tfoot>
 77       <tr>
 78         <td colspan="3">Total: </td>
 79         <td>¥14064.00</td>
 80       </tr>
 81     </tfoot>
 82   </table>
 83   <script>
 84     //1. 查找触发事件的元素
 85     //本例中: 用户点击table中的button触发变化
 86     //1.1 先查找id为data的table
 87     var table=document.getElementById("data")
 88     //1.2 再在table下查找所有的按钮
 89     var btns=
 90       table.getElementsByTagName("button")
 91     console.log(btns);
 92     //2. 绑定事件处理函数
 93     //本例中: 因为所有的按钮都要绑定单击事件,所以需要遍历找到的每个按钮
 94     for(var btn of btns){
 95       //每遍历一个按钮,就为这个按钮绑定单击事件处理函数
 96       btn.onclick=function(){
 97         //this->当前正在触发事件的按钮元素对象
 98         //3. 查找要修改的元素
 99         //本例中: 点任何按钮,都是要修改旁边的span
100         //    当前按钮的父元素      的孩子们中第二个
101         var span=this.parentElement.children[1];
102         //4. 修改元素
103         //4.1 取出元素中现在的旧值,转为整数
104         var n=parseInt(span.innerHTML);
105         //4.2 计算出新值
106         //如果点的按钮的内容是+
107         if(this.innerHTML=="+"){
108           n++;//就将n+1
109         }else if(n>1){//否则如果点的按钮的内容是-,且只有n>1时
110           n--;//才将n-1
111         }
112         //4.3 再将新值放回元素中
113         span.innerHTML=n;
114 
115         /*数量修改,修改小计*/
116         //3. 查找要修改的元素
117         //本例中: 查找当前按钮所在行的最后一个td
118         var lastTd=
119           this.parentElement.nextElementSibling;
120         //当前按钮的父元素td 的下一个兄弟元素td
121         //4. 修改元素
122         //4.1 从当前按钮的父元素td的前一个兄弟元素td中获得单价字符串,去掉开头的¥,再转为小数,获得单价
123         var price=parseFloat(//转为小数
124           this.parentElement//当前按钮的父元素td
125               .previousElementSibling//的前一个兄弟元素td
126               .innerHTML//的内容
127               .slice(1)//去掉开头的¥符号
128         )
129         //4.2 用单价*数量=小计
130         var subTotal=price*n;
131         //4.3 将小计放回当前行最后一个td的内容中
132         lastTd.innerHTML=`¥${subTotal.toFixed(2)}`;
133 
134         /*小计改变,修改总计*/
135         //3. 查找要修改的元素
136         //本例中: 总价计算完,要放入tfoot中最后一个td里!
137         var totalTd=document.querySelector(
138           "tfoot td:last-child"
139         );
140         console.log(totalTd);
141         //4. 修改元素
142         //4.1 查找tbody中每行最后一个td
143         var tds=document.querySelectorAll(
144           "tbody td:last-child"
145         );
146         console.log(tds);
147         //4.2 遍历每行最后一个td中的小计,累加到总计中
148         var total=0;
149         for(var td of tds){
150           //每遍历一个td,就获取td的内容,去掉开头的¥,转为浮点数,并累加到总计变量中
151           total+=parseFloat(
152             td.innerHTML.slice(1)
153           )
154         }
155         //4.3 将总价格式化之后,再放回总价td中
156         totalTd.innerHTML=`¥${total.toFixed(2)}`;
157       }
158     }
159 
160       
161 
162   </script>
163 </body>
164 
165 </html>
View Code

四,修改  3种东西: 内容,属性,样式

修改内容

(1). 获取或修改元素的开始标签到结束标签之间的原始的HTML内容:

元素.innerHTML

(2). 获取或修改元素的开始标签到结束标签之间的纯文本内容: 

元素.textContent

说明: textContent多做2件事: 

1). 去掉了内嵌的HTML标签

2). 将特殊符号翻译为正文

(3). 获取或修改表单元素的值: 

a. 问题: 绝大多数表单元素都是input,单标记。没有结束标签!
b. 解决:  只要获取或修改表单元素的值,都要用: 元素.value

(4). 示例: 使用三种方式获取元素的内容: 

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4   <meta charset="UTF-8">
 5   <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6   <meta name="viewport" content="width=device-width, initial-scale=1.0">
 7   <title>Document</title>
 8 </head>
 9 <body>
10   <h3 id="h3">来自&lt;&lt;<a href="#">新华社</a>&gt;&gt;的消息</h3>
11   <input id="txt" type="text">
12   <button id="btn">百度一下</button>
13   <script>
14     var h3=document.getElementById("h3");
15     //获取h3开始标签到结束标签之间的原始的HTML内容
16     console.log(h3.innerHTML);
17     //想获得h3开始标签到结束标签之间的纯文本内容:
18     console.log(h3.textContent);
19 
20     //单击按钮时,能获得用户在文本框中输入的内容
21     var btn=document.getElementById("btn");
22     btn.onclick=function(){
23       var input=document.getElementById("txt")
24       console.log(`用户想搜索${input.value}相关的内容...`)
25     }
26   </script>
27 </body>
28 </html>
View Code

(5). 示例: 动画开关门效果: 

 1 <!DOCTYPE HTML>
 2 <html>
 3 <head>
 4 <title>读取并修改元素的内容</title>
 5 <meta charset="utf-8" />
 6 <style>
 7   div{float:left; height: 100px; line-height: 100px; }
 8   #d1,#d3{ background-color: #ccff00; }
 9   #d2{ cursor: pointer; background-color: #ffcc00; }
10 </style>
11 </head>
12 <body>
13   <div id="d1">树形列表</div>
14   <div id="d2">&lt;&lt;</div>
15   <div id="d3">内容的主体</div>
16   <script>
17     //DOM 4步
18     //1. 查找触发事件的元素
19     //本例中: 用户点d2触发变化
20     var d2=document.getElementById("d2");
21     //2. 绑定事件处理函数
22     d2.onclick=function(){
23       //一定不要用函数外部的全局变量"d2",
24       //要用this->当前点的d2
25       //3. 查找要修改的元素
26       //本例中: 点击d2,是要显示隐藏d1
27       var d1=document.getElementById("d1");
28       //4. 修改元素
29       //如果当前点击的d2的内容是<<
30       if(this.innerHTML=="&lt;&lt;"){
31         //就把d1隐藏:
32         //HTML中:
33         //<div id="d1" style="display:none">
34         //js中:           ↑      ↑      ↑
35         d1             .style.display="none";
36         //顺便把当前点击的d2的内容改为>>
37         this.innerHTML="&gt;&gt;"
38       }else{//否则如果当前点击的d2的内容是>>
39         //就把d1显示
40         d1.style.display="";//不用写block,意为所有元素默认都是显示的.
41         //顺便把当前点击的d2的内容改为<<
42         this.innerHTML="&lt;&lt;"
43       }
44     }
45   </script>
46 </body>
47 </html>
View Code

修改属性:3种

(1). 字符串类型的HTML标准属性

a. 什么是: HTML标准中规定的,属性值为字符串类型的属性

b. 比如: id, src, title, href ... ...

c. 如何: 2种方式: 

1). 使用旧的核心DOM的4个函数: 

i. 获取属性值: 元素.getAttribute("属性名")

ii. 修改属性值: 元素.setAttribute("属性名","属性值")

iii. 判断是否包含某个属性: 元素.hasAttribute("属性名")

iv. 移除属性: 元素.removeAttribute("属性名")

2). 新的HTML DOM中推出了简写: 

i. 新的HTML DOM已经提前将所有HTML标准属性,定义在了内存中的元素对象身上。无论用不用,都已经长在内存中的元素对象身上了!只不过,暂时没用到的属性,属性值默认为""

ii. 如何访问内存中的元素对象身上的属性: 元素. 属性名

比如: 

获取属性值: 元素.属性名

修改属性值: 元素.属性名="新值"

判断是否包含某个属性: 元素.属性名!==""

移除属性: 元素.属性名=""

d. 示例: 分别使用核心DOM和HTML DOM操作a元素的属性

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4   <meta charset="UTF-8">
 5   <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6   <meta name="viewport" content="width=device-width, initial-scale=1.0">
 7   <title>Document</title>
 8 </head>
 9 <body>
10   <a id="a1" href="http://www.cnblog.com" target="_blank">go to   myblog</a>
11   <script>
12     var a1=document.getElementById("a1");
13     //想获取a1的href属性
14     //console.log(a1.getAttribute("href"))
15     console.log(a1.href);
16     //想修改a1的target属性
17     //a1.setAttribute("target","_self");
18     a1.target="_self";
19     //判断a1是否包含title属性
20     //console.log(a1.hasAttribute("title"));//false
21     console.log(a1.title!=="")
22     //给a1添加title属性
23     //a1.setAttribute("title","欢迎访问myblog")
24     a1.title="欢迎访问  myblog"
25     //判断a1是否包含title属性
26     //console.log(a1.hasAttribute("title"));//true
27     console.log(a1.title!=="")
28     //移除a1的id属性
29     //a1.removeAttribute("id");
30     a1.id="";
31     console.log(a1);
32     console.dir(a1);
33   </script>
34 </body>
35 </html>
View Code

e. 特例: class属性: 

1). 问题: 按理说,操作class属性,也可以用"元素.class"。但是,因为class是ES标准中的关键字!专门用于创建一种类型!所以,DOM就不能用class再操作样式!DOM中的class属性和ES中的class关键字冲突了!

2). 解决:  ,只要在DOM中操作元素的class属性,必须更名为"className"。操作"元素.className",等效于操作<元素 class="xxx">

f. 示例: 手风琴效果: 

 1 <!DOCTYPE HTML>
 2 <html>
 3 
 4 <head>
 5   <title>1. 实现伸缩二级菜单</title>
 6   <meta charset="utf-8" />
 7   <style>
 8     li {
 9       list-style: none;
10     }
11 
12     li span {
13       padding-left: 20px;
14       cursor: pointer;
15       background: url("../images/add.png") no-repeat center left;
16     }
17 
18     li ul {
19       display: none;
20     }
21 
22     .open {
23       background: url("../images/minus.png") no-repeat center left;
24     }
25 
26     .open+ul {
27       display: block;
28     }
29   </style>
30 </head>
31 
32 <body>
33   <ul class="tree">
34     <li>
35       <span class="open">考勤管理</span>
36       <ul>
37         <li>日常考勤</li>
38         <li>请假申请</li>
39         <li>加班/出差</li>
40       </ul>
41     </li>
42     <li>
43       <span>信息中心</span>
44       <ul>
45         <li>通知公告</li>
46         <li>公司新闻</li>
47         <li>规章制度</li>
48       </ul>
49     </li>
50     <li><span>协同办公</span>
51       <ul>
52         <li>公文流转</li>
53         <li>文件中心</li>
54         <li>内部邮件</li>
55         <li>即时通信</li>
56         <li>短信提醒</li>
57       </ul>
58     </li>
59   </ul>
60   <script>
61     //DOM 4步
62     //1. 查找触发事件的元素
63     //本例中: 用户点击每个span触发变化
64     var spans=document.getElementsByTagName("span")
65     //2. 绑定事件处理函数
66     //本例中: 因为多个span都需要单击,所以遍历每个span
67     for(var span of spans){
68       //为每个span绑定单击事件
69       span.onclick=function(){
70         //尽量不要用函数外部的spans和span——不靠谱
71         //this->当前点击的这一个span
72         //3. 查找要修改的元素
73         //4. 修改元素
74         //先找到所有的span,清除他们身上的class=open
75         var spans=document.getElementsByTagName("span");
76         for(var span of spans){
77           span.className="";
78         //<span class="">
79         }
80         //再只给当前span自己加class="open"
81         this.className="open";
82       }
83     }
84       
85   </script>
86 </body>
87 
88 </html>
View Code

(2). bool类型HTML标准属性: 1种

a. 什么是: HTML标准规定的,只要写在元素开始标签中就起作用的属性,无需指定属性值。

b. 比如: checked, selected, disabled, ...

c. 如何: 

1). 不能用核心DOM的4个函数: 因为核心DOM的4个函数,不支持bool类型的值!只支持字符串类型的属性值。

2). 只能用HTML DOM的简写: 元素.属性名,且,属性值必须是bool类型。

d. 补: CSS3中的状态伪类选择器:  :checked 专门匹配已选中的元素

e. 示例: 全选和取消全选: 

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4 <meta charset="utf-8" />
 5 <title>全选和取消全选</title>
 6 </head>
 7 <body>
 8   <h2>管理员列表</h2>
 9   <table border="1px" width="500px">
10     <thead>
11     <tr>
12       <th><input type="checkbox"/>全选</th>
13       <th>管理员ID</th>
14       <th>姓名</th>
15       <th>操作</th>
16     </tr>
17     </thead>
18     <tbody>
19       <tr>
20         <td><input type="checkbox"/></td>
21         <td>1</td>
22         <td>Tester</td>
23         <td>修改 删除</td>
24       </tr>
25       <tr>
26         <td><input type="checkbox"/></td>
27         <td>2</td>
28         <td>Manager</td>
29         <td>修改 删除</td>
30       </tr>
31       <tr>
32         <td><input type="checkbox"/></td>
33         <td>3</td>
34         <td>Analyst</td>
35         <td>修改 删除</td>
36       </tr>
37       <tr>
38         <td><input type="checkbox"/></td>
39         <td>4</td>
40         <td>Admin</td>
41         <td>修改 删除</td>
42       </tr>
43     </tbody>
44   </table>
45   <script>
46     /*1. 先实现点击全选,选中下方所有checkbox*/
47     //DOM 4步
48     //1. 查找触发事件的元素
49     //本例中: 用户点击thead中的input,触发全选
50     var chbAll=
51       document.querySelector("thead input");
52     //2. 绑定事件处理函数
53     chbAll.onclick=function(){
54       //不能用外部的chbAll
55       //this->当前点击的thead中的checkbox
56       //3. 查找要修改的元素
57       //本例中: 点thead中的input,需要同时修改tbody中所有input
58       var chbs=
59         document.querySelectorAll("tbody input");
60       //4. 修改元素
61       //本例中: 遍历找到的tbody中所有input,修改每个input的checked状态
62       for(var chb of chbs){
63         chb.checked=this.checked;
64       }
65     }
66       
67     /*2. 点tbody中的checkbox,也影响thead中的全选checkbox*/
68     //DOM 4步
69     //1. 查找触发事件的元素
70     //本例中: 查找tbody中所有input元素
71     var chbs=
72       document.querySelectorAll("tbody input");
73     //2. 绑定事件处理函数
74     //本例中: 多个chb都要绑定单击事件,所以遍历
75     for(var chb of chbs){
76       chb.onclick=function(){
77         //3. 查找要修改的元素
78         //本例中: 点tbody中的chb,有可能影响thead中的chb
79         var chbAll=
80           document.querySelector("thead input")
81         //4. 修改元素
82         //尝试查找tbody中一个未选中的input
83         var unchecked=document.querySelector(
84           "tbody input:not(:checked)"
85         );
86         //如果找到未选中的input
87         if(unchecked!=null){
88           //则顶上的chbAll就不选中
89           chbAll.checked=false;
90         }else{//否则如果没找到未选中的input
91           //则顶上的chbAll就选中
92           chbAll.checked=true;
93         }
94       }
95     }
96   </script>
97 </body>
98 </html>
View Code

(3). 自定义扩展属性

a. 什么是: HTML标准中没有规定的,程序员根据自身的需要自发添加的自定义属性。

b. 何时: 2种:

                   1). 自定义扩展属性,经常用来代替id选择器、类选择器、元素选择器作为触发事件的元素。

                   i. 其它选择器的问题:

                            id选择器: 一次只能选一个元素

                            类选择器: 类选择器本职工作是定义样式!因为样式经常修改,所以元素的class经常被修改。如果查找元素时,使用类选择器查找,则一旦class被修改,js中的交互行为也会被破坏!

                            元素选择器: 实现同一种效果,可用的元素种类有很多,也可能发生变化。如果用元素选择器查找触发事件的元素,则一旦元素改变,js中的交互行为,又会被破坏!

                   ii. 解决: 项目中,几乎所有的触发事件的元素,都要用自定义属性查找!

                   iii. 好处: 将来即使class名和标签名发生变化,也不会影响js的交互行为!

                   2). 在客户端网页中临时缓存个别业务数据:

                   i. 问题: 有些常用的数据,如果每次触发事件时,都要反复向服务器请求,则请求次数过多,速度慢,且增大服务器的压力

                   ii. 解决: 如果频繁使用的业务数据,可以在首次加载时,就提前请求到客户端,保存在HTML元素自己身上的自定义属性中

                   iii. 好处: 将来反复触发事件时,只要从当前元素自己身上获得自定义属性值即可!无需反复请求服务器端。极大的加快了响应速度,极大的减轻了服务器端的压力。

c. 如何:

                   1). 手工在HTML中添加自定义扩展属性:

                   <元素 data-任意自定义属性名="属性值"> xxx </元素>

                   2). 在js中获取或修改自定义扩展属性: 2种:

                   i. 旧核心DOM2个函数:

                            元素.getAttribute("data-自定义属性名")

                            元素.setAttribute("data-自定义属性名","新属性值")

                   ii. 新HTML5标准: 前提: 如果HTML中的自定义属性是以data-开头

                            元素.dataset.自定义属性名="属性值"

                            强调:

                            ①dataset专门操作html中以data-开头的自定义扩展属性。所以,项目中强烈建议所有自定义扩展属性,都要用data-开头!

                            ②虽然在HTML中自定义扩展属性以data-开头的,但是,js中dataset后的自定义属性名无需data-开头

 d. 示例: 使用自定义属性记录按钮单击次数:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4   <meta charset="UTF-8">
 5   <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6   <meta name="viewport" content="width=device-width, initial-scale=1.0">
 7   <title>Document</title>
 8 </head>
 9 <body>
10   <button data-btn data-n="0">click me</button>
11   <script>
12     //DOM 4步:
13     //1. 查找触发事件的元素
14     //本例中: 就是要点带有data-btn属性的按钮\
15   
16     var btn=document.querySelector("[data-btn]");
17     //2. 绑定事件处理函数
18     btn.onclick=function(){
19       //3. 查找要修改的元素
20       //本例中:就是要修改自己this
21       //4. 修改元素
22       //4.1 获取出当前按钮身上自定义属性data-n中保存的单击次数,转为整数
23       var n=parseInt(
24         //旧核心DOM
25         // this.getAttribute("data-n")
26         //新HTML5
27         this.dataset.n
28       );
29       //4.2 将单击次数+1
30       n++;
31       //4.3 将新的单击次数,再放回当前按钮身上的data-n属性中
32       //旧核心DOM
33       // this.setAttribute("data-n",n);
34       //新HTML5
35       this.dataset.n=n;
36     }
37   </script>
38 </body>
39 </html>
View Code

e. 示例: 标签页效果:

  1 <!DOCTYPE HTML>
  2 <html>
  3 <head>
  4 <title>读取并修改元素的属性</title>
  5 <meta charset="utf-8" />
  6 <style>
  7 *{
  8   margin:0;
  9   padding: 0;
 10 }
 11 #tab li{
 12   float: left; list-style: none;
 13 }
 14 #tab li a{
 15   display:inline-block;
 16   text-decoration:none;
 17   width: 80px; height: 40px;
 18   line-height: 40px;
 19   text-align: center;
 20   color:#000;
 21 }
 22 #container{
 23   position: relative;
 24 }
 25 #content1,#content2,#content3{
 26   width: 300px;
 27   height: 100px;
 28   padding:30px;
 29   position: absolute;
 30   top: 40px;
 31   left: 0;
 32 }
 33 #tab li:first-child,#content1{
 34   background-color: #ffcc00;
 35 }
 36 #tab li:first-child+li,#content2{
 37   background-color: #ff00cc;
 38 }
 39 #tab li:first-child+li+li,#content3{
 40   background-color: #00ccff;
 41 }
 42 </style>
 43 
 44 </head>
 45 <body>
 46   <h2>实现多标签页效果</h2>
 47   <div class="tabs">
 48     <ul id="tab">
 49       <li><a data-tab data-id="content1" href="#content1">10元套餐</a></li>
 50       <li><a data-tab data-id="content2" href="#content2">30元套餐</a></li>
 51       <li><a data-tab data-id="content3" href="#content3">50元包月</a></li>
 52     </ul>
 53     <div id="container">
 54       <div id="content1" style="z-index:10">
 55         10元套餐详情:<br />&nbsp;每月套餐内拨打100分钟,超出部分2毛/分钟
 56       </div>
 57       <div id="content2">
 58         30元套餐详情:<br />&nbsp;每月套餐内拨打300分钟,超出部分1.5毛/分钟
 59       </div>
 60       <div id="content3">
 61         50元包月详情:<br />&nbsp;每月无限量随心打
 62       </div>
 63     </div>
 64   </div>
 65   <script>
 66     //DOM 4步
 67     //1. 查找触发事件的元素
 68     //本例中: 
 69     //1.1 先手工的为每个a都添加data-tab自定义属性
 70     //1.2 再查找带有data-tab属性的元素
 71     var tabs=
 72       document.querySelectorAll("[data-tab]")
 73     //附加步骤: 先定义一个z=10,用来临时保存目前为止最大的zIndex值
 74     var z=10;
 75     //2. 绑定事件处理函数
 76     //本例中: 因为所有tab按钮都要绑定单击事件,所以遍历
 77     for(var tab of tabs){
 78       tab.onclick=function(){
 79         //3. 查找要修改的元素
 80         //本例中: 每单击一个tab,就要找到当前tab对应的div是谁?
 81         //3.1 先手工为每个a添加data-id属性,值为当前a对应的div的id名
 82         //3.2 再在程序中获得当前点击的按钮身上自定义属性data-id中保存的对应div的id名
 83         var id名=this.dataset.id;
 84               //this.getAttribute("data-id")
 85         //3.3 用获得的id名查找当前点击的a对应的div
 86         //                            不要加""
 87         //                            因为id名是变量
 88         var div=document.getElementById(id名);
 89         //4. 修改元素
 90         //4.1 先将z值+1
 91         z++;
 92         //4.2 再将新的最大的z值设置给找到的对应div的style的zIndex属性上
 93         //错误: 虽然css中确实是z-index,但是js中不允许随便用-,会和减法的-冲突!
 94         // div.style.z-index=z;
 95         //正确: 项目中凡是带-的css属性名,必须去横线变驼峰
 96         div.style.zIndex=z;
 97       }
 98     }
 99     //希望开局默认显示第一个标签页对应的div的内容,需要手工为第一个div添加style="z-index:10"
100   </script>
101 </body>
102 </html>
View Code

修改样式

(1). 修改内联样式:

a. 元素对象.style.css属性="属性值"

 b. 相当于手工: <元素 style="css属性:属性值">

 c. 强调:

                   1). 大小、距离、位置相关的属性,必须加单位(px, rem等)

                   2). 如果css属性名中带-,则必须改为去横线变驼峰,比如:

                   z-index 应改为 zIndex

                   font-size 应改为 fontSize

                   background-color 应改为 backgroundColor

(2). 获取完整样式:

         a. 问题: 元素.style只能表示内联样式,无法包含除内联样式之外的其它地方定义的样式。如果用元素.style方式获取元素的样式,一定会丢掉大部分其它地方定义的样式属性!

         b. 解决: 项目中如果想获得一个元素所有css属性的集合,应该获得计算后的样式!

                   1). 什么是计算后的样式: 最终能够应用到这个元素上的所有css属性的集合!

                   2). 如何: 2步:

                   i. 先获得包含计算后的所有css属性的集合对象:

                   var style=getComputedStyle(元素对象)

                           浏览器内置函数,无需定义,即可直接使用!

                   ii. 再从style集合对象中提取出想用的个别css属性值

                   style.css属性名

         c. 坑: 计算后的样式都是只读的,禁止修改的!因为计算后的样式来源不确定!一旦擅自修改,很可能牵一发而动全身!

         (3). 总结: 项目中:

         a. 如果想获取样式时,首选getComputedStyle()

         b. 如果想修改样式时,首选.style

         (4). 示例: 获取或修改h1元素的样式:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4   <meta charset="UTF-8">
 5   <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6   <meta name="viewport" content="width=device-width, initial-scale=1.0">
 7   <title>Document</title>
 8   <style>
 9     h1{
10       background-color:red;
11     }
12   </style>
13 </head>
14 <body>
15   <h1 id="h1" style="color:yellow">Welcome</h1>
16   <p>Welcome dingding</p>
17   <script>
18     var h1=document.getElementById("h1");
19     //想获得h1元素的完整样式: 
20     //                        不要加引号
21     //                        上一句话查找得到的
22     //                        引用h1元素对象的变量
23     var style=getComputedStyle(h1);
24     //想获得h1的字体颜色
25     //正确: 但是不好
26     // console.log(h1.style.color);
27     //正确: 
28     console.log(style.color);
29     //想获得h1的背景颜色
30     //错误: 
31     // console.log(h1.style.backgroundColor);
32     //正确: 
33     console.log(style.backgroundColor);
34     //想获得h1的字体大小
35     //错误: 
36     // console.log(h1.style.fontSize);
37     //正确:
38     console.log(style.fontSize);
39 
40     //想修改h1的字体大小为64px;
41     //错误: 
42     // style.fontSize="64px";//Failed to set the 'font-size' property on 'CSSStyleDeclaration': These styles are computed, and therefore the 'font-size' property is read-only
43     //正确: 
44     h1.style.fontSize="64px";
45   </script>
46 </body>
47 </html>
View Code

(4). 问题: 用.style.css属性方式修改元素的样式,一次只能修改一个css属性值。如果再一次交互行为中,需要同时修改一个元素的多个css属性,代码就会很繁琐!

 (5). 解决: 项目中只要批量修改一个元素的多个css属性,都应该用class属性代替style属性

 (6). 如何: 2步:

         a. 先在css中,为元素定义好不同情况下的样式类套装:

         b. 再在js中根据不同的情况,更换元素的className为不同的css样式类名。

  (7). 示例: 带样式的表单验证:

  1 <!doctype html>
  2 <html>
  3 
  4 <head>
  5   <meta charset="UTF-8">
  6   <title>实现带样式的表单验证</title>
  7   <style>
  8     table {
  9       width: 700px
 10     }
 11 
 12     td:first-child {
 13       width: 60px
 14     }
 15 
 16     td:nth-child(2) {
 17       width: 200px
 18     }
 19 
 20     td:first-child+td {
 21       width: 200px
 22     }
 23 
 24     td span {
 25       color: red
 26     }
 27 
 28     .vali_info {
 29       display: none;
 30     }
 31 
 32     .txt_focus {
 33       border-top: 2px solid black;
 34       border-left: 2px solid black;
 35     }
 36 
 37     .vali_success,
 38     .vali_fail {
 39       background-repeat: no-repeat;
 40       background-position: left center;
 41       display: block;
 42     }
 43 
 44     .vali_success {
 45       background-image: url("对应×的图片");
 46       padding-left: 20px;
 47       width: 0px;
 48       height: 20px;
 49       overflow: hidden;
 50     }
 51 
 52     .vali_fail {
 53       background-image: url("对应√的图片");
 54       border: 1px solid red;
 55       background-color: #ddd;
 56       color: Red;
 57       padding-left: 30px;
 58     }
 59   </style>
 60 </head>
 61 
 62 <body>
 63   <form id="form1">
 64     <h2>增加管理员</h2>
 65     <table>
 66       <tr>
 67         <td>姓名:</td>
 68         <td>
 69           <input name="username" />
 70           <span>*</span>
 71         </td>
 72         <td>
 73           <div class="vali_info">
 74             10个字符以内的字母、数字或下划线的组合
 75           </div>
 76         </td>
 77       </tr>
 78       <tr>
 79         <td>密码:</td>
 80         <td>
 81           <input type="password" name="pwd" />
 82           <span>*</span>
 83         </td>
 84         <td>
 85           <div class="vali_info">6位数字</div>
 86         </td>
 87       </tr>
 88       <tr>
 89         <td></td>
 90         <td colspan="2">
 91           <input type="submit" value="保存" />
 92           <input type="reset" value="重填" />
 93         </td>
 94       </tr>
 95     </table>
 96   </form>
 97   <script>
 98     //DOM 4步
 99     //1. 查找触发事件的元素
100     //本例中: 当姓名文本框失去焦点时触发验证
101     var txtName=      document.getElementsByName("username")[0];
102     //2. 绑定事件处理函数
103    
104     txtName.onblur=function(){
105       //3. 查找要修改的元素
106       //本例中: 当文本框失去焦点时,会修改旁边的div的样式: 当前文本框的爹的下一个兄弟的第一个孩子
107       var div=this //当前input文本框
108               .parentElement //当前文本框的爹td
109               .nextElementSibling //当前td的下一个兄弟td
110               .children[0];//下一个兄弟td的第一个孩子
111       //4. 修改元素
112       //4.1 先定义正则表达式描述姓名的规则
113            ////是js中正则表达式的标志
114       //^表示字符串开头位置
115       //$表示字符串结尾位置
116       //^和$连用表示必须从头到尾完整匹配!
117            //\w表示字母或数字或下划线,相当于[0-9A-Za-z_]
118       //{}在正则中表示数量
119       //{最少个数, 最多个数}
120       //比如:{1,10}表示至少1个字,最多10个字
121       var reg=/^\w{1,10}$/;
122       //4.2 再用正则表达式验证当前文本框中用户输入的内容
123           var result=reg.test(this.value);
124       //4.3 如果验证通过
125       if(result==true){
126         //才修改div的className为vali_success
127         div.className="vali_success";
128       }else{//4.4 否则如果验证未通过
129         //就修改div的className为vali_fail
130         div.className="vali_fail";
131       }
132     }
133   </script>
134 </body>
135 
136 </html>
View Code

五,添加删除替换元素: 

1. 添加一个新元素: 3步

         (1). 先创建一个新的空元素对象:

         a. var 新元素=document.createElement("标签名")

         b. 意为:               创建  元素

         c. 返回值: 返回一个新创建的元素对象

         d. 强调: .前的主语必须是document

         e. 比如: 想创建一个a元素:

                   var a=document.createElement("a");

                   结果: <a></a>

         (2). 为新的空元素添加必要的属性:

                   比如: 想让a当做超链接使用跳转到tmooc

                   a.innerHTML="go to tmooc"

                   a.href="http://tmooc.cn"

                   结果: <a href="http://tmooc.cn">go to tmooc</a>

         (3). 必须将新元素添加到DOM树上指定位置,才能在网页中显示出来,供人们使用!

         a. 在一个父元素下所有子元素末尾追加一个新元素:

                   父元素.appendChild(新元素)

                               追击  孩子

         b. 在一个父元素下的一个现有子元素之前插入一个新元素

                   父元素.insertBefore(新元素, 现有子元素)

                   插入到xxx之前

         c. 替换一个父元素下的一个现有子元素

                   父元素.replaceChild(新元素, 现有子元素)

示意图:

 

 

2. 示例: 添加一个a元素和一个文本框:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4   <meta charset="UTF-8">
 5   <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6   <meta name="viewport" content="width=device-width, initial-scale=1.0">
 7   <title>Document</title>
 8 </head>
 9 <body>
10   <script>
11     //想在页面中添加一个a元素
12     //1. 创建一个新的空的a元素对象
13     var a=document.createElement("a");
14     //2. 为a设置必要的关键属性
15     a.innerHTML="go to tmooc";
16     a.href="http://tmooc.cn";
17     console.log(a);
18     //3. 将a添加到body的末尾
19     document.body.appendChild(a);
20 
21     //想再创建一个普通文本框元素
22     var input=document.createElement("input");
23     //想把文本框放在a之前?
24     document.body.insertBefore(input,a);
25     //想把文本框放在a之后?
26     // a.body.appendChild(input);
27     //想用文本框代替a?
28     // document.body.replaceChild(input,a);
29   </script>
30 </body>
31 </html>
View Code

3. 示例: 动态生成表格: 

 1 <!DOCTYPE HTML>
 2 <html>
 3 <head>
 4 <title>动态创建表格</title>
 5 <meta charset="utf-8" />
 6 <style>
 7   table{width:600px; border-collapse:collapse;
 8     text-align:center;
 9   }
10   td,th{border:1px solid #ccc}
11 </style>
12 
13 </head>
14 <body>
15   <div id="data">
16     <table>
17       <thead>
18         <tr>
19           <th>姓名</th>
20           <th>薪资</th>
21           <th>年龄</th>
22         </tr>
23       </thead>
24     </table>
25   </div>
26   <script>
27   var json=[
28     {
29       "ename":"Tom", "salary":11000, "age":25
30     },
31     {
32       "ename":"John", "salary":13000, "age":28
33     },
34     {
35       "ename":"Mary", "salary":12000, "age":25
36     }
37   ];
38   //0. 手工在<div id="data">内部创建table和表头行内容
39   //1. 动态创建表格,显示数组中的内容
40   //1.1 先创建tbody, *暂时不要*追加到table中
41   //1.1.1 先创建一个新的空tbody
42   var tbody=document.createElement("tbody");
43   //1.1.2 再查找id为data的div下的table
44   var table=document.querySelector("#data>table");
45   //*暂时不要追加到table中*
46   //1.2 遍历json数组中每个员工对象
47   //因为json数组是索引数组,所以用
48   //      Employee
49   //      一个员工对象
50   for(var emp of json){
51     //每遍历一个员工对象,就创建一个tr,追加tbody
52     var tr=document.createElement("tr");
53     tbody.appendChild(tr);
54   //1.3 进一步遍历当前员工对象中每个属性
55     //因为是遍历对象中每个属性,所以
56     for(var key in emp){
57     //每遍历一个属性,就创建一个td,追加到tr中
58       var td=document.createElement("td");
59       tr.appendChild(td);
60     //设置当前td的内容为当前属性的属性值
61           td.innerHTML=emp[key];
62     }
63   }
64   //原1.1.3剪切到此;(为了页面不至于多次的重绘重排)
65   //4. 最后再一次性将tbody追加到table中
66   table.appendChild(tbody);
67   </script>
68 </body>
69 </html>
View Code

4. 优化:

(1). 问题: 每修改一个DOM结构,都会导致整个网页重排重绘,如果频繁修改DOM树结构,就会导致频繁重排重绘,极大的降低网页加载效率。

(2). 解决: 项目中,动态生成元素时,一定更要想尽办法,尽量减少操作DOM树的次数!就可以减少重排重绘的次数

         (3). 如何: 2种:

         a. 如果父元素和子元素都是动态生成的,则不要过早将父元素添加到DOM树。而是先在内存中,将所有子元素,添加到父元素上之后,最后再一次性将父元素添加到DOM树。——只需要更新一次DOM树,一次重排重绘即可!

         b. 如果父元素已经在DOM树上了,只是动态生成子元素而已。就必须借助于文档片段对象来减少重排重绘的次数。

                   1). 什么是文档片段对象: 是内存中临时保存多个平级子元素的虚拟父元素。

                   2). 如何: 3步:

                   i. 创建文档片段对象

                   var 文档片段对象=document.createDocumentFragment();

                                   创建  文档    片段

                   ii. 将多个平级子元素添加到文档片段对象中暂存

                   iii. 最后再一次性将整个文档片段对象添加到DOM树上指定父元素下

                   3). 强调: 文档片段对象将多个子元素添加到DOM树之后,就自动释放了!不会成为页面上真正的一级元素!

                   4). 示例: tbody已经在table中了,既要用文档片段动态添加子元素。

 1 <!DOCTYPE HTML>
 2 <html>
 3 
 4 <head>
 5   <title>动态创建表格</title>
 6   <meta charset="utf-8" />
 7   <style>
 8     table {
 9       width: 600px;
10       border-collapse: collapse;
11       text-align: center;
12     }
13 
14     td,
15     th {
16       border: 1px solid #ccc
17     }
18   </style>
19 
20 </head>
21 
22 <body>
23   <div id="data">
24     <table>
25       <thead>
26         <tr>
27           <th>姓名</th>
28           <th>薪资</th>
29           <th>年龄</th>
30         </tr>
31       </thead>
32       <tbody>
33       </tbody>
34     </table>
35   </div>
36   <script>
37     var json = [
38       {
39         "ename": "Tom", "salary": 11000, "age": 25
40       },
41       {
42         "ename": "John", "salary": 13000, "age": 28
43       },
44       {
45         "ename": "Mary", "salary": 12000, "age": 25
46       }
47     ];
48     //1. 动态创建表格,显示数组中的内容
49     //0. 手工在<div id="data">内部创建table和表头行内容
50     //假设tbody已经手工添加到页面上table中了
51     //1.1 先创建文档片段对象
52     var frag = document.createDocumentFragment();
53     //1.2 遍历json数组中每个员工对象
54     //因为json数组是索引数组,所以用
55     //      Employee
56     //      一个员工对象
57     for (var emp of json) {
58       //每遍历一个员工对象,就创建一个tr,追加文档片段对象
59       var tr = document.createElement("tr");
60       frag.appendChild(tr);
61       //1.3 进一步遍历当前员工对象中每个属性
62       //因为是遍历对象中每个属性,所以
63       for (var key in emp) {
64         //每遍历一个属性,就创建一个td,追加到tr中
65         var td = document.createElement("td");
66         tr.appendChild(td);
67         //设置当前td的内容为当前属性的属性值
68                td.innerHTML = emp[key];
69       }
70     }
71     //4. 最后再一次性将文档片段对象追加到table中tbody内
72     var tbody =
73       document.querySelector("#data>table>tbody");
74     tbody.appendChild(frag);
75   </script>
76 </body>
77 
78 </html>
View Code

5. 删除元素: 父元素.removeChild(子元素)

                    移除  孩子

6. 示例: 为表格添加删除行的功能:

 1 <!DOCTYPE HTML>
 2 <html>
 3 <head>
 4 <title>动态创建表格</title>
 5 <meta charset="utf-8" />
 6 <style>
 7   table{width:600px; border-collapse:collapse;
 8     text-align:center;
 9   }
10   td,th{border:1px solid #ccc}
11 </style>
12 
13 </head>
14 <body>
15   <div id="data">
16     <table>
17       <thead>
18         <tr>
19           <th>姓名</th>
20           <th>薪资</th>
21           <th>年龄</th>
22           <th>操作</th><!--手工为表头行多加一格-->
23         </tr>
24       </thead>
25     </table>
26   </div>
27   <script>
28   var json=[
29     {
30       "ename":"Tom", "salary":11000, "age":25
31     },
32     {
33       "ename":"John", "salary":13000, "age":28
34     },
35     {
36       "ename":"Mary", "salary":12000, "age":25
37     }
38   ];
39   //0. 手工在<div id="data">内部创建table和表头行内容
40   //1. 动态创建表格,显示数组中的内容
41   //1.1 先创建tbody, *暂时不要*追加到table中
42   //1.1.1 先创建一个新的空tbody
43   var tbody=document.createElement("tbody");
44   //1.1.2 再查找id为data的div下的table
45   var table=document.querySelector("#data>table");
46   //*暂时不要追加到table中*
47   //1.2 遍历json数组中每个员工对象
48   //因为json数组是索引数组,所以用
49   //      Employee
50   //      一个员工对象
51   for(var emp of json){//外层循环为了添加行tr
52     //每遍历一个员工对象,就创建一个tr,追加tbody
53     var tr=document.createElement("tr");
54     tbody.appendChild(tr);
55   //1.3 进一步遍历当前员工对象中每个属性
56     //因为是遍历对象中每个属性,所以
57     for(var key in emp){//内层循环为tr中添加td
58     //每遍历一个属性,就创建一个td,追加到tr中
59       var td=document.createElement("td");
60       tr.appendChild(td);
61     //设置当前td的内容为当前属性的属性值
62            td.innerHTML=emp[key];
63     }
64     /*实现点击按钮删除行*/
65     //先在添加完所有的数据格td之后,再在当前行内额外添加一个td
66     var td=document.createElement("td");
67     tr.appendChild(td);
68     //再创建一个button,将button放入td中
69     var btn=document.createElement("button");
70     btn.innerHTML="×";
71     td.appendChild(btn);
72     //为按钮绑定单击事件: 
73     btn.onclick=function(){
74       //点哪个按钮,让当前按钮变成花
75       // this.innerHTML="❀";
76       //找到当前按钮所在的行tr
77       var tr=this //当前按钮
78             .parentElement //当前td
79             .parentElement; //当前tr
80       //找到tbody: 其实就是tr的父元素
81       var tbody=tr.parentElement;
82       //获得当前行中的员工姓名?就是当前行中第一个子元素td的内容
83       var ename=tr.children[0].innerHTML;
84       //先跟用户确认是否继续删除
85       var result=
86         confirm(`是否继续删除 ${ename} 吗?`);
87       //如果用户确认要删除当前行了,才
88       if(result==true){
89         //真正用tbody删除当前tr
90         tbody.removeChild(tr);
91       }
92     }
93   }
94   //原1.1.3剪切到此:
95   //4. 最后再一次性将tbody追加到table中
96   table.appendChild(tbody);
97   </script>
98 </body>
99 </html>
View Code

扩充小知识:

浏览器中三大对话框:

1. 如果想请用户输入一个字符串: 用输入框:

   var str=prompt("提示信息");.

 

 

2. 如果想警告用户一件事: 用警告框

   alert("警告信息")

 

 

3. 如果想跟用户确认是否继续时: 用确认框

   var result=confirm("确认信息")

 

 含返回值 如果是确定的话放回true   取消的话返回false;

 

标签:dom,元素,介绍,查找,var,td,document,属性
来源: https://www.cnblogs.com/CIBud/p/14409783.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有