JavaScript 步伐不能够独立运行,只能在宿主情况中实行。一般情况下可以把 JavaScript 代码放在网页中,借助欣赏器情况来运行。
在 HTML 文档中嵌入 JavaScript 代码
在 HTML 页面中嵌入 JavaScript 脚本需要使用 < s c r i p t > <script> <script>标签,用户可以在 < s c r i p t > <script> <script> 标签中直接编写 JavaScript 代码,具体步骤如下。
第1步,新建 HTML 文档,保存为 test.html。
第2步,在 标签内插入一个
第3步,为 < s c r i p t > <script> <script> 标签设置 t y p e = " t e x t / j a v a s c r i p t " type="text/javascript" type="text/javascript"属性。
现代欣赏器默认 < s c r i p t > <script> <script> 标签的脚本范例为 JavaScript,因此可以省略 type 属性;假如思量到兼容早期版本欣赏器,则需要设置 type 属性。
第4步,在 < s c r i p t > <script> <script> 标签内输入 JavaScript 代码
d o c u m e n t . w r i t e ( " < h 1 > H e l l o W o r l d ! < / h 1 > " ) ; document.write("<h1>Hello World!</h1>"); document.write("<h1>HelloWorld!</h1>");
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>第一个JavaScript程序</title>
<script type="text/javascript">
document.write("<h1>Hello World!</h1>");
</script>
</head>
<body></body>
</html>
复制代码
在 JavaScript 脚本中,document 表示网页文档对象;document.write() 表示调用 Document 对象的 write() 方法,在当前网页源代码中写入 HTML 字符串 " < h 1 > H e l l o W o r l d ! < / h 1 > " "<h1>Hello World!</h1>" "<h1>HelloWorld!</h1>"。
第5步,保存网页文档,在欣赏器中预览,表现效果如图所示。
1. 在脚本文件中编写 JavaScript 代码
JavaScript 步伐不但可以直接放在 HTML 文档中,也可以放在 JavaScript 脚本文件中。JavaScript 脚本文件是文本文件,扩展名为.js,使用任何文本编辑器都可以编辑。
常用的文本编辑器有 Windows 体系中的记事本、Linux 体系中的 Vim、Sublime Text、Notepad++ 等。对于初学者来说,建议先使用文本编辑器来编写 JavaScript 代码,如许有助于我们对 JavaScript 语法、关键字、函数等内容的影象。比及了现实开辟阶段,则可以选择一些更加专业的代码编辑器,例如 Visual Studio Code(简称“VS Code”)、WebStorm(收费)、Atom 等,如许可以进步开辟服从。
新建 JavaScript 文件的步骤如下。
第1步,新建文本文件,保存为 test.js。注意,扩展名为.js,它表示该文本文件是 JavaScript 范例的文件。
第2步,打开 test.js 文件,在此中编写如下 JavaScript 代码。
alert(“Hello World!”);
在上面代码中,alert() 表示 Window 对象的方法,调用该方法将弹出一个提示对话框,表现参数字符串 “Hello World!”。
第3步,保存 JavaScript 文件。在此建议把 JavaScript 文件和网页文件放在同一个目次下。
JavaScript 文件不能够独立运行,需要导入到网页中,通过欣赏器来实行。使用 < s c r i p t > <script> <script> 标签可以导入 JavaScript 文件。
第4步,新建 HTML 文档,保存为 test.html。
第5步,在 标签内插入一个 < s c r i p t > <script> <script> 标签。定义 src 属性,设置属性值为指向外部 JavaScript 文件的 URL 字符串。代码如下:
注意:使用 < s c r i p t > <script> <script>标签包含外部 JavaScript 文件时,默认文件范例为 Javascript。因此,不管加载的文件扩展名是不是 .js,欣赏器都会按 JavaScript 脚本来解析。
第6步,保存网页文档,在欣赏器中预览,表现效果如图所示。
定义 src 属性的 < s c r i p t > <script> <script> 标签不应再包含 JavaScript 代码。假如嵌入了代码,则只会下载并实行外部 JavaScript 文件,嵌入代码将被忽略。
2. JavaScript 代码实行顺序
欣赏器在解析 HTML 文档时,将根据文档流从上到下逐行解析和表现。JavaScript 代码也是 HTML 文档的构成部门,因此 JavaScript 脚本的实行顺序也是根据 < s c r i p t > <script> <script> 标签的位置来确定的。 示例
使用欣赏器测试下面示例,会看到 JavaScript 代码从上到下徐徐被解析的过程。
<!DOCTYPE html>
<script>
alert("顶部脚本");
</script>
<html>
<head>
<meta charset="UTF-8">
<title>test</title>
<script>
alert("头部脚本");
</script>
</head>
<body>
<h1>网页标题</h1>
<script>
alert("页面脚本");
</script>
<p>正文内容</p>
</body>
<script>
alert("底部脚本");
</script>
</html>
复制代码
在欣赏器中欣赏上面示例网页,起首弹出提示文本“顶部脚本”,然后表现网页标题“test”,接着弹出提示文本“头部脚本”,下面才表现一级标题文本“网页标题”,继续弹出提示文本“页面脚本”, 接着表现段落文本“正文内容”,最后弹出提示文本“底部脚本”。
你看,对于导入的 JavaScript 文件,也将按照 < s c r i p t > <script> <script> 标签在文档中出现的顺序来实行,而且实行过程是文档解析的一部门,不会单独解析大概延期实行。
假如想改变 JavaScript 文件的实行顺序,可以给 < s c r i p t > <script> <script> 标签增加 defer 大概 async 属性,想了解的读者请转到:JS文件延迟和异步加载(defer和async属性)
JavaScript 中的几个紧张概念
x > y ? console.log("x 大于 y") : console.log("x 小于 y"); // 输出:x 小于 y
复制代码
条件运算符是唯一的三元运算符,其语法格式如下:
b ? x : y
复制代码
b 利用数必须是一个布尔型的表达式,x 和 y 是任意范例的值。
假如利用数 b 的返回值为 true,则实行 x 利用数,并返回该表达式的值。
假如利用数 b 的返回值为 false,则实行 y 利用数,并返回该表达式的值。
定义变量 a,然后检测 a 是否被赋值,假如赋值则使用该值;否则设置默认值。
var a = null; //定义变量a
typeof a != "undefined" ? a = a : a = 0; //检测变量a是否赋值,否则设置默认值
console.log(a); //显示变量a的值,返回null
复制代码
条件运算符可以转换为条件布局:
if(typeof a != "undefined"){ //赋值
a = a;
}else{ //没有赋值
a = 0;
}
console.log(a);
复制代码
也可以转换为逻辑表达式:
(typeof a != "undefined") && (a =a) || (a = 0); //逻辑表达式
console.log(a);
复制代码
在上面表达式中,假如 a 已赋值,则实行 (a = a) 表达式,实行完毕就不再实行逻辑或运算符后面的 (a = 0) 表达式;假如 a 未赋值,则不再实行逻辑与运算符后面的 (a = a) 表达式,转而实行逻辑或运算符后面的表达式 (a = 0)。 注意:
在实战中需要思量假值的干扰。使用 typeof a != “undefined” 举行检测,可以避开变量赋值为 false、null、“”、NaN等假值时,也被误认为没有赋值。
8. 位运算符
JS do while 循环与 while 循环非常相似,差别之处在于,do while 循环会先实行循环中的代码,然后再对条件表达式举行判定。因此,无论条件表达式是真还是假,do while 循环都能至少实行一次,而 while 循环就不可了,假如条件表达式为假会直接退出 while 循环。 JS do while 循环语法
JS do while 循环的语法格式如下:
do {
// 需要执行的代码
} while (条件表达式);
复制代码
提示:do while 循环与 while 循环还有一点差别,那就是 do while 循环的末尾需要使用分号; 举行末端,而 while 循环则不需要。
do while 循环的实行流程如下图所示:
示例代码如下:
var i = 1;
do{
document.write(i + " ");
i++;
}while (i > 5);
复制代码
运行结果:
1 JS do while 循环示例
使用 do while 循环计算 1~100 之间所有整数的和:
运行结果:
name = Clark
surname = Kent
age = 36
注意,JS for in 循环是为遍历对象而创建的,虽然也可以遍历数组,但是并不保举,若要遍历数组,可以使用 for 循环大概 for of 循环,有关 for of 循环我们会在下节举行先容。
2) for of循环语句的用法
JS for of 循环是 ECMAScript6 中新添加的一个循环方式,与 for in 循环类似,也是普通 for 循环的一种变体。使用 for of 循环可以轻松的遍历数组大概其它可遍历的对象,例如字符串、对象等。
JS for of 循环的语法格式如下:
var obj = {"name": "Clark", "surname": "Kent", "age": "36"};
// 使用 for of 循环遍历对象中的所有属性
for(var value in obj) {
document.write(value + ", ");
}
复制代码
运行结果:
a, b, c, d, e, f,
H, e, l, l, o, , W, o, r, l, d, !,
name, surname, age, 注意: 虽然 for of 循环也可以遍历对象,但并不保举,若要遍历对象可以使用 for in 循环。
JS break和continue语句:跳出循环
事件只有与 HTML 元素绑定之后才能被触发,为 HTML 元素绑定事件处理步伐的方法由很多,最简朴的就是通过 HTML 事件属性来直接绑定事件处理步伐,例如 onclick、onmouseover、onmouseout 等属性。
以 onclick 属性为例,通过该属性我们可以为指定的 HTML 元素定义鼠标点击事件(即在该元素上单击鼠标左键时触发的事件),示例代码如下:
此中 value 为要创建的 Number 对象的数值,若 value 为一个非数字的值,则会尝试将其转换为数字,若转换失败则会返回 NaN。
当 Number() 函数和 new 运算符一起使用时,会创建一个新的 Number 对象。假如不用 new 运算符,把 Number() 看成一个函数来调用,则会将此中的参数转换为一个数值,而且返回这个值(假如转换失败,则返回 NaN)。
示例代码如下:
var a = new Number("123");
var b = Number("456");
var c = 789;
var d = new Number("abc");
document.write(typeof a + "<br>"); // 输出:object
document.write(typeof b + "<br>"); // 输出:number
document.write(typeof c + "<br>"); // 输出:number
document.write(d + "<br>"); // 输出:NaN
复制代码
4. Number 属性
Number 对象中提供了一些属性,如下表所示:
属性形貌Number.MAX_VALUEJavaScript 中所能表示的最大值Number.MIN_VALUEJavaScript 中所能表示的最小值Number.NaN非数字Number.NEGATIVE_INFINITY负无穷,在溢出时返回Number.POSITIVE_INFINITY正无穷,在溢出时返回Number.EPSILON表示 1 与 Number 所能表示的大于 1 的最小浮点数之间的差Number.MIN_SAFE_INTEGER最小安全整数,即 -9007199254740991Number.MAX_SAFE_INTEGER最大安全整数,即 9007199254740991 5. Number 方法
除了属性外,Number 对象中还提供了一些方法,如下表所示:
方法形貌Number.parseFloat()将字符串转换成浮点数,和全局方法 parseFloat() 作用相同Number.parseInt()将字符串转换成整型数字,和全局方法 parseInt() 作用相同Number.isFinite()判定 Number 对象是否为有穷数Number.isInteger()判定 Number 对象是否为整数Number.isNaN()判定 Number 对象是否为 NaN 范例Number.isSafeInteger()判定 Number 对象是否为安全整数,即范围为 -(2⁵³ - 1)到 2⁵³ - 1 之间的整数Number.toString()把 Number 对象转换为字符串,使用指定的基数Number.toLocaleString()把 Number 对象转换为字符串,使用本地数字格式顺序Number.toFixed()把 Number 对象转换为字符串,结果的小数点后有指定位数的数字Number.toExponential()把 Number 对象的值转换为指数计数法Number.toPrecision()把 Number 对象格式化为指定的长度Number.valueOf()返回一个 Number 对象的基本数字值 JS String(字符串)对象
下表中枚举了 Date 属性中提供的方法及其形貌:
方法形貌getDate()从 Date 对象返回一个月中的某一天 (1 ~ 31)getDay()从 Date 对象返回一周中的某一天 (0 ~ 6)getMonth()从 Date 对象返回月份 (0 ~ 11)getFullYear()从 Date 对象返回四位数字的年份getYear()已废弃,请使用 getFullYear() 方法代替getHours()返回 Date 对象的小时 (0 ~ 23)getMinutes()返回 Date 对象的分钟 (0 ~ 59)getSeconds()返回 Date 对象的秒数 (0 ~ 59)getMilliseconds()返回 Date 对象的毫秒(0 ~ 999)getTime()返回 1970 年 1 月 1 日至今的毫秒数getTimezoneOffset()返回本地时间与格林威治标定时间 (GMT) 的分钟差getUTCDate()根据通用时间从 Date 对象返回月中的一天 (1 ~ 31)getUTCDay()根据通用时间从 Date 对象返回周中的一天 (0 ~ 6)getUTCMonth()根据通用时间从 Date 对象返回月份 (0 ~ 11)getUTCFullYear()根据通用时间从 Date 对象返回四位数的年份getUTCHours()根据通用时间返回 Date 对象的小时 (0 ~ 23)getUTCMinutes()根据通用时间返回 Date 对象的分钟 (0 ~ 59)getUTCSeconds()根据通用时间返回 Date 对象的秒钟 (0 ~ 59)getUTCMilliseconds()根据通用时间返回 Date 对象的毫秒(0 ~ 999)parse()返回1970年1月1日午夜到指定日期(字符串)的毫秒数setDate()设置 Date 对象中月的某一天 (1 ~ 31)setMonth()设置 Date 对象中月份 (0 ~ 11)setFullYear()设置 Date 对象中的年份(四位数字)setYear()已废弃,请使用 setFullYear() 方法代替setHours()设置 Date 对象中的小时 (0 ~ 23)setMinutes()设置 Date 对象中的分钟 (0 ~ 59)setSeconds()设置 Date 对象中的秒钟 (0 ~ 59)setMilliseconds()设置 Date 对象中的毫秒 (0 ~ 999)setTime()以毫秒设置 Date 对象setUTCDate()根据通用时间设置 Date 对象中月份的一天 (1 ~ 31)setUTCMonth()根据通用时间设置 Date 对象中的月份 (0 ~ 11)setUTCFullYear()根据通用时间设置 Date 对象中的年份(四位数字)setUTCHours()根据通用时间设置 Date 对象中的小时 (0 ~ 23)setUTCMinutes()根据通用时间设置 Date 对象中的分钟 (0 ~ 59)setUTCSeconds()根据通用时间设置 Date 对象中的秒钟 (0 ~ 59)setUTCMilliseconds()根据通用时间设置 Date 对象中的毫秒 (0 ~ 999)toSource()返回该对象的源代码toString()把 Date 对象转换为字符串toTimeString()把 Date 对象的时间部门转换为字符串toDateString()把 Date 对象的日期部门转换为字符串toGMTString()已废弃,请使用 toUTCString() 方法代替toUTCString()根据通用时间,把 Date 对象转换为字符串toLocaleString()根据本地时间格式,把 Date 对象转换为字符串toLocaleTimeString()根据本地时间格式,把 Date 对象的时间部门转换为字符串toLocaleDateString()根据本地时间格式,把 Date 对象的日期部门转换为字符串UTC()根据通用时间返回 1970 年 1 月 1 日 到指定日期的毫秒数valueOf()返回 Date 对象的原始值 示例代码如下:
Math 是 JavaScript 中的一个内置对象,此中提供了一些数学中常用的常量值和函数,用来实现一些数学中常见计算,例如计算平均数、求绝对值、四舍五入等。
与前面先容的几个对象(例如 Number 对象、String 对象、Array 对象等)差别,调用 Math 对象中的属性和方法无需预先使用 new 运算符来创建它,直接将 Math 作为对象调用即可,例如:
var pi_val = Math.PI; // 数学中 π 的值:3.141592653589793
下表中枚举了 Math 对象中提供的方法及其形貌信息:
方法形貌abs(x)返回 x 的绝对值acos(x)返回 x 的反余弦值acosh(x)返回 x 的反双曲余弦值asin(x)返回 x 的反正弦值asinh(x)返回 x 的反双曲正弦值atan(x)返回 x 的反正切值atanh(x)返回 x 的反双曲正切值atan2(y,x)返回 y/x 的反正切值cbrt(x)返回 x 的立方根ceil(x)对 x 举行向上取整,即返回大于 x 的最小整数clz32(x)返回将 x 转换成 32 无符号整形数字的二进制形式后,开头 0 的个数cos(x)返回 x 的余弦值cosh(x)返回 x 的双曲余弦值exp(x)返回算术常量 e 的 x 次方,即 Exexpm1(x)返回 exp(x) - 1 的值floor(x)对 x 举行向下取整,即返回小于 x 的最大整数fround(x)返回最接近 x 的单精度浮点数hypot([x, [y, […]]])返回所有参数平方和的平方根imul(x, y)将参数 x、y 分别转换位 32 位整数,并返回它们相乘后的结果log(x)返回 x 的天然对数log1p(x)返回 x 加 1 后的天然对数log10(x)返回 x 以 10 为底的对数log2(x)返回 x 以 2 为底的对数max([x, [y, […]]])返回多个参数中的最大值min([x, [y, […]]])返回多个参数中的最小值pow(x,y)返回 x 的 y 次幂random()返回一个 0 到 1 之间的随机数round(x)返回 x 四舍五入后的整数sign(x)返回 x 的符号,即一个数是正数、负数还是 0sin(x)返回 x 的正弦值sinh(x)返回 x 的双曲正弦值sqrt(x)返回 x 的平方根tan(x)返回 x 的正切值tanh(x)返回 x 的双曲正切值toSource()返回字符串"Math"trunc(x)返回 x 的整数部门valueOf()返回 Math 对象的原始值 示例代码如下:
正则表达式由字母、数字、标点以及一些特殊特殊字符构成,例如 /abc/、/(\d+).\d*/,可以在正则表达式中使用的特殊字符如下表所示:
特殊字符含义\转义字符,在非特殊字符之前使用反斜杠表示下一个字符是特殊字符,不能按照字面理解,例如 \b 表示一个字符边界;在特殊字符之前使用反斜杠则表示下一个字符不是特殊字符,应该按照字面理解。例如反斜杠本身,若要在正则表达式中定义一个反斜杠,则需要在反斜杠前再添加一个反斜杠 \。^匹配字符串的开头,假如设置了修饰符 m,则也可以匹配换行符后紧跟的位置。 例如“/^A/”并不会匹配“an A”中的“A”,但是会匹配“An E”中的“A”。$匹配字符串的末尾,假如设置了修饰符 m,则也可以匹配换行符之前的位置。 例如“/t$/”并不会匹配“eater”中的“t”,但是会匹配“eat”中的“t”。*匹配前一个表达式 0 次或多次,等价于 {0,}。例如“/bo*/”能够匹配“A ghost boooooed”中的“booooo”和“A bird warbled”中的“b”,但是在“A goat grunted”中不会匹配任何内容。+匹配前面一个表达式 1 次大概多次,等价于 {1,}。例如“/a+/”能够匹配“candy”中的“a”和“caaaaaaandy”中所有的“a”,但是在“cndy”中不会匹配任何内容。?匹配前面一个表达式 0 次大概 1 次,等价于 {0,1}。例如“/e?le?/”能够匹配“angel”中的“el”,“angle”中的“le”以及“oslo”中的“l”。.匹配除换行符之外的任何单个字符。例如“/.n/”将会匹配“nay, an apple is on the tree”中的“an”和“on”。(x)匹配“x”并记住这一匹配项,这里的括号被称为捕获括号。(?:x)匹配“x”但是不记住匹配项,这里的括号被称为非捕获括号。x(?=y)当“x”后面跟着“y”时,匹配此中的“x”。例如“/Jack(?=Sprat)/”会匹配后面跟着“Sprat”的“Jack”,“/Jack(?=Sprat(?<=y)x当“x”前面是“y”时,匹配此中的“x”。例如“/(?<=Jack)Sprat/”会匹配前面未“Sprat”的“Jack”,“/(?<=Jackx(?!y)当“x”后面不是“y”时,匹配此中的“x”。 例如“/\d+(?!.)/”会匹配“3.141”中的“141”,而不是“3.141”。(?<!y)x当“x”前面不是“y”时,匹配此中的“x”。xly匹配“x”大概“y”。 例如“/greenlred/”能够匹配“green apple”中的“green”和“red apple”中的“red”。{n}n 是一个正整数,表示匹配前一个字符 n 次。例如“/a{2}/”不会匹配“candy”中的“a”,但是能够匹配“caandy”中所有的“a”,以及“caaandy”中的前两个“a”。{n,}n 是一个正整数,表示匹配前一个字符至少 n 次。例如“/a{2,}/”能够匹配“aa”、“aaaa”或“aaaaa”,但不会匹配“a”。{n,m}n 和 m 都是整数,表示匹配前一个字符至少 n 次,最多 m 次,假如 n 或 m 即是 0,则表示忽略这个值。例如“/a{1, 3}/”能够匹配“candy”中的“a”,“caandy”中的前两个“a”,“caaaaaaandy”中的前三个“a”。[xyz]转义序列,匹配 x、y 或 z,您也可以使用破折号-来指定一个字符范围。例如“[abcd]”和“[a-d]”是一样的,它们都能匹配“brisket”中的“b”,“city”中的“c”。[^xyz]反向字符集,匹配除 x、y、z 以外的任何字符,您通用也可以使用破折号 - 来指定一个字符范围。例如“[abc]”和“[a-c]”是一样的,它们都能匹配“brisket”中的“r”,“chop”中的“h”。[\b]匹配一个退格符,注意:不要和 \b 混淆。\b匹配一个单词的边界,即单词的开始或末尾。例如“/\bm/”能够匹配“moon”中的“m”,但不会匹配“imoon”中的“m”。\B匹配一个非单词边界。例如“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。\cX当 X 是 A 到 Z 之间的字符时,匹配字符串中的一个控制符。例如“/\cM/”能够匹配字符串中的“control-M(U+000D)”。\d匹配一个数字,等价于“[0-9]”。例如“/\d/”大概“/[0-9]/”能够匹配“B2 is the suite number.”中的“2”。\D匹配一个非数字字符,等价于“[^0-9]”。 例如“/\D/”大概“/[^0-9]/”能够匹配“B2 is the suite number.”中的“B”。\f匹配一个换页符 (U+000C)。\n匹配一个换行符 (U+000A)。\r匹配一个回车符 (U+000D)。\s匹配一个空缺字符,包罗空格、制表符、换页符和换行符,等价于“[ \f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]”。例如“/\s\w*/”能够匹配“foo bar.”中的“bar”。\S匹配一个非空缺字符,等价于“[^\f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]”。例如“/\S\w*/”能够匹配“foo bar.”中的“foo”。\t匹配一个水平制表符 (U+0009)。\v匹配一个垂直制表符 (U+000B)。\w匹配一个单字字符(字母、数字大概下划线),等价于“[A-Za-z0-9_]”。例如“/\w/”能够匹配“apple,”中的“a”,“$5.28,”中的“5”和“3D.”中的“3”。\W匹配一个非单字字符,等价于“[A-Za-z0-9_]”。例如“/\W/”大概“/[A-Za-z0-9_]/”能够匹配“50%.”中的“%”。\n获取最后的第 n 个匹配的值。比如“/apple(,)\sorange\1/”能够匹配“apple, orange, cherry, peach.”中的“apple, orange,”。\0匹配 NULL(U+0000)字符,不要在这后面跟其它小数,由于 \0 是一个八进制转义序列。\xhh匹配一个两位十六进制数(\x00-\xFF)表示的字符。\uhhhh匹配一个四位十六进制数表示的 UTF-16 代码单位。\u{hhhh}或\u{hhhhh}(仅在设置了修饰符 u 时)匹配一个十六进制数表示的 Unicode 字符。 提示:在正则表达式中 .、*、?、+、[、]、(、)、{、}、^、$、|、\ 等字符被赋予了特殊的含义,若要在正则表达式中使用这些字符的原本意思时,需要在这些字符前添加反斜线举行转义,例如若要匹配 .,则必须编写为 \.。
2. 使用正则表达式
文档对象模子(Document Object Model,简称 DOM),是一种与平台和语言无关的模子,用来表示 HTML 或 XML 文档。文档对象模子中定义了文档的逻辑布局,以及步伐访问和利用文档的方式。
当网页加载时,欣赏器就会自动创建当前页面的文档对象模子(DOM)。在 DOM 中,文档的所有部门(例如元素、属性、文本等)都会被组织成一个逻辑树布局(类似于族谱),树中每一个分支的终点称为一个节点,每个节点都是一个对象,如下图所示:
借助 DOM 您可以使用 JavaScript 来访问、修改、删除或添加 HTML 文档中的任何内容。
1. Document 对象
当欣赏器加载一个 HTML 文档时,会创建一个 Document 对象,Document 对象是 DOM 树中所有节点的根节点。通过 Document 对象我们可以访问 HTML 文档中的所有元素。
提示:Document 对象是 Window 对象的一部门,以是您可以通过 window.document 来访问 Document 对象。
2. Document 对象中的属性
下表中枚举了 Document 对象中提供的属性及其形貌:
属性形貌document.activeElement返回当前获取焦点的元素document.anchors返回对文档中所有 Anchor 对象的引用document.applets返回对文档中所有 Applet 对象的引用。注意: HTML5 已不支持 元素document.baseURI返回文档的基础 URIdocument.body返回文档的 body 元素document.cookie设置或返回与当前文档有关的所有 cookiedocument.doctype返回与文档相关的文档范例声明 (DTD)document.documentElement返回文档的根节点document.documentMode返回欣赏器渲染文档的模式document.documentURI设置或返回文档的位置document.domain返回当前文档的域名document.domConfig已废弃,返回 normalizeDocument() 被调用时所使用的配置document.embeds返回文档中所有嵌入内容(embed)的聚集document.forms返回文档中所有 Form 对象的引用document.images返回文档中所有 Image 对象的引用document.implementation返回处理该文档的 DOMImplementation 对象document.inputEncoding返回文档的编码方式document.lastModified返回文档的最后修改日期document.links返回对文档中所有 Area 和 Link 对象的引用document.readyState返回文档状态(载入中)document.referrer返回载入当前文档的 URLdocument.scripts返回页面中所有脚本的聚集document.strictErrorChecking设置或返回是否欺压举行错误检查document.title返回当前文档的标题document.URL返回文档的完整 URL 3. Document 对象中的方法
通过《文档对象模子》一节的学习我们知道,当网页加载时,欣赏器就会自动创建当前页面的文档对象模子(DOM),并将文档的所有部门(例如元素、属性、文本等)组织成一个逻辑树布局(类似于族谱),逻辑树的每一个分支的终点称为一个节点,每个节点都包含一个对象,这个对象就是我们本节要先容的 Element 对象。
使用 Document 对象中提供的方法(例如 getElementsByTagName()、getElementById()、getElementsByClassName() 等)可以得到 Element 对象,在 Element 对象中同样也提供了一系列方法和属性,来利用文档中的元素大概元素中的属性。
1. Element 对象中的属性
下表中枚举了 JavaScript Element 对象中提供的属性及其形貌:
属性形貌element.accessKey设置或返回一个访问单选按钮的快捷键element.attributes返回一个元素的属性数组element.childNodes返回元素的一个子节点的数组element.children返回元素中子元素的聚集element.classList返回元素中类名构成的对象element.className设置或返回元素的 class 属性element.clientHeight返回内容的可视高度(不包罗边框,边距或滚动条)element.clientWidth返回内容的可视宽度(不包罗边框,边距或滚动条)element.contentEditable设置或返回元素的内容是否可编辑element.dir设置或返回一个元素中的文本方向element.firstChild返回元素中的第一个子元素element.id设置大概返回元素的 idelement.innerHTML设置大概返回元素的内容element.isContentEditable返回元素内容是否可编辑,假如可编辑则返回 true,否则返回 falseelement.lang设置大概返回一个元素的语言element.lastChild返回元素的最后一个子元素element.namespaceURI返回定名空间的 URIelement.nextSibling返回指定元素之后的兄弟元素,两个元素在 DOM 树中位于同一层级(包罗文本节点、注释节点)element.nextElementSibling返回指定元素之后的兄弟元素,两个元素在 DOM 树中位于同一层级(不包罗文本节点、注释节点)element.nodeName返回元素名称(大写)element.nodeType返回元素的节点范例element.nodeValue返回元素的节点值element.offsetHeight返回元素的高度,包罗边框和内边距,但不包罗外边距element.offsetWidth返回元素的宽度,包罗边框和内边距,但不包罗外边距element.offsetLeft返回元素在水平方向的偏移量element.offsetParent返回距离该元素近来的举行过定位的父元素element.offsetTop返回元素在垂直方向的偏移量element.ownerDocument返回元素的根元素(文档对象)element.parentNode返回元素的父节点element.previousSibling返回元素之前的兄弟元素,两个元素在 DOM 树中位于同一层级(包罗文本节点、注释节点)element.previousElementSibling返回元素之前的兄弟元素,两个元素在 DOM 树中位于同一层级(不包罗文本节点、注释节点)element.scrollHeight返回元素的完整高度(包罗被滚动条隐蔽的部门)element.scrollLeft设置或返回元素滚动条距离元素左侧的距离element.scrollTop设置或返回元素滚动条距离元素上方的距离element.scrollWidth返回元素的完整宽度(包罗被滚动条隐蔽的部门)element.style设置或返回元素的样式属性element.tabIndex设置或返回元素的标签顺序element.tagName以字符的形式返回元素的名称(大写)element.textContent设置或返回某个元素以及此中的文本内容element.title设置或返回元素的 title 属性element.length返回对象的长度 2. Element 对象中的方法
元素属性是指在 HTML 元素的开始标签中用来控制标签行为或提供标签信息的特殊词语。
在 HTML DOM 中,通过 attributes 对象来表示 HTML 属性,在 attributes 对象中提供了多种添加、修改和删除 HTML 属性的方法,如下表所示:
属性 / 方法形貌attributes.isId假如属性是 ID 范例,则返回 true,否则返回 falseattributes.name返回属性名称attributes.value设置大概返回属性的值attributes.specified假如定义了指定属性,则返回 true,否则返回 falsenodemap.getNamedItem()从节点列表中返回的指定属性节点nodemap.item()返回节点列表中处于指定索引号的节点nodemap.length返回节点列表的节点数量nodemap.removeNamedItem()删除指定属性节点nodemap.setNamedItem()设置指定属性节点(通过名称) 示例代码如下:
JavaScript history 对象中包含了用户在欣赏器中访问过的历史记录,此中包罗通过欣赏器欣赏过的页面,以及当前页面中通过加载的页面。我们可以通过 window 对象中的 history 属性来获取 history 对象,由于 window 对象是一个全局对象,因此在使用window.history 时可以省略 window 前缀,例如 window.history.go() 可以简写为 history.go()。
1. history 对象中的属性
str = 'welcome https://www.csdn.net/'; // 调用 sayHello() 函数在此处报错:Uncaught ReferenceError: str is not defined at sayHello (index.html:14) at index.html:17
} function sayHello() { alert("事件处理步伐 2"); } // 为 id 为 link 的标签订义多个点击事件 var link = document.getElementById("link"); link.addEventListener("click", sayHi); link.addEventListener("click", sayHello); </script></body></html>
使用 JS 事件冒泡动态为元素绑定事件的方法称为事件委托(Event Delegation,也称为“事件署理”),是 JavaScript 中最热门的技术之一。
事件委托就是把原本需要绑定在子元素上的事件(onclick、onkeydown 等)委托给它的父元素,让父元向来监听子元素的冒泡事件,并在子元素发生事件冒泡时找到这个子元素。
举个简朴的例子,整个宿舍的同学都需要去取快递,一种方法是让他们一个个去取,另一种方法是把这件事委托给宿舍长,让宿舍长把所有人的快递都取回来,然后再根据收件人一一分发给宿舍的同学。在这里,我们可以将取快递看作一个事件;每个同学看作是需要绑定事件的 DOM 元素;宿舍长看作是这些 DOM 元素的父元素,事件需要绑定在这个父元素上;按照收件人分发快递的过程就是事件实行的过程。
1. 为什么要使用事件委托
在 JavaScript 中,页面内事件处理步伐的个数会直接影响页面的整体性能,由于每个事件处理步伐都是对象,对象会占用内存,内存中的对象越多,页面的性能则越差。此外,事件处理步伐需要与 DOM 节点举行交互,访问 DOM 的次数越多,引起欣赏器重绘和重排的次数也就越多,从而影响页面的性能。
重绘是指当元素样式改变时,欣赏器会根据元素的新样式重新绘制元素的外观。重排是指当 DOM 树的一部门发生变化时(例如元素尺寸改变),欣赏器会重新创建 DOM 树。
当页面中很多表格或列表需要添加事件时,假如逐个添加那就太麻烦了,但是使用事件委托就能极大的减轻我们的工作量,同时也能进步页面的性能。
2. 事件委托实现原理
事件委托是使用事件的冒泡原理来实现的,大致可以分为三个步骤:
确定要添加事件元素的父级元素;
给父元素定义事件,监听子元素的冒泡事件;
使用 event.target 来定位触发事件冒泡的子元素。
注意:使用事件委托时,并不是说把事件委托给随意一个父元素就行。由于事件冒泡的过程也需要消耗时间,距离越远,所需的时间也就越长,所有最幸亏直接父元素上使用事件委托。
假如我们要为 ul 列表下的每个 li 标签添加点击事件,假如不使用事件委托,最简朴的办法就是使用循环来为每个 li 标签绑定事件,示例代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JavaScript</title>
</head>
<body>
<ul id="list">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<script>
window.onload = function(){
var the_ul = document.getElementById('list');
var the_li = the_ul.getElementsByTagName('li');
for( var i=0; i < the_li.length; i++ ){
the_li[i].onclick = function(){
console.log(this.innerHTML)
}
}
}
</script>
</body>
</html>
复制代码
通过上面的代码可以看出,要为每个 li 标签绑定点击事件,起首需要找到 ul 标签,然后通过 ul 标签找到所有 li 标签, 最后在通过遍历所有 li 标签来绑定事件。若使用事件委托的话,就会简朴很多,示例代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JavaScript</title>
</head>
<body>
<ul id="list">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<script>
window.onload = function(){
var the_ul = document.getElementById('list');
the_ul.onclick = function(e){
console.log(e.target.innerHTML)
}
}
</script>
</body>
</html>
复制代码
通过代码可以看出,使用事件委托我们只需要为 ul 标签绑定事件,当 li 标签被点击时,由于事件冒泡的特性,会触发 ul 标签上的事件,我们只需要在事件中通过 event 对象中的 target 属性来找到被点击的 li 标签即可。不过如许做也有一个弊端,那就是当我们点击 ul 标签时,也会触发事件。
别的,假如我们需要动态的向 ul 标签中添加 li 标签,同时也需要在新添加的 li 标签中添加点击事件,就必须通过事件委托来实现了,示例代码如下:
document.getElementById('addli').onclick = function (){
var newli = document.createElement("li");
newli.innerHTML = ++sum;
the_ul.appendChild(newli);
};
document.getElementById('delli').onclick = function (){
the_ul.firstElementChild.remove();
};
}
</script>
</body>
</html>
复制代码
3. 事件委托的长处
1) 减小内存消耗
使用事件委托可以大量节省内存,减少事件的定义,通过上面的示例可以看出,要为 ul 标签下的所有 li 标签添加点击事件,假如分别为每个 li 标签绑定事件,不但写起来比较繁琐,而且对内存的消耗也非常大。而使用事件委托的方式将点击事件绑定到 ul 标签上,就可以实现监听所有 li 标签,简洁、高效。
2) 动态绑定事件
在网页中,偶尔我们需要动态增加或移除页面中的元素,比如上面示例中动态的在 ul 标签中添加 li 标签,假如不使用事件委托,则需要手动为新增的元素绑定事件,同时为删除的元素解绑事件。而使用事件委托就没有这么麻烦了,无论是增加还是减少 ul 标签中的 li 标签,即不需要再为新增的元素绑定事件,也不需要为删除的元素解绑事件。
以是使用事件委托动态绑定事件可以减少很多重复工作的。
4. 总结