JavaScript
1. 简介
JavaScript是一种具有面向对象能力的、解释型的程序设计语言。更具体一点,它是基于对象和事件驱动并具有相对安全性的客户端脚本语言。它的主要目的是,验证发往服务器端的数据、增加Web互动、加强用户体验度等。
JavaScript构成:ECMAScript、BOM、DOM
ECMAScript定义的只是这门语言的基础,与Web浏览器没有依赖关系,而在基础语法上可以构建更完善的脚本语言。JavaScript的运行需要一定的环境,脱离了环境JavaScript代码是不能运行的,JavaScript只能够寄生在某个具体的环境中才能够工作。JavaScript运行环境一般都由宿主环境和执行期环境共同构成,其中宿主环境是由外壳程序生成的,如Web浏览器就是一个外壳程序,它提供了一个可控制浏览器窗口的宿主环境。执行期环境则由嵌入到外壳程序中的JavaScript引擎(或称为JavaScript解释器)生成,在这个环境中JavaScript能够生成内置静态对象,初始化执行环境等。
Web浏览器自定义的DOM组件,以面向对象方式描述的文档模型。DOM定义了表示和修改文档所需的对象、这些对象的行为和属性以及这些对象之间的关系。DOM对象,是我们用传统的方法(javascript)获得的对象。DOM属于浏览器,而不是JavaScript语言规范里的规定的核心内容。
前面的DOM是为了操作浏览器中的文档,而为了控制浏览器的行为和操作,浏览器还提供了BOM(浏览器对象模型)。
ECMAScript(基础语法):描述了该语言的语法和基本对象
BOM(浏览器对象模型):描述了与浏览器进行交互的方法和接口
DOM(文档对象模型):描述了处理网页内容的方法和接口
2. 基本用法
JS需要和HTML一起使用才有效果,我们可以通过直接或间接的方式将JS代码嵌入在HTML页面中。
我们可以将JavaScript代码放在html文件中任何位置,但是我们一般放在网页的head或者body部分。由于页面的加载方式是从上往下依次加载的,而这个对我们放置的js代码运行是有影响的。
放在部分,最常用的方式是在页面中head部分放置
1.行内JS:写在标签内部的js代码
<button type="button" onclick="alert('Hello')">按钮</button>
onclink:点击事件,当点击元素时触发
alert("内容"):弹出层
2.内部JS:定义在script标签内部的js代码
<script type="text/javascript">
alert("你好");
</script>
3.外部JS:单独的js文件,在HTML中通过script标签引入
console.log("hello");
index.html中:
<script
src="script/script.js"
type="text/javascript"
charset="utf-8"
></script>
console.log(""); 打印内容在控制台
注:如果script标签设置了src属性,则在script标签中写的js代码无效。
3. 基础语法
3.1 语句
JavaScript程序的执行单位为行(line),也就是自上而下一行一行地执行。一般情况下,每一行就是一个语句。
语句(statement)是为了完成某种任务而进行的操作,语句以分号结尾,一个分号即表示一个语句结束。多个语句可以写在一行内(不建议这么写代码),但是一行写多条语句时,语句必须以分号结尾。
表达式不需要分号结尾。一旦在表达式后面添加分号,则JavaScript引擎就将表达式视为语句,这样会产生一些没有任何意义的语句。
<script type="text/javascript" charset="utf-8">
console.log(1);
console.log(2);
</script>
输出结果:
1
2
3.2 注释
HTML代码中:
兼容HTML注释方式:<!-- 注释内容 -->
JS代码中:
//:单行注释
/* 多行注释 */
3.3 标识符
标识符就是一个名字,用来给变量和函数进行命名,有特定规则和规范
规则:
由unicode字母、_、$、数字组成、中文组成
(1)不能以数字开头
(2)不能是关键字和保留字
(3)严格区分大小写
规范:
(1)见名知意
(2)驼峰命名或下划线规则
3.4 变量
变量即一个带名字的用来存储数据的内存空间,数据可以存储到变量中,也可以从变量中取出数据。
3.4.1 变量的声明
JavaScript是一种弱类型语言,在声明变量时不需要指明数据类型,直接用var修饰符进行声明。
1.声明并赋值
<script type="text/javascript">
var str = "Hello World";
console.log(str);
</script>
2.先声明再赋值
var str2;
str2 = "Hello World";
console.log(str2);
3.4.2 变量的注意点
(1)若只声明而没有赋值,则该变量的值为undefined。
var a;
console.log(a);
(2)变量要有定义才能使用,若变量未声明就使用,JavaScript会报错,告诉你变量未定义。
(3)可以在同一条var命令中声明多个变量。
var aa = 1,
bb = 2,
cc = 10;
console.log(aa, bb, cc);
(4)若使用var重新声明一个已经存在的变量且赋值,则会覆盖掉前面的值。
3.4.3 变量提升
JavaScript引擎的工作方式是,先解析代码,获取所有被声明的变量,然后再一行一行的运行。这样造成的结果是,所有的变量的声明语句,都会被提升到代码的头部,这就叫变量提升。(用var声明)
console.log(username); //undefined
var username = "ABC";
等价于
var username;
console.log(username);
username = "ABC";
3.5 数据类型
虽然JavaScript是弱类型语言,变量没有类型,但数据本身是有类型的。针对不同的类型,我们可以进行不同的操作。
JavaScript中有6种数据类型,其中有五种简单的数据类型:Undefined、Null、布尔、数值和字符串,一种复杂数据类型:Object。
对象(Object):各种值组成的集合
(1)对象(object) 如:{name:"zhangsan",age:"18"}
(2)数组(array) 如:[1,2,3]
(3)函数(function)如:function test() {}
3.5.1 undefined
(1)当声明了变量但未赋值时,这个变量的值就是undefined
var str;
console.log(str); //undefined
(2)调用函数时,函数有形参,但未提供实参,则参数为undefined
function test(str) {
console.log(str);
}
test(); //undefined
(3)函数没有返回值,默认返回undefined
function test(str) {
console.log(str);
}
var t = test(1); //1
console.log(t); //undefined
3.5.2 null
null类型是只有一个值的数据类型,他表示此处的值现在为空,他表示一个空对象引用。
使用null类型值时注意以下几点:
(1)使用typeof操作符测试null返回object字符串
var a = null;
console.log(null); //null
console.log(typeof null); //object
(2)undefined派生自null,所以等值比较返回值是true。未初始化的变量和赋值为null的变量相等。
var a;
console.log(a); //undefined
console.log(null == a); //true
3.5.3 布尔类型(boolean)
布尔类型有两个值:true和false。常用来做判断和循环的条件。
3.5.4 数值型(number)
数值型包含两种数值:整型和浮点型。
(1)所有数字(整型和浮点型)都是以64位浮点数形式存储。所以,JS中1和1.0相等,即1+1.0=2。
console.log(1 == 1.0); //true
console.log(1 + 1.0); //2
(2)浮点数最高精度是17位小数,由于浮点数运算时可能不准确,尽量不要使用浮点数做判断。
(3)在存储数值型数据时自动将可以转换为整型的浮点数(1.0)转为整型(1)。
var a = 1.0;
console.log(a); //1
3.5.5 字符串(string)
使用’'或""引起来,如:‘hello’,“good”。
使用加号"+"进行字符串的拼接,如:
console.log("hello" + "world"); //hello world
3.6 类型转换
3.6.1 自动类型转换
值 | 字符串 | 数字 | 布尔值 |
---|---|---|---|
undefined | “undefined” | NaN | false |
null | “null” | 0 | false |
true | “true” | 1 | true |
false | “false” | 0 | false |
“”(空字符串) | “” | 0 | false |
“1.5” | “1.5” | 1.5 | true |
“one” | “one” | NaN | true |
1 | “1” | 1 | true |
0 | “0” | 0 | false |
-0 | “0” | NaN | false |
NaN | “NaN” | NaN | false |
Infinity | “Infinity” | infinity | true |
-Infinity | “-Infinity” | -Infinity | true |
3.6.2 函数转换(String to Number)
JS提供了parseInt()和parseFloat()两个全局转换函数。前者把值转换成整数,后者把值转换成浮点数。只有对String类型调用这些方法,这两个函数才能正确运行,对其他类型返回的都是NaN。
(1)parseInt()
在转换之前,首先会分析该字符串,判断位置为0处的字符,判断它是否是一个有效数字。如果不是,则直接返回NaN,不再继续;如果是,则继续,直到找到非字符。
console.log(parseInt("1234abc")); //1234
console.log(parseInt("22.51")); //22
console.log(parseInt("abc")); //NaN
(2)parseFloat()
该方法与parseInt()方法的处理方式相似,从位置为0开始查看每个字符,直到找到第一个非有效的字符为止,然后把该字符之前的字符串转换成数字。不过,对于这个方法来说,第一个出现的小数点是有效字符。如果有两个小数点,第二个小数点将被看做无效的,parseFloat()方法会把这个小数点之间的字符串转换成数字。
console.log(parseFloat("1234abc")); //1234
console.log(parseFloat("22.51")); //22.51
console.log(parseFloat("abc")); //NaN
console.log(parseFloat("12.23.34.45")); //12.23
3.6.3 显示转换
(1)Number提供的toString()函数可以将数字转换为字符串。
var data = 10;
console.log(data); //10
console.log(data.toString()); //10(字符串)
var data1 = null;
console.log(data1.toString()); //报错
(2)Number还提供了toFixed()函数将根据小数点后指定位数将数字转为字符串,四舍五入。
var data = 1.1;
console.log(data.toFixed(0)); //1
var data1 = 1.5678;
console.log(data1.toFixed(1)); //1.6
3.6.4 构造方法
JS为number、boolean、string对象提供了构造方法,用于强制转换其他类型的数据。此时操作的是整个数据,而不是部分。
Number(undefined); //NaN
Number(null); //0
Number(true); //1
Number(false); //0
Number(""); //0
Number("7.7"); //7.7
Number("77"); //77
Number("7.7.7"); //NaN
Number("seven"); //NaN
Number(1); //1
Number(0); //0
Number(-0); //-0
Number(NaN); //NaN
Number(Infinity); //Infinity
Number(-Infinity); //-Infinity
Number(new Object()); //NaN
Number(100); //100
注:number、boolean、string构造方法与自动类型转换表一致
其中string()强制类型转换方法是最简单的,他可以把任何值转换成字符串。与toString()方法的唯一不同之处在于,对null或undefined值强制类型转换可以生成字符串而不引发错误。
var a = null;
console.log(String(a)); //null (字符串类型)
var flag = true;
console.log(flag + ""); //true (字符串类型) 直接在任意数值后面+""即可
var b = undefined;
console.log(String(b)); //undefined (字符串类型)
3.7 运算符
运算符用于执行程序代码运算,会针对一个或多个操作数来进行运算。
3.7.1 算术运算符
运算符 | 描述 | 例子(y=5) | 结果 |
---|---|---|---|
+ | 加 | x=y+2 | x=7 |
- | 减 | x=y-2 | x=3 |
* | 乘 | x=y*2 | x=10 |
/ | 除 | x=y/2 | x=2.5 |
% | 求余 | x=y%2 | x=1 |
++ | 自增(前导加,后导加) | x=++y | x=6 |
– | 自减(前导减,后导减) | x=–y | x=4 |
3.7.2 比较运算符
运算符 | 描述 | 例子(x=5) |
---|---|---|
== | 等于(值) | x==8为false |
=== | 全等(值和类型) | x===5为true,x==="5"为false |
!= | 不等于 | x!=8为true |
> | 大于 | x>8为false |
< | 小于 | x<8为true |
>= | 大于等于 | x>=8为false |
<= | 小于等于 | x<=8为true |
3.7.3 逻辑运算符
运算符 | 描述 | 例子 |
---|---|---|
&& | and | (x<10&&y>1)为true |
|| | or | (x==5||y==5)为true |
! | not | !(x==y)为true |
3.7.4 三目运算符
运算符 | 描述 | 例子 |
---|---|---|
?: | 如果正确,输出?后;如果错误,输出:后 | 3>5?3:5,结果为5 |
3.8 控制语句
我们写的JavaScript 代码都是按照从上到下依次执行,很多时候我们希望代码按照我们的意愿去执行,比如有选择性地执行某些代码,或者重复地执行某些代码,这就需要使用到流程控制语句。
流程控制语句一共有三种:
1.流程执行:从上到下,从左到右
2.选择执行:分支选择
3.循环执行:重复执行
3.8.1 选择
(1)单选择:
if(条件){
语句体;
}
首先执行条件,如果结果为true,则执行语句体;如果结果为false,则结束if语句。
注意:若语句体只有一条语句,可以省略大括号,但不建议省略。
(2)双选择:
if(条件){
语句体1;
}else{
语句体2;
}
首先执行条件,如果结果为true,则执行语句体1;如果结果为false,则执行语句体2。
(3)多选择:
if(比较表达式1){
语句体1;
}else if(比较表达式2){
语句体2;
}else if(语句表达式3){
语句体3;
}
...
else{
语句体n+1;
}
(4)switch结构:
多个if…else且值为定值时,可以使用switch替换。即在比较运行结果时,采用的是严格相等运算符(===),而不是相等运算符(==),这意味着比较时不会发生类型转换。
switch(表达式){
case 值1:
语句体1;
break;
case 值2:
语句体2;
break;
...
default:
语句体n+1;
break;
}
break防止穿透,如果没有break,则继续执行后面的代码,直到遇到break或全部执行完毕,但时候些时候会利用穿透。
3.8.2 循环
循环结构用于重复执行某个操作。简单理解就是重复执行同类型的代码,它有多种形式。
(1)while:
先判断后执行
while(判断条件语句){
循环体语句;
}
(2)do…while:
新之行后判断,至少执行一次
do{
循环体语句;
}while(判断条件语句);
(3)for:
for(初始化语句;判断条件语句;控制条件语句){
循环体语句;
}
(4)死循环:
条件永远成立,永远为true,则会产生死循环,下面是最简单的死循环:
while(true){}
for(;;){}
(5)break和continue:
break:停止本层循环
continue:暂停本次循环,继续下一次
3.9 数组
数组是按次序排列的一组数据,每个值的位置都有编号(从0开始),整个数组用方括号表示。
3.9.1 数组定义
JS中定义数组的三种方式如下(也可以先声明再赋值):
var arr1 = [值1,值2,值3]; //隐式创建
var arr2 = new Array(值1, 值2, 值3); //直接实例化
var arr3 = new Array(size); //创建数组并指定长度
数组特点:
1.长度可变;
2.数组中可以任意数据类型;
3.索引从0开始;
4.可以使用任意字符当做数组的索引,如果索引是非正整数,我们称之为数组的属性,属性不影响数组的长度。
3.9.2 基本操作
(1)数组的长度可以通过length属性来获取,并可以任意修改
数组名.length
数组名.length = 新长度
例子:
var arr1 = [1, 2, 3];
var arr2 = [1, 2, 3];
console.log(arr1.length); //3
arr2.length = 5;
console.log(arr2); //[1, 2, 3, empty × 2]
(2)数组中的每一个元素都可以被访问和修改,甚至是不存在的元素,无所谓越界
访问:数组名[下标]
例子:
var arr1 = [1, 2, 3];
console.log(arr1[0]); //1
console.log(arr1[10]); //undefined
修改:数组名[下标] = 新值
例子:
var arr1 = [1, 2, 3];
arr1[5] = "abc";
arr1[]
console.log(arr1); //[1, 2, 3, empty × 2, 'abc']
(3)数组中下标任意字符当做数组的索引,如果索引是非正整数,我们称之为数组的属性,属性不影响数组的长度。
var arr1 = [1, 2, 3];
arr1["username"] = "admin";
console.log(arr1); //[1, 2, 3, username: 'admin'] length: 3
3.9.3 数组遍历
(1)普通的for循环遍历:只能得到正常的索引和空数据
var arr1 = [1, 2, 3];
arr1.length = 5;
arr1["username"] = "admin";
for (var i = 0; i < arr1.length; i++) {
console.log(arr1[i]);
}
输出结果:
1
2
3
undefined
undefined
(2)for…in:
for(var 下标(任意名称) in 数组名){
数组名[下标]是获取元素
}
例子:
for (var index in arr1) {
console.log(index);
console.log(arr1[index]);
console.log("=======");
}
输出结果:
0
1
=====
1
2
=====
2
3
=====
username
admin
=====
(3)forEach:
数组名.forEach(function(element,index)){ //element(任意名称):元素;index(任意名称):下标
}
例子:
var arr1 = [1, 2, 3];
arr1.length = 5;
arr1["username"] = "admin";
arr1.forEach(function (element, index) {
console.log(element);
console.log(index);
console.log("=====");
});
输出结果:
1
0
=====
2
1
=====
3
2
=====
或
arr1.forEach((element) => {
console.log(element);
});
输出结果:
1
2
3
(4)注意事项:
数组在使用的时候建议大家规矩来用。在存放数据时,从下标0开始顺序的存放数组元素。
如果下标:
1.为非负整数(包括整数字符串):自动从0开始,不存在添加undefined
2.为负数、小数、非数字符串:这些内容不计算在长度内,当成“属性”处理,相当于自定义属性。
数组非常灵活,使用数组元素
1.下标:非负整数(包括整数字符串)∶
数组.下标
数组[下标]
2.下标:负数、小数、非数字字符串:
数组[属性]
for:不遍历属性
for in:不遍历索引中的undefined
foreach :不遍历属性和索引中的undefined
3.9.4 数组提供的操作方法
push 添加元素到最后
unshift 添加元素到最前
pop 删除最后一项
shift 删除第一项
reverse 数组反转
join 数组转成字符串
indexof 数组元素索引
slice 截取(切片)数组,原数组不发生变化
splice 剪接数组,原数组变化,可以实现前后删除效果
concat 数组合并
var arr = [1, 2, "a", 3, "b"];
console.log(arr); //[1, 2, 'a', 3, 'b']
arr.push("c");
console.log(arr); //[1, 2, 'a', 3, 'b', 'c']
arr.unshift(0);
console.log(arr); //[0, 1, 2, 'a', 3, 'b', 'c']
arr.pop();
console.log(arr); //[0, 1, 2, 'a', 3, 'b']
arr.shift();
console.log(arr); //[1, 2, 'a', 3, 'b']
arr.reverse();
console.log(arr); //['b', 3, 'a', 2, 1]
console.log(arr.join(",")); //b,3,a,2,1 (字符串类型)
var index = arr.indexOf("a");
console.log(index); //2
var a = arr.slice(2, 3);
console.log(a); //['a']
var b = arr.slice(2, 4);
console.log(b); //['a', 2]
var arr2 = arr.splice(1, 2, "aa", "bb"); //从下标为1的数组开始截取,截取2个,再添加新的"aa""bb"
console.log(arr2); //[3, 'a']
console.log(arr); //['b', 'aa', 'bb', 2, 1]
var arr3 = [100, 200];
var arr4 = arr.concat(arr3);
console.log(arr4); //['b', 'aa', 'bb', 2, 1, 100, 200]
3.10 函数
函数,即方法。就是一段预先设置的功能代码块,可以反复调用,根据输入参数的不同,返回不同的值。函数也是对象。
JS中函数没有重载,如果出现同名方法则覆盖。
3.10.1 函数的定义
(1)函数声明语句:
该方法定义的函数具有声明提升的效果
function 函数名([参数列表]){
}
例如:
function a(){
console.log(1);
}
a();
(2)函数定义表达式:
以表达式方式定义的函数,函数的名称是可以不需要的。这种写法将一个匿名函数赋值给变量。这个匿名函数又称函数表达式,因为赋值语句的等号右侧只能放表达式。
var 变量名 = function([参数列表]) {
}
变量名();
例如:
var fun = function(){
console.log("Hello");
}
fun();
(3)Function构造函数:
Function构造函数接收任意数量的参数,但最后一个参数始终都被看成是函数体,而前面的参数则列举出了新函数的参数。
var add = new Function("x", "y", "return (x + y)");
等同于:
function add(x,y) {
return (x + y);
}
add(1,2);
3.10.2 函数的参数、调用和return语句
(1)参数:
函数运行的时候,有时需要提供外部数据,不同的外部数据会得到不同的结果,这种外部数据就叫参数。定义时的参数称为形参,调用时的参数称为实参。
1.实参可以省略,那么对应形参为undefined
function fun(str) {
console.log(str);
}
fun(); //undefined
2.若函数形参同名(一般不会出现)︰在使用时以最后一个值为准。
function fun(a, a) {
console.log(a);
}
fun(1, 2); //2
3.可以给参数默认值:当参数为特殊值时,可以赋予默认值。
function fun(a) {
a = a || "a";
return a;
}
var a1 = fun();
console.log(a1); //a (字符串类型)
var a2 = fun(100);
console.log(a2); //100
4.参数为值传递,传递副本;引用传递时传递地址,操作的是同一个对象。
值传递:
var n = 10;
function fun(num) {
num = 20;
}
fun(n);
console.log(n); //10
引用传递:
var n = 10;
function fun(num) {
num = 20;
}
fun(n);
console.log(n); //{uname: '李四', upwd: '123456'}
(2)调用:
1.常用调用方式:
函数名([参数列表]);
2.函数调用模式:
function add(a, b) {
return a + b;
}
var sum = add(10, 20);
console.log(sum);
3.对象调用对象:
var ob = {
name: "张三",
age: 18,
sex: true,
test: function () {
console.log("Hello");
},
};
ob.test(); //Hello
(3)return语句:
1.如果函数有返回值,需要通过return返回;
2.如果函数不需要返回数据时,则无返回值,或者说返回undefined
3.如果函数不需要返回值时,使用return,则表示结束方法
3.10.3 函数的作用域
函数作用域:全局和局部
(1)全局变量与局部变量同名问题
(2)在函数中定义变量时,若没有加var关键字,使用之后自动变为全局变量
var a = 10; //全局变量
function test(x) {
var x = 100; //局部变量
var a = 200; //局部变量 与全局变量a没有关系,相当于新声明的变量
console.log(a); //就近原则 200
c = 12; //没有var修饰符,则是全局变量
}
test(a);
console.log(a); //只能获取全局变量 10
console.log(c); //12
3.11 内置对象
String 字符串对象,提供对字符串的一系列操作
Math 数学对象
Date 日期对象,用来创建和获取日期
Arguments 只在函数内部定义,保存了函数的实参
Array 数组对象
3.11.1 String
charAt(idx) 返回指定位置处的字符。idx:下标
indexOf(Chr) 返回指定字符串的位置,从左到右,找不到返回-1。Chr:指定字符串
substr(m,n) 返回给定字符串中从m位置开始,取n个字符,如果参数n省略,则意味着取到字符串末尾。
substring(m,n) 返回给定字符串中从m位置开始,到n位置结束,如果参数n省略,则意味着取到字符串末尾。
toLowerCase() 将字符串中的字符全部转化成小写
toUpperCase() 将字符串中的字符全部转化成大写
length 属性,不是方法,返回字符串的长度
3.11.2 Math
Math.random() 随机数
Math.ceil() 向上取整,大于最大整数
Math.floor() 向下取整,小于最小整数
3.11.3 Date
//获取日期
getFullYear() 年
getMonth() 月,0~11 (1月~12月)
getDate() 日
getHours() 时
getMinutes() 分
getSeconds() 秒
//设置日期
setYear()
setMonth() 0~11
setDate()
setHours()
setMinutes()
setSeconds()
toLocaleString() 可根据本地时间把Date对象转换为字符串,并返回结果。
var date = new Date();
var time = date.toLocaleDateString();
console.log(time); //2022/7/14(字符串类型)
3.12 对象
对象(object)是JavaScript的核心概念,也是最重要的数据类型。JavaScript 的所有数据都可以被视为对象。JavaScript 提供多个内建对象,比如String、Date、Array等等。对象是带有属性和方法的特殊数据类型。
简单说,所谓对象,就是一种无序的数据集合,由若干个"键值对“(key-value)构成。通过JavaScript我们可以创建自己的对象。JavaScript对象满足的这种"键值对"的格式我们称为JSON格式,以后会见得非常多,即伟大的JSON对象。
3.12.1 对象的创建
JS创建自定义对象主要通过三种方式:
(1)字面量形式创建:(重点)
var 对象名 = {}; //空对象
或
var 对象名 = {
键:值,
键:值,
...
};
赋值与修改:
对象名.键 = 值
例子:
//空对象:
var obj = {}; //空对象
console.log(obj); //{}
obj.uname = "张三";
obj.uage = 18;
console.log(obj); //{uname: '张三', age: 18}
//非空对象 键都是字符串,值可以是6种数据类型中任意一种
var obj = {
uname: "张三", //字符串
uage: 18, //数值
islike: true, //布尔值
sayHello: function () {
console.log("Hello...");
}, // 函数
pets: ["小喵", "小汪"], //数组
dog: {
name: "张二狗",
age: 1,
}, //对象
};
console.log(obj);
obj.sayHello(); //调用sayHello()函数
obj.uage = 19; //修改张三年龄为19
(2)通过new Object对象创建:
var obj = new Object(); //创建一个空对象
obj.name = "张三";
obj.age = 18;
console.log(obj); //{name: '张三', age: 18}
(3)通过Object对象的create方法创建对象
var 对象名 = Object.create(null); //创建空对象
var 对象名 = Object.create(参考对象); //以参考对象为模板,创建新的对象
例子:
var obj1 = new Object(); //创建一个空对象
obj1.name = "张三";
var obj2 = Object.create(null); //创建一个空对象
console.log(obj2.name); //undefined
var obj3 = Object.create(obj1); //以obj1为模板,创建新的对象
console.log(obj3.name); //张三
3.12.2 对象的系列化和反序列化
序列化:将JS对象序列化为字符串。反序列化:将字符串反序列化为JS对象。
JS中通过调用JSON方法,可以将对象序列化成字符串,也可以将字符串反序列化成对象。
var obj = {
uname: "张三", //字符串
uage: 18, //数值
islike: true, //布尔值
sayHello: function () {
console.log("Hello...");
}, // 函数
pets: ["小喵", "小汪"], //数组
dog: {
name: "张二狗",
age: 1,
}, //对象
};
var str = JSON.stringify(obj);
console.log(str); //{"uname":"张三","uage":18,"islike":true,"pets":["小喵","小汪"],"dog":{"name":"张二狗","age":1}}
//将JS对象序列化为字符串
var obj2 = JSON.parse(str); //将字符串反序列化为JS对象
console.log(obj2);
3.12.3 this
this是JavaScript语言的一个关键字。它代表函数运行时,自动生成一个内部对象,只能在函数内部使用。随着函数使用场合的不同,this的值会发生变化。但是有一个总的原则,哪个对象调用函数,this指的就是哪个对象。
(1)在函数中使用this:
在函数中使用this属于全局性调用,代表全局对象,通过window对象来访问。
function test() {
this.x = 1;
console.log(this.x);
}
test(); //全局调用时,调用者为window,1
console.log(x); //相当于定义在全局对象上的属性,1
console.log(this); //当前的调用者是window对象,Window {window: Window, self: Window, …}
(2)在对象中使用this:
var obj = {
uname: "张三",
uage: 18,
sayHello: function () {
console.log(this.uname);
console.log(this);
},
};
obj.sayHello(); //当前调用者是obj对象
输出结果:
张三
{uname: '张三', uage: 18, sayHello: ƒ}
4. 事件、BOM对象和DOM对象
4.1 事件的作用
事件(Event)是JavaScript应用跳动的心脏,进行交互,使网页动起来。当我们与浏览器中Web页面进行某些类型的交互时,事件就发生了。事件可能是用户在某些内容上的点击、鼠标经过某个特定元素或按下键盘上的某些按键。事件还可能是Web浏览器中发生的事情,比如说某个Web页面加载完成,或者是用户滚动窗口或改变窗口大小。通过使用JavaScript,你可以监听特定事件的发生,并规定让某些事件发生以对这些事件做出响应。
(1)验证用户输入的数据。
(2)增加页面的动感效果。
(3)增强用户的体验度。
4.2 事件中的几个名词
事件源:谁触发的事件
事件名:触发了什么事件
事件监听:谁管这个事情,谁监视?
事件处理:发生了怎么办
例如:
闯红灯 事件源:车; 事件名:闯红灯; 监听:摄像头、交警; 处理:扣分罚款
单击按钮 事件源:按钮; 事件名:单击; 监听:窗口; 处理:执行函数
4.3 事件类型
HTML DOM 事件对象 | 菜鸟教程 (runoob.com)
JavaScript可以处理的事件类型为:鼠标事件、键盘事件、HTML事件。
Mouse事件:由鼠标或类似用户动作触发的事件
Keyboard 事件:键盘事件
Form事件:由HTML表单内的动作触发的事件(应用到几乎所有HTML元素,但最常用在form元素中)
Media事件:由媒介(比如视频、图像和音频)触发的事件。适用于所有HTML元素,但常见于媒介元素中,比如<audio>、<embed>、<img>、<object>以及<video>
Window事件属性:针对window对象触发的事件(应用到<body>标签)
4.4 事件流和事件模型
我们的事件最后都有一个特定的事件源,暂且将事件源看做是HTML的某个元素,那么当一个HTML元素产生一个事件时,该事件会在元素节点与根节点之间按特定的顺序传播,路径所经过的节点都会受到该事件,这个传播过程称为DOM事件流。
事件顺序有两种类型:事件冒泡和事件捕获。
冒泡和捕获其实都是事件流的不同表现,这两者的产生是因为IE和Netscape两个大公司完全不同的事件流概念产生的。
事件流:指页面接受事件的顺序。IE的事件流是事件冒泡,Netscape的事件流是事件捕获流。
4.4.1 事件冒泡
IE的事件流叫做事件冒泡,即事件开始时由最具体的元素接受,然后逐级向上传播到较为不具体的节点(文档)。
<!DOCTYPE html>
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<body>
<div id="myDiv">click me</div>
</body>
</html>
如果点击了页面中的<div>元素,那么这个click事件会按照如下顺序传播:
1、<div>
2、<body>
3、<html>
4、document
也就是说,click事件首先在div元素上发生,而这个元素就是我们单击的元素。然后,click事件沿DOM树向上传播,在每一级节点上都会发生,直到传播到document对象。
几乎所有现代浏览器都支持事件冒泡,但在具体实现上还是有一些差别。
4.4.2 事件捕获
Netscape提出的另一种事件流叫做事件捕获,事件捕获的思想是不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件。事件捕获的用意在于在事件到达预定目标之前捕获它。还以前面的例子为例。那么单击<div>元素就会按下列顺序触发click事件:
1、document
2、<html>
3、<body>
4、<div>
在事件捕获过程中,document对象首先接收到click事件,然后沿DOM树依次向下,一直传播到事件的实际目标,即<div>元素。
虽然事件捕获是Netscape唯一支持的事件流模式,但很多主流浏览器目前也都支持这种事件流模型。尽管"DOM2级事件"规范要求事件应该从document对象开始时传播,但这些浏览器都是从window对象开始捕获的。
4.4.3 DOM事件流
“DOM2级事件"规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。
首先发生的是事件捕获阶段,为截获事件提供了机会。然后是实际的目标接收到事件。最后一个阶段是冒泡阶段,可以在这个阶段对事件做出响应。
冒泡过程
8<----------7<------------6<----------5<----
window document body div |
1---------->2------------>3---------->4-----
捕获过程
4.5 事件处理程序
事件就是用户或浏览器自身执行的某种动作,例如click、load和mouseover都是事件的名字。而响应某个事件的函数就叫做事件处理程序(或事件侦听器)。事件处理程序的名字以"on"开头,因此click事件的事件处理程序就是onclick,为事件指定处理程序的方式有好几种。
4.5.1 HTML事件处理程序
某个元素支持的每种事件,都可以用一个与相应事件处理程序同名的HTML特性来指定。这个特性的值应该是能够执行的JavaScript代码:
<button type="button" onclick="alert('Hello')" onmouseout="test()">按钮</button>
function test() {
console.log("鼠标移开了...");
}
这样做有一些缺点,例如耦合度过高,还可能存在时差问题(当用户点击按钮时,处理函数还未加载到,此时处理函数是单独写的一段JS代码),而且在不同的浏览器上可能会有不同的效果。
4.5.2 DOM0级事件处理程序
通过JavaScript指定事件处理程序的传统方式,就是将一个函数赋值给一个事件处理程序属性。只能为同一个元素的同一个事件设定一个事件程序(后者覆盖前者)。
这种方式被很多现代浏览器所支持。这种方式首先必须取得一个要操作的对象的引用,每个元素都有自己的事件处理程序属性,这些属性通常全都小写,例如onclick,然后将这种属性的值设为一个函数,就可以指定事件处理程序了。例如:
<body>
<button type="button" id="btn">DOM0级事件处理程序</button>
</body>
<script type="text/javascript">
//通过id属性值获取按钮对象
var btn = document.getElementById("btn");
console.log(btn); //<button type="button" id="btn">DOM0级事件处理程序</button>
//给指定元素绑定点击事件
btn.onclick = function () {
console.log("DOM0级事件..."); //只能为同一个元素的同一个事件设定一个事件程序(后者会覆盖前者)
};
btn.onclick = function () {
console.log("test..."); //test...
};
</script>
//如果将<script>写到<head>中,需要加window.onload = function() {}
<!DOCTYPE html>
<head>
<meta charset="UTF-8" />
<title>Document</title>
<script type="text/javascript">
window.onload = function(){ //当页面或图像加载完后才会加载,因此当代码加载完后,就存在btn对象了
//通过id属性值获取按钮对象
var btn = document.getElementById("btn");
console.log(btn);
//给指定元素绑定点击事件
btn.onclick = function () {
console.log("DOM0级事件...");
};
btn.onclick = function () {
console.log("test...");
};
}
</script>
</head>
<body>
<button type="button" id="btn">DOM0级事件处理程序</button>
</body>
</html>
4.5.3 DOM2级事件处理程序
“DOM2级事件"定义了两个方法,用于处理指定和删除事件处理程序的操作:addEventListener()和removeEventListener()。
所有DOM节点都包含这两个方法,并且他们都接受3个参数:参数1:事件名;参数2:处理事件程序的函数;事件3:布尔值。最后这个布尔值参数如果是true,则表示在捕获阶段调用事件处理程序;如果是false则表示在冒泡阶段调用事件处理程序。
var btn2 = document.getElementById("btn2");
btn2.addEventListener('click',function(){ //给按钮绑定事件监听1
console.log("DOM2级事件...");
})
btn2.addEventListener('click',fn); //给按钮绑定事件监听2 可以为同一个元素的同一个事件**设定多个事件程序**
function fn(){
console.log("按钮被点击了...");
}
btn2.removeEventListener('click',fn); //移除事件监听2
输出结果:
DOM2级事件...
4.6 常用事件
几个常用事件:
on1oad:当页面或图像加载完后立即触发
onblur:元素失去焦点
onfocus:元素获得焦点
onclick:鼠标点击某个对象
onchange:用户改变域的内容
onmouseover:鼠标移动到某个元素上
onmouseout:鼠标从某个元素上离开
onkeyup:某个键盘的键被松开
onkeydown:某个键盘的键被按下
//on1oad:当页面或图像加载完后立即触发
window.onload = function () {
console.log("页面加载完成...");
};
=========================================
//onblur:元素失去焦点
//onfocus:元素获得焦点
<body>
姓名:<input type="text" id="uname" />
</body>
<script>
//绑定onblur事件
var uname = document.getElementById("uname");
uname.onblur = function () {
console.log("文本框失去焦点...");
};
//绑定onfocus事件
uname.onfocus = function () {
console.log("文本框获取焦点...");
};
</script>
=========================================
//onclick:鼠标点击某个对象
<body>
<button type="button" onclick="clickBtn()">按钮</button>
</body>
<script>
function clickBtn() {
console.log("按钮被点击了...");
}
</script>
=========================================
//onchange:用户改变域的内容
<body>
城市:<select id="city">
<option>请选择城市</option>
<option>北京</option>
<option>上海</option>
</select>
</body>
<script>
document.getElementById("city").onchange = function () {
console.log("下拉框的值改变了...");
};
</script>
=========================================
//onmouseover:鼠标移动到某个元素上
//onmouseout:鼠标从某个元素上离开
<body>
<div id="div1">这是一个div</div>
</body>
<script>
var div1 = document.getElementById("div1");
div1.onmouseover = function () {
console.log("鼠标悬停...");
};
div1.onmouseout = function () {
console.log("鼠标移开...");
};
</script>
=========================================
//onkeyup:某个键盘的键被松开
//onkeydown:某个键盘的键被按下
<body>
姓名:<input type="text" id="uname" />
</body>
<script>
var uname = document.getElementById("uname");
uname.onkeydown = function () {
console.log("按键按下...");
};
uname.onkeyup = function () {
console.log("按键松开...");
};
</script>
5. BOM对象
BOM的核心对象是window,它表示浏览器的一个实例。window对象有双重角色,它既是通过JavaScript访问浏览器窗口的一个接口,又是ECMAScript规定的Global对象。这意味着在网页中定义的任何一个对象、变量和函数,都以window作为其Global对象,因此有权访问parseInt()等方法。如果页面中包含框架,则每个框架都拥有自己的window对象,并且保存在frames集合中。在frames集合中,可以通过数值索引(从0开始,从左至右,从上到下)或者框架的名称来访问相应的window对象。
5.1 Window对象方法
5.1.1 系统对话框
浏览器通过(实际是window对象的方法)alert()、confirm()、prompt()方法可以调用系统对话框向用户显示消息。
<body>
<button type="button" onclick="testAlert()">消息框</button>
<button type="button" onclick="testPrompt()">输入框</button>
<button type="button" onclick="testConfirm()">确认框</button>
</body>
<script>
//(1)消息框:alert
function testAlert() {
window.alert("Hello"); //window.可以省略
console.log("你好"); //alert()消息框会阻止后面代码运行,除非点击确认键
}
//(2)输入框:prompt
function testPrompt() {
var uname = window.prompt("请输入用户名:", "");
console.log("用户名为:", uname);
}
//(3)确认框:confirm
function testConfirm() {
var flag = confirm("你确认要删除该记录吗?");
if (flag) {
alert("删除成功!");
} else {
alert("没事别瞎点...");
}
}
</script>
5.1.2 打开窗口
window.open()方法既可以导航到一个特定的URL也可以用来打开一个新的窗口
<body>
<button type="button" id="btn1">打开窗口</button>
</body>
<script>
document.getElementById("btn1").onclick = function () {
//打开空白窗口
//window.open();
//打开指定页面
//window.open("https://www.baidu.com/");
//指定方式打开页面
window.open("https://www.baidu.com/", "_self");
};
</script>
5.1.3 关闭窗口
<body>
<button type="button" onclick="test()">关闭窗口</button>
</body>
<script>
function test() {
window.close();
}
</script>
5.1.4 时间函数
(1)setTimeout():
在指定的毫秒数后调用函数或计算表达式,返回一个唯一的标识。也可以通过返回的标识clearTimeout(id):来清除函数的执行。
var id = setTimeout(function, times);
参数1:执行的函数
参数2:时间,单位毫秒
例子:
setTimeout(function () {
console.log("3秒钟后执行的程序...");
}, 3000);
=========================================
<body>
<button type="button" onclick="toBaidu()">3秒钟后跳转到百度</button>
</body>
<script>
function toBaidu() {
setTimeout(test, 3000);
}
function test() {
window.open("https://www.baidu.com/");
}
</script>
=========================================
<body>
<button type="button" onclick="init()">开始</button>
<button type="button" onclick="stop()">暂停</button>
<h2 id="time"></h2>
</body>
<script>
var id;
function init() {
var time = new Date().toLocaleTimeString();
//将时间赋值给h2标签
document.getElementById("time").innerHTML = time;
//每秒钟调用自己
id = setTimeout(init, 1000);
}
function stop() {
//时间停止
clearTimeout(id);
}
</script>
(2)setInterval():
可按照指定的周期(以毫秒计)来调用函数或表达式,也可根据返回的标识用来结束。该方法会不停的调用函数,知道clearInterval()被调用或窗口被关闭。
var id = setInterval(function, times);
参数1:执行的函数
参数2:时间,单位毫秒
例子:
<body>
<button type="button" onclick="Hello()">定时执行</button>
</body>
<script>
function Hello() {
setInterval(function () {
console.log("你好...");
}, 1000);
}
</script>
5.2 history对象
history对象的属性:
window.history.length:返回浏览器历史列表中的URL数量
history对象的方法:
back():加载history列表的前一个URL
forward():加载history列表的下一个URL。当页面第一次访问时,还没有下一个URL
go(number|URL):URL参数使用的是要访问的URL。而number参数使用的是要访问的URL在history的URL列表中的相对位置。go(-1)返回上一页
5.3 location对象
location对象是window对象之一,提供了与当前窗口中加载的文档有关的信息,还提供了一些导航功能。也可通过window.location 属性来访问。
location对象的属性:
href:设置或返回完整的URL
location对象的方法:
reload():重新加载当前文档
replace():用新的文档替换当前文档,不可后退
例子:
<body>
<button type="button" onclick="test()">跳转</button>
</body>
<script>
//获取当前访问的URL
var url = window.location.href;
console.log(url);
function test() {
//页面跳转
window.location.href = "https://www.baidu.com/";
}
</script>
=========================================================
<body>
<button type="button" onclick="test()">reload()</button>
</body>
<script>
function test() {
window.location.reload();
}
</script>
=========================================================
<body>
<button type="button" onclick="test()">replace()</button>
</body>
<script>
//不能后退页面
function test() {
window.location.replace("https://www.baidu.com/");
}
</script>
6. DOM对象
DOM(Document Object Model):文档对象模型
要实现页面的动态交互效果,BOM操作远远不够,需要操作HTML才是核心。如何操作HTML,就是DOM。简单的说,DOM提供了用程序动态控制HTML接口。DOM描绘了一个层次化的节点树,运行开发人员添加、移除和修改页面的某一部分。DOM处于JavaScript的核心地位上。
每个载入浏览器的HTML文档都会成为Document对象。Document对象使我们可以从脚本中对HTML页面中的所有元素进行访问。Document对象是Window对象的一部分,可通过window.document属性对其进行访问。
6.1 节点
加载HTML页面时,Web浏览器生成一个树型结构,用来表示页面内部结构。DOM将这种树型结构理解为由节点组成,组成一个节点树。对于页面中的元素,可以解析成以下几种类型的节点:
节点类型 | HTML内容 | 例如 |
---|---|---|
文档节点 | 文档本身 | 整个文档document |
元素节点 | 所有的HTML元素 | <a>、<div>、<p> |
属性节点 | HTML元素内的属性 | id、href、name、class |
文本节点 | 元素内的文本 | hello |
注释节点 | HTML中的注释 | <!-- --> |
6.2 操作元素的节点
6.2.1 获取节点
在进行增、删、改的操作时,都需要指定到一个位置,或者找到一个目标,此时我们就可以通过Document对象提供的方法,查找、定位某个对象(也就是我们说的节点)。注意:操作DOM必须等节点初始化完毕后,才能执行。
处理方式两种:
(1)把JavaScript调用标签移到HTML末尾即可;
(2)使用onload事件来处理JavaScript,等待HTML加载完毕再加载onload事件里的JavaScript。
window.onload = function() {} //预加载HTML后执行
获取方式如下:
方法 | 描述 |
---|---|
getElementById() | 根据id获取DOM对象,如果id重复,那么以第一个为准 |
getElementsByName() | 根据name属性值获取DOM对象数组,常用于多选获取值 |
getElementsByTagName() | 根据标签名获取DOM对象数组 |
getElementsByClassName() | 根据样式名获取DOM对象数组 |
例子:
//javascript:void(0)主要用于防止页面跳转,如果不加,默认是进行href的跳转,所以“1”会一闪而过
//否则直接换为button标签
<body>
<a href="javascript:void(0)" onclick="testById()">按照id获取</a>
</body>
<script>
function testById() {
console.log(1);
}
</script>
=================getElementById()=================
//如果获取元素时,id有多个,则以第一个为准
<body>
<p id="p1" class="para">这是一个段落</p>
<p id="p1" class="para">这又是一个段落</p>
</body>
<script>
function testById() {
var p = document.getElementById("p1");
console.log(p); //这是一个段落
}
</script>
=================getElementsByName()=================
<body>
<input type="checkbox" name="hobby" value="游泳" />游泳
<input type="checkbox" name="hobby" value="篮球" />篮球
<input type="checkbox" name="hobby" value="足球" />足球
<a href="javascript:void(0)" onclick="testByName()">按照name获取</a>
</body>
<script>
function testByName() {
var hobby = document.getElementsByName("hobby");
console.log(hobby[0]); //<input type="checkbox" name="hobby" value="游泳">
console.log(hobby[1]); //<input type="checkbox" name="hobby" value="篮球">
console.log(hobby[2]); //<input type="checkbox" name="hobby" value="足球">
}
</script>
=================getElementsByTagName()=================
<body>
<input type="text" name="txt" />
<input type="checkbox" name="hobby" value="游泳" />游泳
<input type="checkbox" name="hobby" value="篮球" />篮球
<input type="checkbox" name="hobby" value="足球" />足球
<a href="javascript:void(0)" onclick="testByTagName()">按照标签名获取</a>
</body>
<script>
function testByTagName() {
var inputs = document.getElementsByTagName("input");
for (var i = 0; i < inputs.length; i++) {
console.log(inputs[i].type + ",", inputs[i].value); //input的类型,input的值
if (inputs[i].type == "checkbox") {
console.log(inputs[i].checked); //单选框或复选框是否选中
}
}
}
</script>
输出结果:
text,
checkbox, 游泳
false
checkbox, 篮球
false
checkbox, 足球
false
=================getElementsByClassName()=================
<body>
<p id="p1" class="para">这是一个段落</p>
<p id="p1" class="para">这又是一个段落</p>
<a href="javascript:void(0)" onclick="testByClass()">按照class获取</a>
</body>
<script>
function testByClass() {
var clas = document.getElementsByClassName("para");
console.log(clas.length); //2
}
</script>
6.2.2 创建节点与插入节点
很多时候我们想要在某个位置插入一个新的节点,此时我们首先需要有一个节点存在,可以通过以下几种方式创建新节点。
(1)创建节点
方法 | 描述 |
---|---|
createElement() | 创建一个新的节点,需要传入节点的标签名称,返回创建的元素对象 |
createTextNode() | 创建一个文本节点,可以传入文本内容 |
innerHTML | 也能达到创建节点的效果,直接添加到指定位置 |
(2)插入节点
方法 | 描述 |
---|---|
write() | 将任意的字符串插入到文档中 |
appendChild() | 向元素中添加新的子节点,作为最后一个子节点 |
insertBefore() | 向指定的已有的节点之前插入新的节点} newItem:要插入的节点 exsitingItem:参考节点 需要参考父节点 |
例1:添加段落
=================添加段落-方法一=================
<body>
<button onclick="addPara()">添加段落</button>
<div id="container"></div>
</body>
<script>
function addPara() {
//获取容器
var div = document.getElementById("container");
//创建p元素节点
var p = document.createElement("p");
//创建文本节点
var txt = document.createTextNode("这是一段文本...");
//将文本节点追加到元素节点中
p.appendChild(txt);
//将p标签设置到div中
div.appendChild(p);
console.log(p);
}
</script>
=================添加段落-方法二=================
<body>
<button onclick="addPara()">添加段落</button>
</select>
<div id="container"></div>
</body>
<script>
function addPara() {
//获取容器
var div = document.getElementById("container");
//创建p元素节点
var p = document.createElement("p");
p.innerHTML = "这是一段文本...";
console.log(p);
//将p标签设置到div中
div.appendChild(p);
}
</script>
=================添加段落-方法三=================
<body>
<button onclick="addPara()">添加段落</button>
<div id="container"></div>
</body>
<script>
function addPara() {
//获取容器
var div = document.getElementById("container");
//创建p元素节点
var p = "<p>这是一段文本...</p>";
// div.appendChild(p); p标签是字符串,而appendChild()括号内需要节点,会报错
div.innerHTML += p; //innerHTML本意是赋值,不管赋值多少次都会显示一次,所以用+=重复出现
console.log(p);
}
</script>
例2:添加图片
=================添加图片-方法一=================
<body>
<button onclick="addImg()">添加图片</button>
<div id="container"></div>
</body>
<script>
function addImg() {
//获取容器
var div = document.getElementById("container");
//创建img元素节点
var img = document.createElement("img");
//设置属性
img.src = "images/cat.jpg";
//设置宽、高属性
img.width = 100;
img.height = 120;
//将图片设置到div容器中
div.appendChild(img);
}
</script>
=================添加图片-方法二=================
<body>
<button onclick="addImg()">添加图片</button>
<div id="container"></div>
</body>
<script>
function addImg() {
//获取容器
var div = document.getElementById("container");
//创建img元素节点
var img = document.createElement("img");
//设置属性
img.setAttribute("src", "images/cat.jpg");
//设置宽、高属性
img.width = 100;
img.height = 120;
//将图片设置到div容器中
div.appendChild(img);
}
</script>
=================添加图片-方法三=================
<body>
<button onclick="addImg()">添加图片</button>
<div id="container"></div>
</body>
<script>
function addImg() {
//获取容器
var div = document.getElementById("container");
var img = "<img src = 'images/cat.jpg'>";
div.innerHTML += img;
}
</script>
例3:添加文本
=================添加文本-方法一=================
<body>
<button onclick="addTxt()">添加文本</button>
<div id="container"></div>
</body>
<script>
function addTxt() {
//获取容器
var div = document.getElementById("container");
//创建input元素
var inp = document.createElement("input");
//指定input元素的类型
inp.type = "text"; //input类型:文本框
inp.value = "今天天气不错..."; //文本框的值
//将input元素设置到容器中
div.appendChild(inp);
}
</script>
=================添加文本-方法二=================
<body>
<button onclick="addTxt()">添加文本</button>
<div id="container"></div>
</body>
<script>
function addTxt() {
//获取容器
var div = document.getElementById("container");
//创建input元素
var inp = document.createElement("input");
//设置属性
inp.setAttribute("type", "text");
inp.setAttribute("value", "今天天气不错...");
//将input元素设置到容器中
div.appendChild(inp);
}
</script>
=================添加文本-方法三=================
<body>
<button onclick="addTxt()">添加文本</button>
<div id="container"></div>
</body>
<script>
function addTxt() {
//获取容器
var div = document.getElementById("container");
//创建input元素
var inp = "<input type='text' value='hello'>";
div.innerHTML += inp;
}
</script>
例4:添加选项
=================添加选项-方法一=================
<body>
<button onclick="addOptions()">添加选项</button>
<select name="music">
<option value="0">晴天</option>
<option value="1">七里香</option>
<option value="2">爱情转移</option>
</select>
</body>
<script>
function addOptions() {
//通过name属性值获取下拉框对象
var music = document.getElementsByName("music")[0]; //因为是数组,取下标0
//创建下拉选项
var opt = document.createElement("option");
//设置文本和值
opt.value = "3";
opt.text = "青花瓷";
//给下拉框添加下拉选项
music.appendChild(opt);
console.log(music);
}
</script>
=================添加选项-方法二=================
<body>
<button onclick="addOptions()">添加选项</button>
<select name="music">
<option value="0">晴天</option>
<option value="1">七里香</option>
<option value="2">爱情转移</option>
</select>
</body>
<script>
function addOptions() {
//通过name属性值获取下拉框对象
var music = document.getElementsByName("music")[0]; //因为是数组,取下标0
//创建下拉选项
var opt = document.createElement("option");
//设置文本和值
opt.value = "3";
opt.text = "青花瓷";
//将option添加到下拉列表中
music.options.add(opt); //music.options能表示所有下拉框
}
</script>
=================添加选项-方法三=================
<body>
<button onclick="addOptions()">添加选项</button>
<select name="music">
<option value="0">晴天</option>
<option value="1">七里香</option>
<option value="2">爱情转移</option>
</select>
</body>
<script>
function addOptions() {
//通过name属性值获取下拉框对象
var music = document.getElementsByName("music")[0]; //因为是数组,取下标0
//创建下拉选项
var opt = "<option value='3'>青花瓷</option>";
music.innerHTML += opt;
}
</script>
例5:write()
<script>
document.write("<h2>你好...</h2>");
</script>
例6:insertBefore()
//在红色之前添加粉色
<body>
<ul>
<li id="red">红色</li>
<li>绿色</li>
</ul>
</body>
<script>
var li = document.createElement("li");
var txt = document.createTextNode("粉色");
li.appendChild(txt);
document
.getElementById("red")
.parentElement.insertBefore(li, document.getElementById("red"));
</script>
6.2.3 间接查找节点
方法|属性 | 描述 |
---|---|
childNodes | 返回元素的子节点的数组(包括元素节点和文本节点) |
children | 返回元素的所有子元素数组(不包括文本节点) |
firstChild | 返回元素的第一个子节点(包括元素节点和文本节点) |
lastChild | 返回元素的最后一个子节点(包括元素节点和文本节点) |
firstElementChild | 返回元素的第一个子元素节点(不包括文本节点) |
lastElementChild | 返回元素的最后一个子元素节点(不包括文本节点) |
nextSibling | 返回元素的下一个兄弟节点(包括元素节点和文本节点) |
nextElementSibling | 返回元素的下一个兄弟元素节点(不包括文本节点) |
previousSibling | 返回元素的上一个兄弟节点(包括元素节点和文本节点) |
previousElementSibling | 返回元素的上一个兄弟元素节点(不包括文本节点) |
parentNode | 返回元素的父节点(包括元素节点和文本节点) |
parentElement | 返回元素的父元素节点(不包括文本节点) |
例子:
=================childNodes、children=================
<body>
<ul>
<li id="red">红色</li>
<li>绿色</li>
</ul>
</body>
<script>
//得到ul
var ul = document.getElementsByTagName("ul")[0];
//childNodes,返回元素的子节点的数组
console.log(ul.childNodes); //5,因为把li前后的空白文本都算入了,节点
console.log(ul.children); //2,返回元素的所有子元素数组,元素
</script>
=================firstChild、lastChild=================
<body>
<ul>
<li id="red">红色</li>
<li>绿色</li>
</ul>
</body>
<script>
//得到ul
var ul = document.getElementsByTagName("ul")[0];
//firstChild,返回元素的第一个子节点
//lastChild,返回元素的最后一个子节点
console.log(ul.firstChild); //#text,前面的空白文本节点
console.log(ul.lastChild); //#text,后面的空白文本节点
</script>
=================firstElementChild、lastElementChild=================
<body>
<ul>
<li id="red">红色</li>
<li>绿色</li>
</ul>
</body>
<script>
//得到ul
var ul = document.getElementsByTagName("ul")[0];
//firstElementChild,返回元素的第一个子节点
//lastElementChild,返回元素的最后一个子节点
console.log(ul.firstElementChild); //<li id="red">红色</li>
console.log(ul.lastElementChild); //<li>绿色</li>
</script>
=================nextSibling、previousSibling=================
<body>
<ul>
<li id="red">红色</li>
<li>绿色</li>
</ul>
</body>
<script>
//得到ul
var ul = document.getElementsByTagName("ul")[0];
//nextSibling,返回元素的下一个兄弟节点
//previousSibling,返回元素的上一个兄弟节点
console.log(document.getElementById("red").nextSibling); //#text
console.log(document.getElementById("red").previousSibling); //#text
</script>
=================parentNode、parentElement=================
<body>
<ul>
<li id="red">红色</li>
<li>绿色</li>
</ul>
</body>
<script>
//得到ul
var ul = document.getElementsByTagName("ul")[0];
//parentNode,返回元素的父节点
//parentElement,返回元素的父元素节点
console.log(ul.parentNode); //<body>...</body>
console.log(ul.parentElement); //<body>...</body>
</script>
6.2.4 删除节点
方法|属性 | 描述 |
---|---|
removeChild() | 从元素中移除子节点 |
例子:
<body>
<span id="programmer">程序猿</span>
<a href="javascript:void(0)" onclick="delNode()">删除</a>
</body>
<script>
function delNode() {
//得到被删除的对象
var span = document.getElementById("programmer");
//得到被删除的对象的父元素
var parent = span.parentElement;
//删除元素
parent.removeChild(span);
}
</script>
7. 表单
表单是我们页面向后台传输数据的一种非常常见的方式,在进行数据发送(请求发出)之前,我们应该先在页面进行一系列数据合法性的验证,节省不必要的错误数据的传输,以及提高用户的体验度。
7.1 获取表单
document.表单名称; //常用
document.getElementById(表单id、name等都可以); //常用
document.forms //得到当前文档中的表单集合
document.forms[表单名称]
document.forms[索引]; //从0开始
例子:
=================方法一=================
<body>
<form id="form1" name="form1" method="get" action=""></form>
</body>
<script>
var form1 = document.form1;
console.log(form1); //<form id="form1" name="form1" method="get" action=""></form>
</script>
=================方法二=================
<body>
<form id="form1" name="form1" method="get" action=""></form>
</body>
<script>
var form1 = document.getElementById("form1");
console.log(form1); //<form id="form1" name="form1" method="get" action=""></form>
</script>
=================方法三=================
<body>
<form id="form1" name="form1" method="get" action=""></form>
<form id="form2" name="form2" method="get" action=""></form>
</body>
<script>
var forms = document.forms;
console.log(forms);//HTMLCollection(2) [form#form1, form#form2, form1: form#form1, form2: form#form2]
</script>
=================方法四=================
<body>
<form id="form1" name="form1" method="get" action=""></form>
<form id="form2" name="form2" method="get" action=""></form>
</body>
<script>
var forms = document.forms["form1"];
console.log(forms); //<form id="form1" name="form1" method="get" action=""></form>
</script>
=================方法五=================
<body>
<form id="form1" name="form1" method="get" action=""></form>
<form id="form2" name="form2" method="get" action=""></form>
</body>
<script>
var forms = document.forms[0];
console.log(forms); //<form id="form1" name="form1" method="get" action=""></form>
</script>
7.2 获取表单元素
7.2.1 获取input元素
(1)通过id获取:document.getElementById(元素id);
(2)通过form.元素名称形式获取;
(3)通过name获取:document.getElementByName[索引]; //从0开始
(4)通过tagName数组:document.getElementByTagName("input")[索引]; //从0开始
例子:
=================方法一=================
<body>
<form id="myform" name="myform" action="" method="get">
姓名:<input type="text" id="uname" name="uname" value="张三" /><br />
密码:<input type="password" id="upwd" name="upwd" value="123456" /><br />
<input type="hidden" name="uno" id="uno" value="隐藏域" />
个人说明<textarea name="intro"></textarea>
<button type="button" onclick="getTxt()">获取元素内容</button>
</form>
</body>
<script>
function getTxt() {
var uname = document.getElementById("uname").value;
console.log(uname);
}
</script>
=================方法二=================
<body>
<form id="myform1" name="myform1" action="" method="get">
姓名:<input type="text" id="uname" name="uname" value="张三" /><br />
密码:<input type="password" id="upwd" name="upwd" value="123456" /><br />
<input type="hidden" name="uno" id="uno" value="隐藏域" />
个人说明<textarea name="intro"></textarea>
<button type="button" onclick="getTxt()">获取元素内容</button>
</form>
</body>
<script>
function getTxt() {
var upwd = myform1.upwd.value;
console.log(upwd); //123456
}
</script>
=================方法三=================
<body>
<form id="myform1" name="myform1" action="" method="get">
姓名:<input type="text" id="uname" name="uname" value="张三" /><br />
密码:<input type="password" id="upwd" name="upwd" value="123456" /><br />
<input type="hidden" name="uno" id="uno" value="隐藏域" />
个人说明<textarea name="intro"></textarea>
<button type="button" onclick="getTxt()">获取元素内容</button>
</form>
</body>
<script>
function getTxt() {
var uno = document.getElementsByName("uno")[0].value;
console.log(uno); //隐藏域
}
</script>
=================方法四=================
<body>
<form id="myform1" name="myform1" action="" method="get">
姓名:<input type="text" id="uname" name="uname" value="张三" /><br />
密码:<input type="password" id="upwd" name="upwd" value="123456" /><br />
<input type="hidden" name="uno" id="uno" value="隐藏域" />
个人说明<textarea name="intro"></textarea>
<button type="button" onclick="getTxt()">获取元素内容</button>
</form>
</body>
<script>
function getTxt() {
var inpu = document.getElementsByTagName("input");
console.log(inpu);
}
</script>
7.2.2 获取单选按钮
前提:将一组单选按钮设置相同的name属性值
(1)获取单选按钮组:
document.getElementsByName("name属性值");
(2)遍历每个单选按钮,并查看单选按钮元素的checked属性。
选中状态设定:checked = "checked"或checked = "true"或checked
未选中状态设定:没有checked属性或checked = "false"
例子:
<body>
<input type="radio" name="rad" value="1" /> 1
<input type="radio" name="rad" value="2" /> 2
<button type="button" onclick="getRadio()">获取单选按钮</button>
</body>
<script>
function getRadio() {
//(1)获取单选按钮组
var radios = document.getElementsByName("rad");
//(2)遍历每个单选按钮,并查看单选按钮元素的checked属性
for (var i = 0; i < radios.length; i++) {
console.log(radios[i].checked);
//如果选中则打印值
if (radios[i].checked) {
console.log(radios[i].value);
}
}
}
</script>
7.2.3 获取多选按钮
操作方式与单选同理,不同之处在于可以多选
<body>
<input type="checkbox" name="hobby" value="sing" /> 唱歌
<input type="checkbox" name="hobby" value="dance" /> 跳舞
<input type="checkbox" name="hobby" value="rap" /> 说唱
<button type="button" onclick="getCheckbox()">获取多选按钮</button>
</body>
<script>
function getCheckbox() {
//(1)获取多选按钮组
var checkboxs = document.getElementsByName("hobby");
var str = "";
//(2)遍历每个多选按钮,并查看多选按钮元素的checked属性
for (var i = 0; i < checkboxs.length; i++) {
//如果选中则打印值
if (checkboxs[i].checked) {
str += checkboxs[i].value + ",";
}
}
//通过截取,去除最后一个多余的逗号
str = str.substring(0, str.length - 1); //截取第0位到str.length-1(不包括)之间的数
console.log(str);
}
</script>
7.2.4 获取下拉选项
(1)获取下拉框对象:
var ufrom = document.getElementById("ufrom"); //id,name,class都可以
(2)获取下拉框的所有下拉选项
var selectoptions = ufrom.options;
(3)获取下拉框被选中项的索引:
var idx = ufrom.selectIndex;
(4)获取选中项options的value属性值:
var val = ufrom.options[idx].value;
//当通过options获取选中项的value属性值时:
//若没有value属性,则取option标签的内容
//若有value属性,则取value属性的值
(5)获取选中项options的text:
var txt = ufrom.options[idx].text;
//选中状态设定:selected="selected"或selected="true"或selected
//未选中状态设定:不设selected属性
(6)设置某个下拉选项被选中:
var selectoptions = ufrom.options;
selectoptions[1].selected = true;
例子:
<body>
来自:
<select name="ufrom" id="ufrom">
<option value="0">请选择</option>
<option value="beijing" selected="selected">北京</option>
<option value="shanghai">上海</option>
<option>深圳</option>
//当未设置value值时会默认为文本值
</select>
<button type="button" id="sub">获取下拉选项</button>
</body>
<script>
document.getElementById("sub").onclick = function () {
//1.获取下拉框对象
var ufrom = document.getElementById("ufrom");
//2.获取下拉框的所有下拉选项
var selectoptions = ufrom.options;
console.log(selectoptions); //HTMLOptionsCollection(4)
//3.获取下拉框被选中项的索引
var index = ufrom.selectedIndex;
console.log(index); //索引号
//4.获取被选中项的value值
var val = selectoptions[index].value;
console.log(val); //显示value值
//或 获取当前被选中项的值
var selectvalue = ufrom.value;
console.log(selectvalue); //显示value值
//5.获取选中项的text值
var txt = selectoptions[index].text;
console.log(txt); //显示text值
//6.设置某个下拉选项被选中
selectoptions[2].selected = true; //上海
};
</script>
7.3 提交表单
(1)使用普通button按钮:
//获取表单.submit();
<body>
<form
id="myform1"
name="myform"
action="https://www.baidu.com/"
method="get"
>
姓名:<input type="text" id="uname" />
<input type="button" value="提交表单" onclick="submitForm()" />
</form>
</body>
<script>
function submitForm() {
//获取姓名文本框的值
var uname = document.getElementById("uname").value;
if (uname == null || uname.trim() == "") {
//trim():去除前后空格,不去除文本中间空格
//保证如果不输入就无法提交
return;//结束
}
//获得表单.提交表单
document.getElementById("myform1").submit();
}
</script>
(2)使用submit按钮:
//最后必须返回:return true|false;
<body>
<form id="myform1" action="https://www.baidu.com/" method="get">
姓名:<input type="text" id="uname" />
<input type="submit" value="提交表单" onclick="return submitForm()" />
<!--return后面必须跟true、false或者空(等价于false)
true会提交表单,false或空不会提交表单-->
</form>
</body>
<script>
function submitForm() {
var uname = document.getElementById("uname").value;
if (uname == null || uname.trim() == "") {
return false; //如果表单为空,则不提交表单
}
return true; //否则,提交表单
}
</script>
(3)使用submit按钮方法2:
//最后必须返回:return true|false;
<body>
<form
id="myform1"
action="https://www.baidu.com/"
method="get"
onsubmit="return submitForm()"
>
姓名:<input type="text" id="uname" />
<input type="submit" value="提交表单" onclick="return submitForm()" />
</form>
</body>
<script>
function submitForm() {
var uname = document.getElementById("uname").value;
if (uname == null || uname.trim() == "") {
return false; //如果表单为空,则不提交表单
}
return true; //否则,提交表单
}
</script>
7.4 表单校验
要求:
1.验证用户名:(1)不能为空;(2)长度为6-12位;
2.验证密码:(1)不能为空;(2)长度为6-12位;(3)不能包含用户名;
3.年龄:必须选择“你懂得”;
4.爱好:最少选择一项;
5.来自:最少选择一项;
满足以上条件:
1.弹出所有的内容;
2.提交表单
1.说明错误原因;
2.不能提交表单。
<body>
<form id="myform" name="myform">
用户名:
<input type="text" id="uname" name="uname" /><br />
密码:
<input type="password" id="upwd" name="upwd" /><br />
年龄:
<input type="radio" name="uage" value="0" />小屁孩
<input type="radio" name="uage" value="1" />你懂得<br />
爱好:
<input type="checkbox" name="ufav" value="篮球" />篮球
<input type="checkbox" name="ufav" value="爬床" />爬床
<input type="checkbox" name="ufav" value="代码" />代码 <br />
城市:
<select name="ufrom" id="ufrom">
<option value="0" selected>请选择</option>
<option value="1">北京</option>
<option value="2">上海</option>
</select>
<br />
<div id="validate" style="color: red"></div>
<button type="button" onclick="checkForm();">提交</button>
<button type="reset" onclick="resetForm();">重置</button>
</form>
</body>
<script>
//封装,获取id对象
function $(id) {
return document.getElementById(id);
}
//封装,判断字符串是否为空
//如果为空,返回true;如果不为空,返回false
function isEmpty(str) {
if (str == null || str.trim() == "") {
return true;
}
return false;
}
//==========重置功能==========
//重置表单
function resetForm() {
$("myform").reset(); //reset():重置表单
}
//==========提交功能==========
function checkForm() {
//1.验证用户名
//获取用户名
var uname = $("uname").value;
//判断用户名是否为空
if (isEmpty(uname)) {
//通过innerHTML赋值
$("validate").innerHTML = "用户名不能为空!";
return;
}
//判断用户名长度
if (uname.length < 6 || uname.length > 12) {
$("validate").innerHTML = "用户名长度在6-12位之间!";
return;
}
$("validate").innerHTML = "";
//2.验证密码
//获取密码
var upwd = $("upwd").value;
//判断密码是否为空
if (isEmpty(upwd)) {
//通过innerHTML赋值
$("validate").innerHTML = "密码不能为空!";
return;
}
//判断密码长度
if (upwd.length < 6 || upwd.length > 12) {
$("validate").innerHTML = "密码长度在6-12位之间!";
return;
}
$("validate").innerHTML = "";
//判断密码是否包含用户名
//indexOf判断upwd是否包含uname,如果包含将会返回一个>=0的值
if (upwd.indexOf(uname) >= 0) {
$("validate").innerHTML = "密码不能包含用户名!";
return;
}
$("validate").innerHTML = "";
//3.验证年龄
//获取年龄
var uages = document.getElementsByName("uage");
//判断“你懂得”单选框是否被选中
var radio2 = uages[1].checked;
if (!radio2) {
$("validate").innerHTML = "年龄必须选择你懂得!";
return;
}
$("validate").innerHTML = "";
//4.验证爱好
//获取爱好
var ufavs = document.getElementsByName("ufav");
var favs = ""; //用来存储被选中的“爱好”
//判断“爱好”多选框是否被选中
for (var i = 0; i < ufavs.length; i++) {
if (ufavs[i].checked) {
favs += ufavs[i].value + ",";
}
}
if (isEmpty(favs)) {
$("validate").innerHTML = "必须选择一项爱好!";
return;
}
//substring(m,n):返回从m位置到n位置,为了去掉favs中的空字符
favs = favs.substring(0, favs.length);
//5.验证城市
//获取下拉框
var city = $("ufrom").value;
if (city == 0) {
$("validate").innerHTML = "必须选择一个城市!";
return;
}
$("validate").innerHTML = "";
//设置表单提交的地址
$("myform").action = "https://www.baidu.com/";
//提交表单
$("myform").submit();
}
</script>