前端JavaScript(2) --常用内置对象,函数,伪数组 arguments,关于DOM的事件操作,DOM介绍
昨日内容回顾
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
1.三种引入方式 1.行内js < div onclick = 'add(3,4)'></ div > //声明一个函数 function add(a,b){ } 2.内接js < script >/*js代码*/</ script > 3.外接样式 < script src = 'main.js'></ script > //在前端项目中 当你看到index、main开头,这个时候应该考虑是项目的入口文件 //标签中img标签 link标签 script a标签 里面的属性 href src 都会往服务器发送请求 get请求 函数的声明 def add(): print('111') add() 对象: 万事万物皆对象 window对象:属性和方法(浏览器提供了一些自己的属性和方法) //在script脚本中声明的变量、函数(方法)都会被挂载window,这个window是一个全局对象 //全局对象和局部作用 2. 数据类型 string number NaN Infinity boolean 所有的类型都可以是boolean类型 undefine null //将数值类型转换成字符串类型 String() //将字符串类型转换为数值类型 Number() typeof 验证类型 |
在js中,所有事件都是带on的
alert是浏览器原生的方法
windos.alter('11') 也能执行。
但是在js里面,可以省略window
但是有一个例外,window.onload必须要写全。
在js声明对的变量,都被window挂起
1
2
|
var d1 = 11; console.log(window.d1); |
查看console,就会看到11
直接查看window
1
|
console.log(window); |
查看console,这里面有很多属性,其中就有alert,还有声明的变量。
函数调用,可以在任意位置
在script脚本中声明的变量、函数(方法)都会被挂载window,这个window是一个全局对象
它可以在任意位置调用
调用方法,一定要加括号,否则不执行,比如:
1
|
< div onclick="add(3,4)"></ div > |
一、常用内置对象
所谓内置对象就是ECMAScript提供出来的一些对象,我们知道对象都是有相应的属性和方法
数组Array
1.数组的创建方式
- 字面量方式创建(推荐大家使用这种方式,简单粗暴)
1
2
|
var colors = ['red','color','yellow']; console.log(colors); |
查看结果:
使用for循环遍历数组
1
2
3
4
|
var colors = ['red','color','yellow']; for (var i = 0;i < colors.length;i++){ console.log(colors[i]); } |
查看结果:
- 使用构造函数(后面会讲)的方式创建 使用new关键词对构造函数进行创建对象
1
2
|
var colors2 = new Array(); console.log(colors2) |
查看结果:
构造函数,必须要有关键字 new
函数名首字母大写
括号里面,也可以加变量
1
2
|
var colors2 = new Array(1,2,3); console.log(colors2) |
查看结果:
2.数组的赋值
1
2
3
4
5
6
|
var arr = []; //通过下标进行一一赋值 arr[0] = 123; arr[1] = '哈哈哈'; arr[2] = '嘿嘿嘿' console.log(arr) |
查看结果:
3.数组的常用方法
3.1 数组的合并 concat()
1
2
3
4
5
|
var north = ['北京','山东','天津']; var south = ['东莞','深圳','上海']; var newCity = north.concat(south); console.log(newCity) |
查看结果:
3.2 join() 将数组中的元素使用指定的字符串连接起来,它会形成一个新的字符串
1
2
3
|
var score = [98,78,76,100,0]; var str = score.join('|'); console.log(str);//98|78|76|100|0 |
查看结果:
3.3 将数组转换成字符串 toString()
1
2
3
4
5
|
var score = [98,78,76,100,0]; //toString() 直接转换为字符串 每个元素之间使用逗号隔开 var str = score.toString(); console.log(str);//98,78,76,100,0 |
查看结果:
3.4 slice(start,end); 返回数组的一段,前开后闭
1
2
3
|
var arr = ['张三','李四','王文','赵六']; var newArr = arr.slice(1,3); console.log(newArr);//["李四", "王文"] |
查看结果:
3.5 pop 移除数组的最后一个元素
1
2
3
|
var arr = ['张三','李四','王文','赵六']; var newArr = arr.pop(); console.log(newArr);//["张三", "李四","王文"] |
查看结果:
3.6 push() 向数组最后添加一个元素
1
2
3
|
var arr = ['张三','李四','王文','赵六']; var newArr = arr.push('小马哥'); console.log(newArr);//["张三", "李四","王文","赵六","小马哥"] |
查看结果:
3.7 reverse() 翻转数组
1
2
3
4
5
|
var names = ['alex','xiaoma','tanhuang','angle']; //4.反转数组 names.reverse(); console.log(names); |
查看结果:
3.8 sort对数组排序
1
2
3
|
var names = ['alex','xiaoma','tanhuang','abngel']; names.sort(); console.log(names);// ["alex", "angle", "tanhuang", "xiaoma"] |
查看结果:
3.9 判断是否为数组:isArray()
isArray是最新html5的方法
1
|
布尔类型值 = Array.isArray(被检测的值) ; |
举例:
1
2
|
var colors = ['red','color','yellow']; console.log(Array.isArray(colors)); |
查看结果:
数组没有去重的内置函数,需要自己写代码,来实现去重功能。
不能根据索引值插入!
4.字符串String
字符串方法
4.1 chartAt() 返回指定索引的位置的字符
1
2
3
|
var str = 'alex'; var charset = str.charAt(1); console.log(charset); |
查看结果:
4.2 concat 返回字符串值,表示两个或多个字符串的拼接
1
2
3
|
var str1 = 'al'; var str2 = 'ex'; console.log(str1.concat(str2,str2));//alexex |
查看结果:
4.3 replace(a,b) 将字符串a替换成字符串b
1
2
3
|
var a = '1234567755'; var newStr = a.replace("4567","****"); console.log(newStr);//123****755 |
查看结果:
4.4 indexof() 查找字符的下标,如果找到返回字符串的下标,找不到则返回-1 。跟seach()方法用法一样
1
2
3
|
var str = 'alex'; console.log(str.indexOf('e'));//2 console.log(str.indexOf('p'));//-1 |
查看结果:
4.5 slice(start,end) 左闭右开 分割字符串
1
2
|
var str = '小马哥'; console.log(str.slice(1,2));//马 |
查看结果:
4.6 split('a',1) 以字符串a分割字符串,并返回新的数组。如果第二个参数没写,表示返回整个数组,如果定义了个数,则返回数组的最大长度
1
2
|
var str = '我的天呢,a是嘛,你在说什么呢?a哈哈哈'; console.log(str.split('a')); |
查看结果:
4.7 subStr(statr,end) 左闭右开
1
2
|
var str = '我的天呢,a是嘛,你在说什么呢?a哈哈哈'; console.log(str.substr(0,4));//我的天呢 |
查看结果:
4.8 toLowerCase()转小写
1
2
|
var str = 'XIAOMAGE'; console.log(str.toLowerCase());//xiaomage |
查看结果:
4.9 toUpperCase()转大写
1
2
|
var str = 'xiaomage'; console.log(str.toUpperCase()); |
查看结果:
特别:
将number类型转换成字符串类型
1
2
3
4
|
//1.将number类型转换成字符串类型 var num = 132.32522; var numStr = num.toString(); console.log(typeof numStr); |
查看结果:
四舍五入
1
2
3
4
|
var num = 132.32522; //四舍五入,2表示保留2位 var newNum = num.toFixed(2); console.log(newNum); |
查看结果:
5.Date日期对象
创建日期对象只有构造函数一种方式,使用new关键字
1
2
|
//创建了一个date对象 var myDate = new Date(); |
1
2
3
4
5
6
|
//创建日期对象 var myDate=new Date(); //获取一个月中的某一天 console.log(myDate.getDate()); //返回本地时间 console.log(myDate.toLocaleString());//2018/5/27 下午10:36:23 |
查看结果:
获取标准时间
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<script type="text/javascript"> function getNowFormatDate() { var date = new Date(); var seperator1 = "-";//设置成自己想要的日期格式 年-月-日 var seperator2 = ":";//设置成自己想要的时间格式 时:分:秒 var month = date.getMonth() + 1;//月 var strDate = date.getDate();//日 if (month >= 1 && month <= 9) { month = "0" + month; } if (strDate >= 0 && strDate <= 9) { strDate = "0" + strDate; } var currentdate = date.getFullYear() + seperator1 + month + seperator1 + strDate + " " + date.getHours() + seperator2 + date.getMinutes() + seperator2 + date.getSeconds(); return currentdate; } console.log(getNowFormatDate()); </script>
查看结果:
6.Math 内置对象
常用内置对象
6.1 Math.ceil() 向上取整,'天花板函数'
1
2
3
4
|
var x = 1.234; //天花板函数 表示大于等于 x,并且与它最接近的整数是2 var a = Math.ceil(x); console.log(a);//2 |
查看结果:
6.2 Math.floor 向下取整,'地板函数'
1
2
3
4
|
var x = 1.234; // 小于等于 x,并且与它最接近的整数 1 var b = Math.floor(x); console.log(b);//1 |
查看结果:
6.3 求两个数的最大值和最小值
1
2
3
|
//求 两个数的最大值 最小值 console.log(Math.max(2,5));//5 console.log(Math.min(2,5));//2 |
查看结果:
6.4 随机数 Math.random()
返回0~1之间的小数,1是永远取不到的,0是有可能取到的。
这个是很常用的,上面的不常用
1
2
|
var ran = Math.random(); console.log(ran); |
查看结果:
如果让你取100-200之间的随机数,怎么做?
背过公式:min - max之间的随机数: min+Math.random()*(max-min)
1
2
3
|
// min - max之间的随机数: min+Math.random()*(max-min) num = (100+Math.random()*(300-100)); console.log(num); |
查看结果:
推荐一个网站,关于js的教程很正规,链接如下:
https://developer.mozilla.org/zh-CN/
二、函数
函数:就是将一些语句进行封装,然后通过调用的形式,执行这些语句。
函数的作用:
-
将大量重复的语句写在函数里,以后需要这些语句的时候,可以直接调用函数,避免重复劳动。
-
简化编程,让编程模块化。
1
2
3
4
5
6
7
|
console.log("hello world"); sayHello(); //调用函数 //定义函数: function sayHello(){ console.log("hello"); console.log("hello world"); } |
僵尸代码:所有代码,看起起来一样,重复代码太多。
为了避免僵尸代码,需要用到函数。
第一步:函数的定义
函数定义的语法:
1
2
3
|
function 函数名字(){ } |
解释如下:
-
function:是一个关键字。中文是“函数”、“功能”。
-
函数名字:命名规定和变量的命名规定一样。只能是字母、数字、下划线、美元符号,不能以数字开头。
-
参数:后面有一对小括号,里面是放参数用的。
-
大括号里面,是这个函数的语句。
代码结束,必须要加分号,一般网站的js代码为了节省流量,js代码会压缩一下,它是通过分号来压缩的。
第二步:函数的调用
函数调用的语法:
1
|
函数名字(); |
函数的参数:形参和实参
函数的参数包括形参和实参
注意:实际参数和形式参数的个数,要相同。
例子:
1
2
3
4
5
6
7
8
|
sum(3,4); sum("3",4); sum("Hello","World"); //函数:求和 function sum(a, b) { console.log(a + b); } |
查看结果:
第三步:函数的返回值
例子:
1
2
3
4
5
6
|
console.log(sum(3, 4)); //函数:求和 function sum(a, b) { return a + b; } |
查看结果:
三、伪数组
arguments代表的是实参。有个讲究的地方是:arguments只在函数中使用。
(1)返回函数实参的个数:arguments.length
例子:
1
2
3
4
5
6
7
8
9
10
11
|
fn(2,4); fn(2,4,6); fn(2,4,6,8); function fn(a,b,c) { console.log(arguments); console.log(fn.length); //获取形参的个数 console.log(arguments.length); //获取实参的个数 console.log("----------------"); } |
结果:
调用fn函数,就算不传参数,也不会报错。它接收参数是一一对应的。
2)之所以说arguments是伪数组,是因为:arguments可以修改元素,但不能改变数组的长短。举例:
1
2
3
4
5
6
7
8
|
fn(2,4); fn(2,4,6); fn(2,4,6,8); function fn(a,b) { arguments[0] = 99; //将实参的第一个数改为99 arguments.push(8); //此方法不通过,因为无法增加元素 } |
查看结果,是因为push报错了!
清空数组的几种方式:
1
2
3
4
5
|
var array = [1,2,3,4,5,6]; array.splice(0); //方式1:删除数组中所有项目 array.length = 0; //方式1:length属性可以赋值,在其它语言中length是只读 array = []; //方式3:推荐 |
在js中,也可以对length修改。
arguents 用的很少
四、关于DOM的事件操作
一、JavaScript的组成
JavaScript基础分为三个部分:
-
ECMAScript:JavaScript的语法标准。包括变量、表达式、运算符、函数、if语句、for语句等。
-
DOM:文档对象模型,操作网页上的元素的API。比如让盒子移动、变色、轮播图等。
-
BOM:浏览器对象模型,操作浏览器部分功能的API。比如让浏览器自动滚动。
现在写的代码,基本上是基于ECMAScript 第5个版本,简称es5
二、事件
1
|
JS是以事件驱动为核心的一门语言。 |
事件的三要素
事件的三要素:事件源、事件、事件驱动程序。
比如,我用手去按开关,灯亮了。这件事情里,事件源是:手。事件是:按开关。事件驱动程序是:灯的开和关。
再比如,网页上弹出一个广告,我点击右上角的X
,广告就关闭了。这件事情里,事件源是:X
。事件是:onclick。事件驱动程序是:广告关闭了。
于是我们可以总结出:谁引发的后续事件,谁就是事件源。
总结如下:
-
事件源:引发后续事件的html标签。
-
事件:js已经定义好了(见下图)。
-
事件驱动程序:对样式和html的操作。也就是DOM。
代码书写步骤如下:(重要)
-
(1)获取事件源:document.getElementById(“box”); //类似与ios语言的 UIButton *adBtn = [UIButton buttonWithType:UIButtonTypeCustom];
-
(2)绑定事件: 事件源box.事件onclick = function(){ 事件驱动程序 };
-
(3)书写事件驱动程序:关于DOM的操作
代码举例:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
常见事件如下:
onkeyup,表示按一个键,然后松开。就会触发此事件,它可以检测,你必须要按enter键的时候才触发。需要用到键盘编码
对应的键值的Unicode 编码
onmouseover跟a:hover类似,也是悬停效果
onsumit用于表单提交事件,比如检测一个表单中,是否每一项输入,都符合规范。检测通过后,才发送数据给后端,否则提示弹窗,信息没有填写完整,请重新输入!
这些事件中,在ie 6,7,8可能有兼容性问题。在后面学习jquery时,它自动帮你做了兼容。在任何浏览器,都可以使用。这不是绝对的!只是说大部分。
下面针对这事件的三要素,进行分别介绍。
1、获取事件源的方式(DOM节点的获取)
获取事件源的常见方式如下:
这3种方式,使用非常频繁,重点掌握!
1
2
3
|
var div1 = document.getElementById("box1"); //方式一:通过id获取单个标签 var arr1 = document.getElementsByTagName("div"); //方式二:通过 标签名 获得 标签数组 var arr2 = document.getElementsByClassName("hehe"); //方式三:通过 类名 获得 标签数组 |
方式一:通过id获取单个标签
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="box" class="box"> <p>内容</p> <p>内容</p> <p>内容</p> </div> <script type="text/javascript"> window.onload = function () { // 通过id获取单个标签 var oDiv = document.getElementById('box'); console.log(oDiv); } </script> </body> </html>
查看网页:
方式二:通过 标签名 获得 标签数组
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="box" class="box"> <p>内容</p> <p>内容</p> <p>内容</p> </div> <script type="text/javascript"> window.onload = function () { // 通过 标签名 获得 标签数组 var oP = document.getElementsByTagName('p'); console.log(oP); } </script> </body> </html>
查看结果:
2、绑定事件的方式
方式一:直接绑定匿名函数
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<div id="box1" ></div> <script type="text/javascript"> var div1 = document.getElementById("box1"); //绑定事件的第一种方式 div1.onclick = function () { alert("我是弹出的内容"); } </script>
方式二:先单独定义函数,再绑定
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style type="text/css"> .warp { width: 100px; height: 100px; background-color: red; } </style> </head> <body> <div id="box" class="warp"> </div> <script type="text/javascript"> window.onload = function () { var oDiv = document.getElementById('box'); //绑定事件的第二种方式 oDiv.onclick = eject; //注意,这里是eject,不是eject()。eject()指的是返回值。 // 弹框方法 function eject() { alert('hello'); return 1; } } </script> </body> </html>
查看网页,点击红色区域,就会弹框
注意上方代码的注释。绑定的时候,是写eject,不是写eject()。eject代表的是整个函数,而eject()代表的是返回值。
方式三:行内绑定
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style type="text/css"> .warp { width: 100px; height: 100px; background-color: red; } </style> </head> <body> <div id="box" class="warp" onclick="fn()"> </div> <script type="text/javascript"> function fn() { alert("我是弹出的内容"); } </script> </body> </html>
查看网页,点击红色区域,就会弹框
注意第一行代码,绑定时,是写的"fn()"
,不是写的"fn"
。因为绑定的这段代码不是写在js代码里的,而是被识别成了字符串。
3、事件驱动程序
我们在上面是拿alert举例,不仅如此,我们还可以操作标签的属性和样式。举例如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style type="text/css"> #box { width: 100px; height: 100px; background-color: pink; cursor: pointer; } </style> </head> <body> <div id="box"></div> <script type="text/javascript"> window.onload = function () { var oDiv = document.getElementById("box"); //点击鼠标时,原本粉色的div变大了,背景变红了 oDiv.onclick = function () { oDiv.style.width = "200px"; //属性值要写引号 oDiv.style.height = "200px"; oDiv.style.backgroundColor = "red"; //属性名是backgroundColor,不是background-Color } //鼠标移出div区域时,还原属性 oDiv.onmouseout = function () { oDiv.style.width = "100px"; oDiv.style.height = "100px"; oDiv.style.backgroundColor = "pink"; } } </script> </body> </html>
查看网页,点击红色区域,效果如下:
第二个例子:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> .box{ width: 100px; height: 100px; background-color: red; } </style> </head> <body> <button type="button" id="big">变大</button> <button type="button" id='small'>变小</button> <button type="button" id="circle">变圆</button> <button type="button" id="changeColor">变色</button> <div class="box" id="hezi"></div> <script type="text/javascript"> window.onload = function() { //这样写很low,太繁琐了 // var oBig = document.getElementById('big'); // var oBig = document.getElementById('big'); // var oBig = document.getElementById('big'); // var oBig = document.getElementById('big'); //定义函数,通过id获取对象 function $(id){ return document.getElementById(id); } //变大 $('big').onclick = function(){ $('hezi').style.width = '150px'; $('hezi').style.height = '150px'; } //变小 $('small').onclick = function(){ $('hezi').style.width = '50px'; $('hezi').style.height = '50px'; } //变圆 $('circle').onclick = function(){ $('hezi').style.borderRadius = '50%'; } //变色 $('changeColor').onclick = function(){ $('hezi').style.backgroundColor = 'green'; } } </script> </body> </html>
网页效果如下:
上方代码的注意事项:
- 在js里写属性值时,要用引号
- 在js里写属性名时,是
backgroundColor
,不是CSS里面的background-Color
。记得所有的像css属性的text-*,line-*、backgroun-*等在js中都写成驼峰
onload事件
当页面加载(文本和图片)完毕的时候,触发onload事件。
举例:
1
2
3
4
5
|
< script type="text/javascript"> window.onload = function () { console.log("小马哥"); //等页面加载完毕时,打印字符串 } </ script > |
有一点我们要知道:js的加载是和html同步加载的。因此,如果使用元素在定义元素之前,容易报错。这个时候,onload事件就能派上用场了,我们可以把使用元素的代码放在onload里,就能保证这段代码是最后执行。
建议是:整个页面上所有元素加载完毕在执行js内容。所以,window.onload可以预防使用标签在定义标签之前。
事件案例
1、京东顶部广告栏关闭
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> *{ padding: 0; margin: 0; } .top-banner{ /*position: relative;*/ background-color: rgb(0, 148, 124); } .top-banner .w{ width: 1190px; position: relative; margin: 0 auto; } .top-banner .banner{ display: block; width: 100%; height: 80px; background: url('images/close.jpg') no-repeat center 0; } .top-banner .close{ position: absolute; right: 0; top:0; text-decoration: none; color: white; width: 20px; height: 20px; line-height: 20px; text-align: center; } .hide{ display: none; } </style> </head> <body> <div class="top-banner" id="topBanner"> <div class="w"> <a href="#" class="banner"></a> <a href="#" class="close" id="closeBanner">x</a> </div> </div> <script type="text/javascript"> // /需求:点击案例,隐藏盒子。 //思路:点击a链接,让top-banner这个盒子隐藏起来(加隐藏类名)。 window.onload = function(){ // /1.获取事件源和相关元素 var closeBanner = document.getElementById('closeBanner'); var topBanner = document.getElementById('topBanner'); //2.绑定事件 closeBanner.onclick = function(){ //3.书写事件驱动程序 //类控制 //topBanner.className += ' hide';//保留原类名,添加新类名 //topBanner.className = 'hide'; //替换旧类名 topBanner.style.display = 'none'; } } </script> </body> </html>
网页效果:
2.要求实现效果:当鼠标悬停在img上时,更换为另外一张图片;鼠标离开时,还原为本来的图片。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <script> //window.onload页面加载完毕以后再执行此代码 window.onload = function () { //需求:鼠标放到img上,更换为另一张图片,也就是修改路径(src的值)。 //步骤: //1.获取事件源 //2.绑定事件 //3.书写事件驱动程序 //1.获取事件源 var img = document.getElementById("box"); //2.绑定事件(悬停事件:鼠标进入到事件源中立即出发事件) img.onmouseover = function () { //3.书写事件驱动程序(修改src) img.src = "images/jd2.png"; // this.src = "images/jd2.png"; } //1.获取事件源 var img = document.getElementById("box"); //2.绑定事件(悬停事件:鼠标进入到事件源中立即出发事件) img.onmouseout = function () { //3.书写事件驱动程序(修改src) img.src = "images/jd1.png"; } } </script> </head> <body> <img id="box" src="images/jd1.png" style="cursor: pointer;"/> </body> </html>
切了2张京东搜索框的图片,一个是灰色,一个是红色。
网页效果:
五、DOM介绍
什么是DOM
DOM:文档对象模型。DOM 为文档提供了结构化表示,并定义了如何通过脚本来访问文档结构。目的其实就是为了能让js操作html元素而制定的一个规范。
DOM就是由节点组成的。
解析过程
HTML加载完毕,渲染引擎会在内存中把HTML文档,生成一个DOM树,getElementById是获取内中DOM上的元素节点。然后操作的时候修改的是该元素的属性。
DOM树(一切都是节点)
DOM的数据结构如下:
上图可知,在HTML当中,一切都是节点:(非常重要)
-
元素节点:HMTL标签。
-
文本节点:标签中的文字(比如标签之间的空格、换行)
-
属性节点::标签的属性。
整个html文档就是一个文档节点。所有的节点都是Object。元素就是标签
DOM可以做什么
-
找对象(元素节点)
-
设置元素的属性值
-
设置元素的样式
-
动态创建和删除元素
-
事件的触发响应:事件源、事件、事件的驱动程序
CURD操作,也就是Create Retrieve Update Delete。分别表示创建,读取,更新,删除
DOM节点的获取
DOM节点的获取方式其实就是获取事件源的方式
操作元素节点,必须首先找到该节点。有三种方式可以获取DOM节点:
1
2
3
4
5
|
var div1 = document.getElementById("box1"); //方式一:通过id获取单个标签 var arr1 = document.getElementsByTagName("div"); //方式二:通过 标签名 获得 标签数组 var arr2 = document.getElementsByClassName("hehe"); //方式三:通过 类名 获得 标签数组 |
既然方式二、方式三获取的是标签数组,那么习惯性是先遍历之后再使用。
特殊情况:数组中的值只有1个。即便如此,这一个值也是包在数组里的。这个值的获取方式如下:
1
2
3
|
document.getElementsByTagName("div1")[0]; //取数组中的第一个元素 document.getElementsByClassName("hehe")[0]; //取数组中的第一个元素 |
DOM访问关系的获取
DOM的节点并不是孤立的,因此可以通过DOM节点之间的相对关系对它们进行访问。如下:
节点的访问关系,是以属性的方式存在的。
JS中的父子兄访问关系:
这里我们要重点知道parentNode和children这两个属性的用法。下面分别介绍。
获取父节点
调用者就是节点。一个节点只有一个父节点,调用方式就是
1
|
节点.parentNode |
(1)nextSibling:
指的是下一个节点(包括标签、空文档和换行节点)
-
火狐、谷歌、IE9+版本:都指的是下一个节点(包括标签、空文档和换行节点)。
-
IE678版本:指下一个元素节点(标签)。
(2)nextElementSibling:
- 火狐、谷歌、IE9+版本:都指的是下一个元素节点(标签)。
总结:为了获取下一个元素节点,我们可以这样做:在IE678中用nextSibling,在火狐谷歌IE9+以后用nextElementSibling,于是,综合这两个属性,可以这样写:
1
|
下一个兄弟节点 = 节点.nextElementSibling || 节点.nextSibling |
previous的中文是: 前一个
(1)previousSibling:
-
火狐、谷歌、IE9+版本:都指的是前一个节点(包括标签、空文档和换行节点)。
-
IE678版本:指前一个元素节点(标签)。
(2)previousElementSibling:
- 火狐、谷歌、IE9+版本:都指的是前一个元素节点(标签)。
总结:为了获取前一个元素节点,我们可以这样做:在IE678中用previousSibling,在火狐谷歌IE9+以后用previousElementSibling,于是,综合这两个属性,可以这样写:
1
|
前一个兄弟节点 = 节点.previousElementSibling || 节点.previousSibling |
3、补充:获得任意一个兄弟节点:
1
|
节点自己.parentNode.children[index]; //随意得到兄弟节点 |
获取单个的子节点
1、第一个子节点 | 第一个子元素节点:
(1)firstChild:
-
火狐、谷歌、IE9+版本:都指的是第一个子节点(包括标签、空文档和换行节点)。
-
IE678版本:指第一个子元素节点(标签)。
(2)firstElementChild:
- 火狐、谷歌、IE9+版本:都指的是第一个子元素节点(标签)。
总结:为了获取第一个子元素节点,我们可以这样做:在IE678中用firstChild,在火狐谷歌IE9+以后用firstElementChild,于是,综合这两个属性,可以这样写:
1
|
第一个子元素节点 = 节点.firstElementChild || 节点.firstChild |
2、最后一个子节点 | 最后一个子元素节点:
(1)lastChild:
-
火狐、谷歌、IE9+版本:都指的是最后一个子节点(包括标签、空文档和换行节点)。
-
IE678版本:指最后一个子元素节点(标签)。
(2)lastElementChild:
- 火狐、谷歌、IE9+版本:都指的是最后一个子元素节点(标签)。
总结:为了获取最后一个子元素节点,我们可以这样做:在IE678中用lastChild,在火狐谷歌IE9+以后用lastElementChild,于是,综合这两个属性,可以这样写:
1
|
最后一个子元素节点 = 节点.lastElementChild || 节点.lastChild |
获取所有的子节点
(1)childNodes:标准属性。返回的是指定元素的子节点的集合(包括元素节点、所有属性、文本节点)。是W3C的亲儿子。
- 火狐 谷歌等高本版会把换行也看做是子节点。(了解)
用法:
1
|
子节点数组 = 父节点.childNodes; //获取所有节点。 |
(2)children:非标准属性。返回的是指定元素的子元素节点的集合。【重要】
- 它只返回HTML节点,甚至不返回文本节点。
- 在IE6/7/8中包含注释节点(在IE678中,注释节点不要写在里面)。
虽然不是标准的DOM属性,但它和innerHTML方法一样,得到了几乎所有浏览器的支持。
用法:(用的最多)
1
|
子节点数组 = 父节点.children; //获取所有节点。用的最多。 |
nodeType
这里讲一下nodeType。
-
nodeType == 1 表示的是元素节点(标签) 。记住:元素就是标签。
-
nodeType == 2 表示是属性节点 了解
-
nodeType == 3 是文本节点 了解
注意:上面列举的内容只做了解,下面的内容才是重点
DOM节点操作(重要)
上一段的内容:节点的访问关系都是属性。
节点的操作都是函数(方法)
创建节点
格式如下:
1
|
新的标签(元素节点) = document.createElement("标签名"); |
比如,如果我们想创建一个li标签,或者是创建一个不存在的adbc标签,可以这样做:
1
2
3
4
5
6
7
8
9
10
|
< script type="text/javascript"> var a1 = document.createElement("li"); //创建一个li标签 var a2 = document.createElement("adbc"); //创建一个不存在的标签 console.log(a1); console.log(a2); console.log(typeof a1); console.log(typeof a2); </ script > |
结果:
插入节点
插入节点有两种方式,它们的含义是不同的。
方式1:
1
|
父节点.appendChild(新的子节点); |
解释:父节点的最后插入一个新的子节点。
举例:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> </style> </head> <body> <div id="father"></div> <script type="text/javascript"> window.onload = function(){ var father = document.getElementById('father'); //1.创建节点 var oP = document.createElement('p'); //创建一个p标签 console.log(typeof oP); //2.插入节点 father.appendChild(oP); } </script> </body> </html>
查看网页,会发现多了一个P标签
方式2:
1
|
父节点.insertBefore(新的子节点,作为参考的子节点); |
解释:
- 在参考节点前插入一个新的节点。
- 如果参考节点为null,那么他将在父节点最后插入一个子节点
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> </style> </head> <body> <div id="father"> <div id="child"></div> </div> <script type="text/javascript"> window.onload = function(){ var father = document.getElementById('father'); var child = document.getElementById('child'); //1.创建节点 var oP = document.createElement('p'); //创建一个p标签 //2.插入节点 father.insertBefore(oP,child); //child表示参考节点 } </script> </body> </html>
查看网页,会发现child上面多了P标签
删除节点
格式如下:
1父节点.removeChild(子节点);
解释:用父节点删除子节点。必须要指定是删除哪个子节点。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> </style> </head> <body> <div id="father"> <div id="child"></div> </div> <script type="text/javascript"> window.onload = function(){ var father = document.getElementById('father'); var child = document.getElementById('child'); // //删除节点child father.removeChild(child); } </script> </body> </html>
查看网页,发现child已经被删除了
如果我想删除自己这个节点,可以这么做:
1node1.parentNode.removeChild(node1);
删除自己
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> </style> </head> <body> <div id="father"> <div id="child"></div> </div> <script type="text/javascript"> window.onload = function(){ var child = document.getElementById('child'); //删除自己 child.parentNode.removeChild(child); } </script> </body> </html>
查看网页,发现child自己已经被删除了
复制节点(克隆节点)
格式如下:
123要复制的节点.cloneNode(); //括号里不带参数和带参数false,效果是一样的。
要复制的节点.cloneNode(true);
括号里带不带参数,效果是不同的。解释如下:
-
不带参数/带参数false:只复制节点本身,不复制子节点。
-
带参数true:既复制节点本身,也复制其所有的子节点。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> </style> </head> <body> <div id="father"> <div id="child"></div> </div> <script type="text/javascript"> window.onload = function(){ var father = document.getElementById('father'); var oP = document.createElement('p'); //创建一个p标签 var oP2 = oP.cloneNode(); //复制节点 console.log(oP2); //插入节点 father.appendChild(oP); //插入新建的p标签 father.appendChild(oP2); //插入复制的p标签 } </script> </body> </html>
查看网页,会发现多个2个P标签
设置节点的属性
我们可以获取节点的属性值、设置节点的属性值、删除节点的属性。
我们就统一拿下面这个标签来举例:
1<
img
src="images/11.jpg" class="image-box" title="美女图片" alt="美女" id="a1">
下面分别介绍。
1、获取节点的属性值
方式1:
12元素节点.属性;
元素节点[属性];
举例:(获取节点的属性值)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> </style> </head> <body> <img src="images/11.jpg" class="image-box" title="美女图片" alt="美女" id="a1"> <script type="text/javascript"> var myNode = document.getElementsByTagName("img")[0]; console.log(myNode.src); console.log(myNode.className); //注意,是className,不是class console.log(myNode.title); console.log("------------"); console.log(myNode["src"]); console.log(myNode["className"]); //注意,是className,不是class console.log(myNode["title"]); </script> </body> </html>
网页查看console
方式2:(推荐)
1素节点.getAttribute("属性名称");
例子:
123console.log(myNode.getAttribute("src"));
console.log(myNode.getAttribute("class")); //注意是class,不是className
console.log(myNode.getAttribute("title"));
完整代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> </style> </head> <body> <img src="images/11.jpg" class="image-box" title="美女图片" alt="美女" id="a1"> <script type="text/javascript"> var myNode = document.getElementsByTagName("img")[0]; console.log(myNode.getAttribute("src")); console.log(myNode.getAttribute("class")); //注意是class,不是className console.log(myNode.getAttribute("title")); </script> </body> </html>
网页查看console
方式1和方式2的区别在于:前者是直接操作标签,后者是把标签作为DOM节点。推荐方式2。
2、设置节点的属性值
方式1举例:(设置节点的属性值)
12myNode.src = "images/2.jpg" //修改src的属性值
myNode.className = "image2-box"; //修改class的name
完整代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> </style> </head> <body> <img src="images/11.jpg" class="image-box" title="美女图片" alt="美女" id="a1"> <script type="text/javascript"> var myNode = document.getElementsByTagName("img")[0]; myNode.src = "images/22.jpg" //修改src的属性值 myNode.className = "image2-box"; //修改class的name </script> </body> </html>
网页访问,就会发现图片换了
方式2:(推荐)
1元素节点.setAttribute(属性名, 新的属性值);
举例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> </style> </head> <body> <img src="images/11.jpg" class="image-box" title="美女图片" alt="美女" id="a1"> <script type="text/javascript"> var myNode = document.getElementsByTagName("img")[0]; myNode.setAttribute('src','images/33.jpg'); //修改src的属性值 </script> </body> </html>
网页查看:
方式2举例:(设置节点的属性值)
123myNode.setAttribute("src","images/3.jpg");
myNode.setAttribute("class","image3-box");
myNode.setAttribute("id","你好");
完整代码:
View Code
网页查看,效果同上!
3、删除节点的属性
格式:
1元素节点.removeAttribute(属性名);
举例:(删除节点的属性)
12myNode.removeAttribute("class");
myNode.removeAttribute("id");
完整代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> </style> </head> <body> <img src="images/11.jpg" class="image-box" title="美女图片" alt="美女" id="a1"> <script type="text/javascript"> var myNode = document.getElementsByTagName("img")[0]; myNode.removeAttribute("class"); //删除class属性 myNode.removeAttribute("id"); //删除id属性 </script> </body> </html>
网页访问
查看网页代码,发现class和id属性不见了
补充:
innerHTML、innerText 、value
举例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> .t{ color: red; } </style> </head> <body> <div id="father"> <div id="child"> </div> </div> <input type="text" name="" value="" id="username"> <script type="text/javascript"> var father = document.getElementById('father'); var child = document.getElementById('child'); var username = document.getElementById('username'); // 1.创建节点 var oP = document.createElement('p'); var oSpan = document.createElement('span'); // console.log(typeof oP); // 设置文本 oP.innerText = '<span>哈哈哈</span>'; // 设置类名 oSpan.className = 't'; // 设置内容 oSpan.innerHTML = '<span>嘿嘿嘿</span>' // 2.插入节点 father.insertBefore(oP,child); //指定的已有子节点之前插入新的子节点 username.value = '123'; //修改value值 console.log(father.innerText); //查看innerText属性 console.log(father.innerHTML); //查看innerHTML属性 </script> </body> </html>
网页查看
表单控件,只有value才能修改值
查看console
就可以看出innerText和innerHTML直接的区别
总结:
innerHTML与innerText的用法与区别:
1、innerHTML:
也就是从对象的起始位置到终止位置的全部内容,包括Html标签。2、innerText:
从起始位置到终止位置的内容, 但它去除Html标签 -