目录
- 一、javascript书写形式
- 二、标识符
- 三、数据类型(前5种是基本数据类型,最后一个是引用数据类型)
- 四、运算符(也叫操作符)
- 五、Unicode编码
- 六、语句
- 六、函数
- 七、全局作用域与函数作用域
- 八、数组
- 九、`call()`和 `apply()`方法
- 十、`Date`对象(时间)
- 十一、Math 对象
- 十二、包装类(将基本数据类型转化为对象)
- 十三、正则表达式
- 十四、DOM
- 十五、样式
- 十五、BOM
- 十六、JSON
一、javascript书写形式
1.外部引用(推荐)
若引用了外部.js文件,还想继续在html中写js,必须添加<script>
标签。
引用代码
<script type="text/javascript" src="script.js"></script>
2.写在<head>
标签内
将js代码写在<script>
标签里即可。如下:
<head>
<script type="text/javascript">
// 浏览器显示一个弹窗警告
alert("看我干嘛");
// 让计算机在页面输入内容,documen.write()可以向body输入一个内容
document.write("别瞅我");
// 向控制台输入一个内容。console.log()
console.log("听到了没有");
</script>
</head>
3. 写在<body>
标签里(不推荐)
可以将js代码写在onclick
和href
中。当点击到该标签的内容,就会执行Js代码
<body>
<button onclick="alert('我是js代码,但是要用单引号')">看吧我还是可以显示js代码</button>
<a href="javascript:alert('我还是js代码');">看链接里也能放js代码</a>
<a href="javascript:;">看我还是很常用的</a>
</body>
二、标识符
1. 定义
JS中所有可以自主命名的都可以称为标识符(例如:变量名、函数名、属性名)
2. 命名规则
- 1.标识符中可以含有数字、字母、下划线_、$
- 2.不能以数字开头
- 3.不能是ES中的关键字 和保留字
- 4.一般用驼峰命名法(首字母小写、每个单词开头大写、其余字母小写。eg:helloWorld)
三、数据类型(前5种是基本数据类型,最后一个是引用数据类型)
1.String(字符串)
- 1.需要用引号引起来(单引号
''
,双引号""
都可以) - 2.引号不能嵌套使用。除非添加转义符号
\
,下面有例子 - 3.列举一些特殊符号可以使用
\
进行转义 \"
表示"
\'
表示'
\n
表示换行\t
制表符(Tab键)\\
表示\
<head>
<script type="text/javascript">
//String字符串
var str2 = "我觉得:\"你今天真好看\"";
console.log(str2);
//可以用双引号 “”
var str3 = "今天天气真好";
console.log(str3);
//也可以用单引号‘’
var str4 = '今天天气真好';
console.log(str4);
</script>
</head>
2.Number 数值
注意事项
- 1.JS中可以表示的最大数值:
Number.MAX_VALUE
(1.7976931348623157e+308);最小数值:Number.MIN_VALUE
(5e-324) - 2.当数值超过了最大值,会返回
Infinity
(表示正无穷);小于最小值,会返回-Infinity
(表示负无穷) - 3.用运算符
typeof
检查一个变量的类型。语法:typeof 变量
- 4.由于浮点运算结果不精确,故不要用JS 写精确度要求高的运算
<head>
<script type="text/javascript">
// Number数值
var a = 1;
//加法
var b = 123 + 456;
//最大值
var c = Number.MAX_VALUE;
//最大值相乘
var d = Number.MAX_VALUE * Number.MAX_VALUE;
//最小值
var e = Number.MIN_VALUE;
//Not A Number 没有这个数值。
var f = NaN;
console.log(a);
console.log(b);
console.log(c);
console.log(d);
console.log(e);
console.log(f);
//显示某个变量的数据类型
console.log(typeof a);
</script>
</head>
3.Boolean 布尔值
- true为真
- false为假
<head>
<script type="text/javascript">
//Boolean 布尔值
var bool = true;
console.log(bool);
console.log(typeof bool);
</script>
</head>
4.Null 空值
<!DOCTYPE html>
<html lang="en">
<head>
<script type="text/javascript">
//Null 空值,其类型的值只有一个,为null
//null专门表示一个为空的对象,用typeof检查一个null值时,会返回object
var g = null;
console.log(g);
console.log(typeof g);
</script>
</head>
5.Undefined 未定义
<head>
<script type="text/javascript">
//Undefined 未定义,其类型值只有一个,就是undefined
//当声明一个变量,但不给变量赋值时,其值就是undefined。用typeof检查时,返回也是undefined
var h;
console.log(h);
</script>
</head>
6.Object 对象(引用数据类型)
6.1 定义
对象属于一种复合的数据类型,在对象中可以保存多个不同数据类型的属性。
格式(语法):
1.创建对象 | 用new 关键字调用的函数,是构造函数constructor (构造函数时专门用来创建对象的函数) 用typeof 检查一个对象时,会返回object | 语法:var obj = new 某函数 例如: var obj = new Object(); |
---|---|---|
2.向对象添加属性 | 在对象中保存的值称为属性 | 语法:对象.属性名 = 属性值 例如:obj.name = "好莱坞" |
3.读取对象中的属性 | 如果读取的对象中没有该属性,不会报错,但会返回undefined | 语法:对象.属性名 例如: console.log(obj.gender) |
6.2 对象的分类
- 1.内建对象
由ES标准中定义的对象,在任何ES的实现中都可以使用 | 例如:Math对象、String对象、Number对象、Boolean对象、Function对象、Object对象、Date对象、Array对象、RegExp对象 |
---|
- 2.宿主对象
由JS的运行环境提供的对象,目前来讲主要指由浏览器提供的对象 | 比如DOM、BOM |
---|
- 3.自定义对象
由开发人员自己定义 |
---|
6.3 对象的属性名和属性值
1.对象属性名不强制要求遵守标识符的规范,啥奇怪的名都可以。但尽量按标识符标准去用 | var obj = new Object(); obj.name = "liuliu"; console.log(obj.name); |
---|---|
2.如果需要使用特殊属性名,要用这种方式: 语法:对象[“属性名”] = 属性值; 读取也是这种方式 | var obj1 = new Object(); obj1["111"] = "哈哈哈哈"; console.log(obj1["111"]); |
3.属性值可以是任何数据类型,包括对象 | obj.test = true; obj.test = null; obj.test = undefined; console.log(obj.test); //结果分别为:true null undefined |
// 属性值为对象 //将obj2设置为obj的属性 var obj2 = new Object(); obj2.name = "小猪佩奇"; obj.test = obj2; console.log(obj.test); //{name: '小猪佩奇'} console.log(obj.test.name); //小猪佩奇 | |
4.当比较两个基本数据类型 时,比较的是值 。比较两个引用数据类型 时,比较的是对象的内存地址 ,即便两个对象是一样的,但地址不同,结果也就为false | var a = 2; var b = 2; console.log(a == b); //true,当比较两个基本数据类型时,比较的是值。 var obj3 = new Object(); var obj4 = new Object(); obj3.name = "小明"; obj4.name = "小明";console.log(obj3 == obj4); //false 当比较两个引用数据类型时 |
5. in 运算符 :通过运算符可以检查一个对象是否有指定的属性,有 则返回true ,无 则返回false 语法: "属性名" in 对象 | console.log("age" in obj); |
6.使用[] 这种形式去操作属性,更加灵活。在[]中可以直接传递一个变量 ,这样变量值是多少就会读取那个属性 | var n = "name";console.log(obj[n]); //结果为liuliu |
7. 字面量的定义 语法: {属性名:属性值,属性名:属性值...} 即在创建变量时,直接定义对象中的属性。对象中的属性名可以不加“”,如:"name":"nan",``建议不加 。但若是特殊字符 ,则必须加 。如"@#¥": 00; | var obj = { name: "小明" }; console.log(obj); var obj2 = { name: "nan", gender: "男", age: 30, test: { name: "yinyin" }} console.log(obj2); |
6.4 使用工厂方法创建对象
- 工厂方法创建对象:可大批量创建对象,即把对象和属性都封装起来。只需要传值进来就可以。
- 缺点:使用工厂方法创建的对象都是Object类型的(因为使用的都是Object的构造函数),导致无法区分多种不同类型的对象。(解决方法,使用不同的构造函数。)
<script type="text/javascript">
// 工厂方法创建对象(可大批量创建对象),即把对象和属性都封装起来。只需要传值进来就可以。
function fun(name, age, gender) {
//创建对象
var obj = new Object();
//给对象赋值
obj.name = name;
obj.age = age;
obj.gender = gender;
obj.sayName = function () {
alert(this.name);
}
// 返回新的obj对象
return obj;
}
var obj1 = fun("小明", 28, "男");
var obj2 = fun("小花", 29, "女");
console.log(obj1);
console.log(obj2);
// obj1.sayName();
</script>
6.5 构造函数
6.5.1 构造函数的定义
构造函数
:创建方式其实和普通函数没什么区别,但是函数名首字母
习惯要大写
。
- 构造函数和普通函数的区别是:调用方式不同
普通函数
是直接调用
,构造函数
要使用new
关键字 来调用
6.5.2 构造函数的执行流程
- 1.立刻
创建一个新的对象
- 2.将
新建的对象
设置为函数中this
,在构造函数中可以使用this来引用新建的对象(和其他函数最主要的区别
) - 3.逐行执行函数中的代码
- 4.将新建的对象作为
返回值
返回
6.5.3 类和实例
- 1.使用同一个构造函数创建的对象,称为
一类对象
,也将一个构造函数称为一个类
,将通过一个构造函数的对象,称为该类的实例
- 2.使用
instanceof
来检查一个对象是否是一个类的实例
语法: 对象 instanceof 构造函数
如果是
返回true
,否
则返false
- 3.
所有对象
都是Object的后代
,所有对象
和Object
作instanceof
比较都会返回true
。
6.5.4 this情况
- 1.当以
函数
的形式调用时,this
是window
- 2.当以
方法
的形式调用时,谁调用方法
,this就是谁
- 3.当以
构造函数
的形式调用时,this
就是创建的那个对象
6.5.5 构造函数中创建方法问题
- 问题:每调用一次函数就会调用这个方法,会浪费空间和影响性能。(即这个所有实例都是唯一的,每次执行构造函数都会调用到它)
- 解决方法:于是把方法提取出来,让它只调用一次。
即在全局作用域中定义此方法
。但是这样污染了全局作用域的命名空间
,并且定义在全局作用域中也不安全
(解决方法是原型对象
)
<script type="text/javascript">
function Person(name, age, gender) {
this.name = name; //用this来引用新建的对象
this.age = age;
this.gender = gender;
this.sayName = sayName1;
// 创建一个方法
// this.sayName = function () { //每调用一次函数就会调用这个方法,会浪费空间和影响性能。
// alert(this.name); //即这个所有实例都是唯一的,每次执行构造函数都会调用到它。
// }
}
// 即在全局作用域中定义此方法
function sayName1() {
alert(this.name);
}
var per = new Person("小米", 14, "女"); //per是Person类的实例。
var per1 = new Person("小红", 15, "女");
console.log(per);
per.sayName(); //调用sayName方法
// 使用instanceof来检查一个对象是否是一个类的实例
console.log(per instanceof Person); //true
console.log(per instanceof Object);
//true 所有对象都是Object的后代,所有对象和Object作instanceof比较都会返回true。
</script>
6.5.6 原型对象的解决方法
<script type="text/javascript">
// 原型对象的解决方法 注意直接调用这个原型对象即可,
//构造函数里的this.sayName = sayName1;不用再定义了。
Person.prototype.sayName = function () {
alert(this.name);
};
</script>
6.6 原型对象
6.6.1 定义
- 原型
prototype
- 创建的
每一个函数
,解析器都会向函数中添加一个属性prototype
,其对应着一个对象
。这个对象就是原型对象
。
6.6.2 用法
- 原型对象相当于一个
公共区域
,所有同一个类的实例
都可以访问到这个原型对象(即可以把对象中共有的内容添加到原型对象中
) - 当
访问对象
的一个属性或方法
时,会先
在对象自身
寻找,有则直接用,没
有则再去原型对象
中找,找到直接用。 - 在创建构造函数时,如果对象有公共属性和方法,统一添加到原型对象中。即既不用分别给每个对象添加,也不影响全局作用域。
6.6.3 原理
- 若函数
作为普通函数调用
,其prototype``没
有任何作用
- 若函数
作为构造函数调用
,其创建的对象中都
有一个隐含的属性
,指向该构造函数的
原型对象,可以通过__prototype__
来访问
该属性
<script type="text/javascript">。
function Mytime() {
}
var one = new Mytime();
console.log(Mytime.prototype); //{constructor: ƒ}说明存在原型对象。(每一个函数和对象都有原型对象)
console.log(one.__proto__ == Mytime.prototype); //true 构造函数,下他们是属于同一个对象。
console.log(one.__proto__);
</script>
6.6.4 检查属性是否在对象/原型对象中
- 使用
in
检查对象中是否含有某个属性时,如果对象中没有
但是原型中有,也会返回true
。(不靠谱) - 所以
对象
的hasOwnProterty()
来检查对象自身中是否有该属性
,使用该方法只有当对象自身中有
该属性时才会返回true
- 原型对象也是对象,所以它也有原型(一般总共就2级)
- 当使用一个对象的属性或方法时,会在自身中找,自身有,则直接用, 自身没有则去原型对象找,有则用,没有再去原型的原型对象找,直到找到
Object对象的原型
。Object对象的原型没有原型
,若在Object中也没找到,会返回undefined
<script type="text/javascript">
// 向Mytime 的原型中添加一个name属性
Mytime.prototype.name = "我是原型中的name";
console.log(one.name); //我是原型中的name
// 使用in检查对象中是否含有某个属性时,如果对象中没有但是原型中有,也会返回true。
console.log("name" in one); //true
console.log(one.hasOwnProperty("name")); //false即name属性不在one对象中
console.log(one.__proto__.hasOwnProperty("name")); //true 即name属性是在one的原型对象中的属性
console.log(one.__proto__.hasOwnProperty("hasOwnProperty"));
//false,hasOwnProperty不在原型对象中
console.log(one.__proto__.__proto__.hasOwnProperty("hasOwnProperty"));
//true,hasOwnProperty在原型对象的原型对象中
</script>
6.7 toString()方法:修改对象输出的形式
- 当
直接
在页面打印对象,输出的是对象的toString()
方法的返回值
,若不
想输出的是[object Object]
时,可以给对象
添加一个toString()方法
- 语法
类名.prototype.toString = function () { }
<script type="text/javascript">
function Person(name, age) {
this.name = name;
this.age = age;
}
// 创建一个实例
var per = new Person("小红", 29);
console.log(per); //结果为Person {name: '小红', age: 29},为啥是这样。原理:
// 当直接在页面打印对象,输出的是对象的toString()方法的返回值
// 若不想输出的是[object Object]时,可以给对象添加一个toString()方法
// per.toString = function () { //这样的方式太局限。修改成可以调用的带参形式。
// return "傻啊";
// }
// 修改Person原型的toString
Person.prototype.toString = function () {
return "[name =" + this.name + ",age = " + this.age + "]";
}
var result = per.toString();
console.log("result = " + result);
</script>
6.8 垃圾回收
- 若一个对象
没有任何的变量或属性对他进行引用
,将永远无法操作该对象。此时的对象是垃圾,要对其进行设置null
,才能让JS自动垃圾回收
机制启动,从内存中销毁。
<script type="text/javascript">
// 创建一个对象
var obj = new Object();
// 不再适用对象时,设置为null。系统会自动把他清理掉(垃圾回收)
obj = null;
</script>
7.强制类型转换
7.1 强制类型转换-String
注意:
方法一:
- 1.调用被转换数据类型的
参数.toString()
方法 - 2.该方法不会影响到原变量,会将转换的结果返回
- 3.但是:
null
和undefined
两个值没有toString()
方法,调用则会报错
方法二: - 1.调用
String(参数)
函数,并将被转换的数据作为参数传递给函数 -
- 使用
String()
函数做强调类型转换时
①对Number
和Boolean
实际上就是调用toString()
方法
②对null
和undefined
就是直接把他们转化为字符串“null”
和“undefined”
。
- 使用
<head>
<script type="text/javascript">
//方法一:调用 参数.toString() 方法,不能用null和undefined,会报错
var a = "abc";
a = a.toString(); //强制转化为String(本身就是String),结果为abc
var b = 123;
b = b.toString(); //强制转化为String,结果为123
var c = true;
c = c.toString(); //强制转化为String,结果为true
//方法二:调用 String(参数) 函数
/// 对Number和Boolean实际就是调用,toString()方法;
// 对null和undefined就是直接把他们转化为字符串。
var d = null;
d = String(d); //强制转化为String,结果为null
var e = undefined;
e = String(e); //强制转化为String,结果为undefined
console.log(a);
console.log(typeof a);
console.log(b);
console.log(typeof b);
console.log(c);
console.log(typeof c);
console.log(d);
console.log(typeof d);
console.log(e);
console.log(typeof e);
</script>
</head>
7.2 强制类型转换-Number
通过**Number()**函数,强制转换数据类型
转化方式一:
- 字符串 --> 数字
1.纯数字
字符串,则直接转为数字
2.字符串中有非数字
内容,则转为NaN
3.字符串是一个空串
或全为空格的
,则直接转为0
- 布尔 --> 数字
1.true
转成 1
2.false
转成 0
- null --> 数字 0
- undefined --> 数字NaN
转化方式二:
- 只针对字符串。(只转化第一个字符前所带的数值,若是第一个字符就是字母,则结果还是为NaN)
- parseInt()和 parseFloat()
<head>
<script type="text/javascript">
var a = "abdc";
a = Number(a); //强制转化为number,结果为NaN
var b = 123;
b = Number(b); //强制转化为number(本身就是number),结果为123
var c = "2b4k.5";
//下面这两个函数只转化第一个字符前所带的数值,若是第一个字符就是字母,则结果还是为NaN
g = parseInt(c); //专门用来强制转化带数字的字符串,parseInt()把一个字符串转换为一个整数
h = parseFloat(c); //专门用来强制转化带数字的字符串,parseFloat()把一个字符串转换为一个浮点数
c = Number(c);
var d = null;
d = Number(d); //强制转化为number,结果为0
var e = undefined;
e = Number(e); //强制转化为number,结果为NaN
var f = true;
f = Number(f); //强制转化为number,结果为1
console.log(a);
console.log(typeof a);
console.log(b);
console.log(typeof b);
console.log(c);
console.log(typeof c);
console.log(g);
console.log(typeof g);
console.log(h);
console.log(typeof h);
console.log(d);
console.log(typeof d);
console.log(e);
console.log(typeof e);
console.log(f);
console.log(typeof f);
</script>
7.3 强制类型转换-Boolean
其他数据类型转换为Boolean
,用Boolean()
函数
方式一:
- 数字 —> 布尔
①除了0
和NaN
,其余的都是true
- 字符串 —> 布尔
① 除了空串
,其余的都是true
null
和undefined
都会转换为false
对象
也会转换为true
方式二:(隐式转换)
通过非运算转换为布尔值。
var a = "yes" //String类型
a = !!a //结果为true,Boolean类型
方式一例子:
<head>
<script type="text/javascript">
//其他数据类型转换为Boolean,用Boolean()函数
var a = 123;
var b = "";
var c = "正确";
var d = Infinity;
var e = null;
var f = undefined;
a = Boolean(a);
b = Boolean(b);
c = Boolean(c);
d = Boolean(d);
e = Boolean(e);
f = Boolean(f);
console.log(a); //结果为true
console.log(typeof a);
console.log(b); //结果为false
console.log(typeof b);
console.log(c); //结果为true
console.log(typeof c);
console.log(d); //结果为true
console.log(typeof d);
console.log(e); //结果为false
console.log(typeof e);
console.log(f); //结果为false
console.log(typeof f);
</script>
</head>
8.其他进制数
十六进制
以0x
开头八进制
以0
开头,有些浏览器会把0
开头的当成八进制
,有的还是当成十进制
。为避免这种情况,可以直接定义要生成的数字praseInt(参数,进制);
二进制
,有些浏览器不兼容。以0b
开头。
<head>
<script type="text/javascript">
//十六进制以 0x 开头
var a = 0xdbfe;
var b = 0x0200;
//八进制以 0 开头,有些浏览器会把 0 开头的当成八进制,有的还是当成十进制。
var c = 010;
// 为避免这种情况,可以直接定义要生成的数字 praseInt(参数,进制);
var e = parseInt(c, 10);
//二进制,有些浏览器不兼容。以 0b 开头。
var d = 0b10;
console.log(a);
console.log(typeof a);
console.log(b);
console.log(typeof b);
console.log(c);
console.log(typeof c);
console.log(d);
console.log(typeof d);
console.log(e);
console.log(typeof e);
</script>
</head>
四、运算符(也叫操作符)
运算符不会改变原变量。除非运算后赋值给原变量。
其中,typeof
是运算符,可以获得一个值的类型,typeof 某参数
是一个字符串
类型。但返回的参数依然是参数具体的数据类型。
1、算数运算符
当对非Number
类型的值进行运算时,会将这些值转换为Number
,任何和NaN
做运算的结果都是NaN
+
加法
<head>
<script type="text/javascript">
var a = 3;
a = a + 5;
console.log(a);
console.log(typeof a); //返回的是a 的数据类型,为number
console.log(typeof typeof a); //typeof a是一个字符串
var b = 9;
b = b + true;
console.log(b); //结果为10,true自动被转换为Number 1.
console.log(typeof b);
var c = 9;
c = c + undefined;
console.log(c); //结果为NaN,undefined自动被转换为Number NaN,任何和NaN做运算的结果都是NaN
console.log(typeof c);
var d = 9;
d = d + "456"; //所以也可以通过这个形式,转换为String类型。
console.log(d); //结果为9456,和字符串相加,结果返回的还是字符串,是直接拼接的结果。即拼串
console.log(typeof d);
</script>
</head>
-
减法
<head>
<script type="text/javascript">
var a = 4;
a = a - "1"; //结果为3.
console.log(a);
console.log(typeof a);
</script>
</head>
*
乘法
<head>
<script type="text/javascript">
var b = 5;
b = b * true;
console.log(b); //结果为5
</script>
</head>
/
除法
<head>
<script type="text/javascript">
var c = 5;
c = c / true;
console.log(c); //结果为5
</script>
</head>
%
取模
<head>
<script type="text/javascript">
var d = 8;
d = d % 3;
console.log(d); //结果为5
</script>
</head>
2、一元运算符(只有一个操作数)
所以非Number
值,都可以通过+
、-
来实现转换为Number
数据类型。
①+
正号
<head>
<script type="text/javascript">
var a = true;
a = +a; //结果为1
a = -a; //结果为-1
console.log(a);
var b = 4;
// b = b + "1" + 3; //结果为 413
b = b + +"1" + 3; //结果为 8
console.log(b);
</script>
②-
负号
同上。
3.自增和自减
①自增(++)
- 自增可以使变量在原变量基础上+1
- 类别:
前++
(++a
)后++
(a++
),都会立即使原变量+1 ++a
的值是变量的新值 (自增后的值)a++
的值是变量的原值 (自增前的值)
<head>
<title>运算符</title>
<script type="text/javascript">
//自增
var a = 5;
// a++; // 自增 + 1,此时a++为5, a为6.
// console.log("a = " + a); //结果为6
// console.log("a++ = " + a++); //结果为5
// console.log("++a = " + ++a); //结果为6
a = ++a + a++ + a;
console.log("a = " + a); //结果为19(6 + 6 + 7)
</script>
</head>
②自减(–)
- 自减可以使变量在原变量基础上+1
- 类别:
前--
(--a
)后--
(a--
),都会立即使原变量+1 --a
的值是变量的新值 (自减后的值)a--
的值是变量的原值 (自减前的值)
<head>
<script type="text/javascript">
//自减
var a = 5;
// a--; // 自减 + 1,此时a--为5, a为4.
// console.log("a = " + a); //结果为4
// console.log("a-- = " + a--); //结果为5
// console.log("--a = " + --a); //结果为4
// a = --a + a-- + a;
// console.log("a = " + a); //结果为19(4 + 4 + 11)
a = a--;
console.log("a = " + a); //虽然a--为5,执行a--后a为4,但是直接将a--赋值给a,则此时a=5
</script>
</head>
3.逻辑运算符
1. 非运算符: !
非
特点:
- 1.对一个值进行非运算(取反)
- 2.两次
!!
结果为原值。 - 3.对非布尔值进行运算,先转为布尔值,再取反(可以用此方法进行隐式数据类型的转换。原理通Boolean()函数一样)
2.与运算符: &&
与
特点:
- 对符号两侧的值进行
与运算
并返回结果
布尔值规则: - 1.两个值只要有一个为
false
,就返回false
,只有两个都为true
时,才返回true
- 2、JS中的
与运算
属于短路
的与
,如果第一个值为false,就不会看第二个值
**非布尔值规则:**先转换为布尔值,再运算,并返回原值。 - 1.如果第一个值为
true
,必然返回第二个值 - 2.如果第一个值为
false
,则直接返回第一个值。
<script type="text/javascript">
// && 与运算
var b;
//非布尔值运算情况
// b = "" && "hello"; //空串为false,故结果为空串。
// b = 0 && 3; //0 为false,直接返回第一个值,结果为0
// b = 3 && 0; //3为true,直接返回第二个值0
// b = 8 && 3; //8为true,直接返回第二个值3
// 布尔值运算情况
// b = true && false; //只有两个值全为true,结果才是true。
// b = false && true;
// b = false && false;
b = true && true;
console.log("b = " + b);
</script>
3.或运算符: ||
或
特点:
- 对符号两侧的值进行
或运算
并返回结果
规则: - 1.两个值只要有一个为
true
,就返回true
,只有两个都为false
时,才返回false
- 2、JS中的
或运算
属于短路
的或
,如果第一个值为true,就不会看第二个值
**非布尔值规则:**先转换为布尔值,再运算,并返回原值。 - 1.如果第一个值为
true
,必然返回第一个值 - 2.如果第一个值为
false
,则直接返回第二个值。
<script type="text/javascript">
//或运算
// 非布尔值情况
var c;
// c = 0 || 5; // 当第一个值为false,直接返回第二个值,结果为5
// c = 0 || NaN; //结果为NaN
// c = "" || "HELLO"; //结果为HELLO
// c = "yes" || "no"; //当第一个值为true,直接返回第一个值 yes
// c = 5 || 0; //结果为5
// 布尔值情况
// c = false || false; //当两个值全为false,结果为false
// c = false || true; //当有一个值为true,结果为true
// c = true || false; //结果为true
c = true || true; //结果为true
console.log("c = " + c);
</script>
4.赋值运算符
=
+=
-=
*=
/=
%=
<script type="text/javascript">
// 赋值运算符
var a = 9;
// a += 5;
// a -= 5;
// a *= 5;
// a /= 3;
a %= 5;
console.log("a = " + a);
</script>
5.关系运算符
规则:比较结果正确为true,错误为false
>
>=
<
<=
- 非数值情况:先转换为数值,再比较。
①任何值和NaN做比较都是错的。
②如果符号两边
都是字符串
,不会
转换为数字,而是
直接比较其对应的Unicode编码
③比较编码是一位一位进行比较的。基本以第一位的比较结果为准
<script type="text/javascript">
// 关系运算符
var b;
// b = 3 > 4; //false
// b = 0 < -1; //false
// b = 0 > -1; //true
// b = 4 <= 4; //true
// b = 5 >= 3; //true
// b = 1 > true; //false 对非数值,先转为数值再比较,true认为是1
// b = 1 >= true; //true
// b = NaN > 1; //false 任何值与NaN比较,结果都为false
// b = 1 > "hello"; //false。hello转换为数值为NaN.
// b = "22" < "5"; //true,两边都是字符串时,会直接按Unicode编码比较,且按第一个值对比,若有结果则以其为准,若无再进行下一位比较。
// b = "22" < +"5"; //false,两边都是字符串且都为数值时,为结果避免出错,需要对其进行数据转换,可用“+"正号转换。
// b = "abc" > "b"; //false 编码中,a<b
b = "abc" < "b"; //true 编码中,a<b
console.log("b = " + b);
</script>
6.相等运算符:
6.1 ==
相等和!=
不相等
规则
- 在判断时,若是两个值类型不同,会先自动转换为相同数据类型(没有规定转换为哪种类型),再进行比较。
NaN
与任何值(包括它本身)都不想等undefined
是null
衍生出来的,所以他们相等
<script type="text/javascript">
// 相等 ==
console.log(5 == 6); //false
console.log(5 == 5); //true
console.log("1" == 1); //true,当数据类型不同,会自动转换为相同的数据类型。
console.log("hello" == "2"); //false
console.log(true == 1); //true,当数据类型不同,会自动转换为相同的数据类型。
console.log(NaN == null); //false,任何值与NaN比较都不相等(包括它本身)。所以结果都为false
console.log(null == 0); //false,并没有将null转换为Number
console.log(null == undefined); //true, undefined是null衍生出来的。
// 不相等 !=
console.log(5 != 6); //true
console.log(5 != 5); //false
console.log("1" != 1); //fasle,当数据类型不同,会自动转换为相同的数据类型。
console.log("hello" != "2"); //true
console.log(true != 1); //fasle,当数据类型不同,会自动转换为相同的数据类型。
console.log(NaN != null); //true,任何值与NaN比较都不相等(包括它本身)。所以结果都为true
console.log(null != 0); //true,并没有将null转换为Number
console.log(null != undefined); //fasle, undefined是null衍生出来的。
</script>
6.2 ===
全等和!==
不全等
===
全等:判断两个值是否全等,类似相等,但不会自动进行数据类型转换(即当数据类型不同
时,全等
结果为false
)
<script type="text/javascript">
//全等 ===
console.log(5 === 6); //false
console.log(5 === 5); //true
console.log("1" === 1); //false,当数据类型不同,不会自动转换数据类型,直接为false
console.log("hello" === "2"); //false
console.log(true === 1); //false,当数据类型不同,直接为false
console.log(NaN === null); //false,任何值与NaN比较都不相等(包括它本身)。所以结果都为false
console.log(null === 0); //false,并没有将null转换为Number
console.log(null === undefined); //false,当数据类型不同,直接为false
</script>
!==
不全等:判断两个值是否不全等,类似不相等,但不会自动进行数据类型转换(即当数据类型不同
时,不全等
结果为true
)
<script type="text/javascript">
//不全等 !==
console.log(5 !== 6); //true
console.log(5 !== 5); //false
console.log("1" !== 1); //true,当数据类型不同,不会自动转换为相同的数据类型,直接为false。
console.log("hello" !== "2"); //true
console.log(true !== 1); //true,,当数据类型不同,直接为false。
console.log(NaN !== null); //true,任何值与NaN比较都不相等(包括它本身)。所以结果都为true
console.log(null !== 0); //true,并没有将null转换为Number
console.log(null !== undefined); //true, ,当数据类型不同,不会自动转换为相同的数据类型,直接为false。
</script>
7.条件运算符: (三目运算符)
isNaN(value)判断value是否为非数值,是非数值为true,不是为false
<script type="text/javascript">
var a = 10;
var b = 20;
var c = 40;
var max = a > b ? a : b;
var max = a > b ? (a > c ? a : c) : (b > c ? b : c); //不推荐用这种方法
// 推荐下面这种(3个或3个以上的值比较时)
var max = a > b ? a : b;
var max = max > c ? max : c;
//非布尔值也会自动转换为布尔值。
console.log("" ? "正确" : "错误");
console.log("max = " + max);
</script>
8.运算符的优先级
优先级如图,但是不需要记忆,若是遇到不清楚的优先级,添加括号即可。
<script type="text/javascript">
//运算符优先级
var d = (1 || 3) && 5; //当不知道哪个优先级高,加括号即可,此时结果为5
// var d = 1 || 3 && 5; //&& 优先级高,则先3&&5 --> 5,再进行 1||5 --> 1.结果为1
console.log("d = " + d);
</script>
五、Unicode编码
<head>
<script type="text/javascript">
// 在JS 中使用Unicode编码,用\u四位编码
console.log("\u2620");
</script>
</head>
<body>
<!-- 在网页中用Unicode编码。&#编码,这里的编码是十进制 -->
<h1>☠</h1>
</body>
六、语句
1.分类
- if条件语句 语法:
if(条件表达式){ }
- 条件分支语句 语法:
switch(条件表达式){ case 名称:语句;break;default:语句;}
- while循环语句 语法:
while(条件表达式){ }
- do…while循环语句 语法:
do{语句; }while(条件表达式)
- for循环语句 语法:
for(初始化变量;条件表达式;更新表达式){ }
2.break
和continue
- 相同点: 都可用于循环语句,且一般默认退出距离最近的当前循环;
且都可以用label标签退出标签下的所有循环
- 不同点:
break
还可以用于switch
语句。
<script type="text/javascript">
// break关键字可以退出switch或循环语句
// 不能在语句中使用break和continue
// break关键字,可以立即终止离他最近的那个循环
// 可以为循环语句创建一个label,来标识当前的循环
// label: 循环语句
// 使用break语句时,可以在break后跟着一个label,这个时候退出的是整个循环而不是最近的循环
// outer: //定义一个label
// for (var i = 1; i < 10; i++) {
// for (var j = 1; j < 10; j++) {
// document.write("@lalal " + i + "<br/>");
// // break; //此时只是退出内层循环。
// break outer; //引用label,也就是执行break语句时,直接退出label下的所有循环语句,即退出outer下的循环语句。
// }
// document.write("la " + i + "<br/>");
// }
// for (var i = 1; i < 10; i++) {
// for (var j = 1; j < 10; j++) {
// if (j == 2) {
// break; //此时退出的时内层循环
// }
// document.write("@lalal " + j + "<br/>");
// // break; //此时只是退出内层循环。
// }
// document.write("la " + i + "<br/>");
// }
// continue关键字可以用来跳过档次循环,默认退出离他最近的循环。
// continue关键字用在for、while、do-while等循环体中, 常与if条件语句一起使用, 用来加速循环。
one:
for (var i = 1; i < 10; i++) {
for (var j = 1; j < 10; j++) {
// if (j == 2) {
// continue; //此时退出的是这一次的循环,也就是跳过j==2的循环。继续j==3等语句(继续j++、j<10)。
// }
// continue; //跳出本次循环,这里也即跳出整个内层for循环
continue one;// 也可以跟break一样,跳出标签下的整个循环。
document.write("@lalal " + j + "<br/>");
}
document.write("la " + i + "<br/>");
}
</script>
六、函数
1.函数的创建(有3种)
- 1.创建一个函数对象
- 2.创建一个函数表达式
- 3.创建一个
函数声明
(常用!!!)
<script type="text/javascript">
// 函数的创建有三种形式
// 1、用构造函数 创建一个函数对象 ,少用
//可以将要封装的代码以字符串的形式传递给构造函数
var fun = new Function("console.log('这是用构造函数创建的一个函数对象');");
fun(); // 调用函数
//2.使用 函数表达式 来创建一个函数 语句:function([参数1,参数2...参数N]){ }
// 将匿名函数function(){}赋值给fun1这个变量。
var fun1 = function (name, age) { //函数定义的时候,一般用的是形参。
console.log("我是" + name + ",我今年" + age + "岁了");
}
// 调用函数
fun1("la", 15); //调用函数时,用的是实参(实参可以是任何数据类型,包括对象和函数)
//调用函数时,解析器不会检查实参的数量,多余的实参不会被赋值,当实参数量少于形参的时候,少的那个形参将是undefined
// 3.常用:函数声明 来创建一个函数 语句:function 函数名([参数1,参数2...参数N]){ }
function fun2() {
console.log("我是用函数声明的方式创建的函数");
}
fun2(); // 调用函数
console.log(fun2); //直接显示整个fun2()函数的内容
</script>
2.实参和返回值
实参和返回值
都可以是任何数据类型
,包括对象和函数
- 1.
return;
和return alert();
结果都是undefined
- 2.调用函数时,解析器不会检查实参的数量,
多余
的实参``不会被赋值
,当实参数量少于形参
的时候,少的
那个形参` - 将是undefined`
<script type="text/javascript">
//返回值
// 返回值可以是任何数据类型(包括对象和函数),return;和return alert();结果都是undefined
function fun3(a, b) {
var sum = a + b;
return sum;
}
console.log(fun3(3, 5)); //返回的是8。
//实参
//调用函数时,用的是实参(实参可以是任何数据类型,包括对象和函数)
//调用函数时,解析器不会检查实参的数量,多余的实参不会被赋值,当实参数量少于形参的时候,少的那个形参将是undefined
function square(r) { //形参
console.log("square =" + 3.14 * r * r);
}
square(10); //调用square函数且传10 这个实参给函数。
//函数作为实参
function f1(a) { //此时a = function square(r) {.log("square =" + 3.14 * r * r);}
// console.log(a);
a(10); //也即 a=square(r){} 即(r=10)
}
f1(square); //调用square函数名,即调用整个函数块。
</script>
3.立即执行函数
<script type="text/javascript">
// 立即执行函数,只会执行一次,执行后就销毁。 直接把匿名函数作为函数名即可
(function (a, b) {
console.log("a = " + a);
console.log("b = " + b);
})(3, 5);
</script>
4. 方法
定义:如果一个函数作为一个对象的属性保存,那么称这个函数是这个对象的方法,调用函数就说是调用对象的方法(即属性值是函数=方法
)
<script type="text/javascript">
var obj = new Object(); //创建一个对象
obj.name = "小明"; //向对象中添加属性值
obj.age = 18;
// 对象的属性值可以是任何数据类型,也可以是函数
//下面说明函数也可以是属性值。
// 如果一个函数作为一个对象的属性保存,那么称这个函数是这个对象的方法,调用函数就说是调用对象的方法
obj.sayName = function () { //函数作为对象的属性值
console.log(obj.name);
};
// 调用对象的方法
obj.sayName();
// 字面量定义对象(与上面的一样,只是换了创建对象的方式)
var obj1 = {
name: "下下",
age: 80,
sayName: function () {
console.log(obj1.name);
}
}
obj1.sayName();
</script>
4.2枚举方式
语法:for(var 变量 in 对象){ }
<script type="text/javascript">
// 枚举对象中的属性
// 语法:for(var 变量 in 对象){ }
// for ...in 语句 对象中有几个属性,循环体就会执行几次。每次执行,会将对象中的一个属性名赋值给变量
for (var n in obj1) {
console.log("属性名:" + n); //显示对象的每一个属性名
console.log("属性值:" + obj1[n]); //因为n是变量,不能直接用obj.n来打印属性值。
}
</script>
七、全局作用域与函数作用域
1. 全局作用域
- 全局作用域在页面打开时创建,在页面关闭时销毁
- 在全局作用域中有一个
全局对象window
。代表的是一个浏览器的窗口,由浏览器创建我们可以直接使用 - 在
全局作用域
中,创建的变量
都会作为window对象
的属性
保存 创建的函数
都会作为window对象
的方法
保存
变量的声明提前
- 使用var关键字声明的变量,会在所有代码执行之前被声明(但不会被赋值)(不报错,返回undefined)
- 若是不使用var关键字声明变量,则变量不会被声明提前。(报错)
<script type="text/javascript">
// 全局作用域在页面打开时创建,在页面关闭时销毁
// 在全局作用域中有一个全局对象window。代表的是一个浏览器的窗口,由浏览器创建我们可以直接使用
// 在全局作用域中,创建的 变量 都会作为window对象的 属性 保存 创建的 函数 都会作为window对象的 方法 保存
var a = 20;
var b = 2;
var c = 13;
console.log("a = " + a);
console.log("c = " + window.c);
// 变量的声明提前
// - 使用var关键字声明的变量,会在所有代码执行之前被声明(但不会被赋值)(不报错,返回undefined)
// 若是不使用var关键字声明变量,则变量不会被声明提前。(报错)
console.log("d = " + d); //结果为undefined。相当于在上一行有一个,var d; 在下一行有d = 60;所以d存在,但是未定义
var d = 60;
// console.log("d = " + d); //报错。
// d = 50;
// 函数的声明提前
// 用 函数声明形式 创建的函数 function 函数(){ },会在所有代码执行前被创建,即可以在函数声明前来调用函数
// 使用 函数表达式 创建的函数,不会被声明提前,所以不能在声明前调用(会报错)
fun(); //结果为:我是fun函数 与变量声明提前同理
function fun() {
console.log("我是fun函数");
}
// fun1(); //报错。(函数表达式) 函数没有提前被声明,所以调用不了。出错
// var fun1 = function () {
// console.log("我是fun1函数");
// }
</script>
2.函数作用域
- 1.在
函数作用域中
也有声明提前的特性
。(相当于函数就是一个小的全局作用域) -
- var关键字声明的变量,会在函数中所有代码被执行之前被声明
-
- 函数声明也会在函数中所有的代码执行之前执行
- 2.调用函数创建的函数作用域,函数执行完之后,函数作用域销毁
- 3.每调用一次函数就会去创建一个新的函数作用域,他们之间是互相独立的
- 4.在
函数作用域中操作一个变量时
,会先在自身作用域中寻找,有就直接用,没有就向上一级作用域寻找,直到在全局作用域中寻找,全局也没找到就报错(就近原则
) - 5.在函数中要
访问全局变量
可以使用window对象
- 在函数中,
没有用var 定义
的变量
都是全局变量
。
<script type="text/javascript">
// 函数作用域
// 1.在函数作用域中也有声明提前的特性。(相当于函数就是一个小的全局作用域)
// - var关键字声明的变量,会在函数中所有代码被执行之前被声明
// - 函数声明也会在函数中所有的代码执行之前执行
// 2.调用函数创建的函数作用域,函数执行完之后,函数作用域销毁
// 3.每调用一次函数就会去创建一个新的函数作用域,他们之间是互相独立的
// 4.在函数作用域中操作一个变量时,会先在自身作用域中寻找,有就直接用,没有就向上一级作用域寻找,直到在全局作用域中寻找,全局也没找到就报错
// 5.在函数中要访问全局变量可以使用window对象
var a = 5;
fun();
function fun() {
console.log("a = " + a); //此时还没有定义任何变量,引用的是全局变量的a=5
a = 50; //在函数中,没有用var 定义的变量都是全局变量。所以全局变量变成了50
}
console.log("a = " + a); //结果为50
</script>
3.调用函数时,浏览器每次都会传递进有两个隐含的参数
3.1 函数的上下文对象 this
定义: 解析器在每次函数调用的时候都会向函数内部传递一个隐含的参数(this
)。this
指向的是一个对象。这个对象称为函数的上下文对象
。根据调用方式不同,this
会指向不同的对象。
- 1.以
方法
的形式调用,this
就是调用方法的那个对象
(定义的对象名)。 - 2.以
函数
的形式调用,this
就永远是window
。
<script type="text/javascript">
function fun() {
// console.log(this); //this是上下文对象。this:函数不传参,但是可以通过this向函数内部调用一个隐形的参数
console.log(this.name); //更直观看出this指向的是那个对象。
}
var obj = { //字面量创建对象方法
name: "小明",
sayNeeeame: fun //把fun()函数作为属性值
}
// 调用方式不同,this会指向不同的对象
// 1.以方法的形式调用,this就是调用方法的那个对象。这里this就是obj
// obj.sayName(); //{name: '小明', sayName: ƒ}
obj.sayName(); //小明
// 2.以函数的形式调用,this就永远是window。
var name = "全局变量的name";
// fun(); //window
fun(); //全局变量的name
</script>
3.2 封装实参的对象arguments
- arguments是一个
类数组对象
(但不属于数组对象)。可以通过索引操作数据
,也可以获取长度
- 在
调用函数
时,所传递的实参
都会在arguments 中保存
arguments.length
获取的是实参的长度(个数)
- 即使不定义形参,也可以通过arguments来使用实参,只是比较麻烦
arguments[0]
表示第一个实参
(类似数组形式)arguments.callee
返回结果为:编译器状态下当前正在执行
的函数下所有内容
<script type="text/javascript">
function fun() {
console.log(arguments instanceof Array); //false
console.log(arguments); //Arguments [callee: ƒ, Symbol(Symbol.iterator): ƒ]
console.log(Array.isArray(arguments)); //false
console.log(arguments.length); //arguments.length获取的是实参的长度(个数)
console.log(arguments[0]); //表示第一个实参,为2
console.log(arguments.callee); //返回结果为编译器状态下fun函数下所有内容: //fun() {
// console.log(arguments instanceof Array); //false
// console.log(arguments); //Arguments [callee: ƒ, Symbol(Symbol.iterator): ƒ]
// console.log(Array.isArray(ar…
}
fun(2);
</script>
八、数组
8.1 定义
- 创建数组
var 数组名= new Array();例如var arr = new Array();
- 读取数组
语法:数组[索引]
- 向数组最后一个位置添加元素。
语法:数组[数组.length]=值 例如 arr[arr.length] = 20;
- 修改length。若是修改的大于原长度,多出来的部分会空出来;若小于原长度,多的元素会被删除
数组.length = 值; 例如arr.length = 10;
- 获取数组长度(数组元素的个数)。
语法: 数组.length
。对连续的数组
,获取到的是元素的个数
;对非连续的数组
,获取到的是数组最大索引+1
- 数组也是一个对象,和普通功能类似,也是存值
- 区别:普通对象用字符串作为属性名,
数组
用数字作为索引
操作元素
<script type="text/javascript">
// 创建数组
var arr = new Array();
arr[0] = 9;
console.log(typeof arr); //object
console.log(arr[4]); //undefined(读取不存在的索引,不会报错而返回undefined)
// 获取数组长度(数组元素的个数)。语法: 数组.length
// 对连续的数组,获取到的是元素的个数
// 对非连续的数组,获取到的是数组最大索引+1
console.log(arr.length); //1 获取数组的长度
// 修改length。若是修改的大于原长度,多出来的部分会空出来;若小于原长度,多的元素会被删除
arr.length = 10;
console.log(arr.length); // 10
console.log(arr); //(10) [9, empty × 9]
// 数组也是一个对象,和普通功能类似,也是存值
// 区别:普通对象用字符串作为属性名,数组用数字作为索引操作元素
// 读取数组 语法:数组[索引]
// 向数组最后一个位置添加元素。 语法:数组[数组.length]=值
arr[arr.length] = 20;
console.log(arr);
</script>
8.2 数组的更多数据类型的定义形式
- 字面量创建数组
语法:var 数组名 = [];
- 使用字面量创建数组时,可以在创建时就指定数组中的元素
var arr1 = [1, 35, 67];
- 使用构造函数创建数组时,也可以同时添加元素,将要添加的元素作为构造函数的参数传递,元素之间用,隔开
看代码中第3点
- 数组中也可以放数组。如下为二维数组
var arr2 = [[23, 5, 6], [6, 7, 8], [5, 7, 8]];
- 数组中是
任何数据类型
arr3 = [1, 3, "h3kko", null, undefined, true];
- 即也可以是
对象
arr4 = [{ name: "小红" }, { name: "小丽" }];
- 5.也可以是函数
arr5 = [function () { alert(1); }, function () { alert(2); }]
具体看第5点
<script type="text/javascript">
// 字面量创建数组 语法:var 数组名 = [];
var arr = [];
console.log(arr);
console.log(typeof arr); //object
// 使用字面量创建数组时,可以在创建时就指定数组中的元素
var arr1 = [1, 35, 67];
console.log(arr1);
// 3.使用构造函数创建数组时,也可以同时添加元素,将要添加的元素作为构造函数的参数传递
// 元素之间用,隔开
var arr0 = new Array(10, 20, 40);
console.log(arr0);
// 创建一个数组,数组中只有一个元素
var arr6 = [1];
console.log(arr6);
// 创建一个长度为10 的数组
arr7 = new Array(10); //与上面的区别,用构造函数创建的数组这样写只能是代表数组长度。
console.log(arr7);
console.log(arr7.length);
// 4.数组中也可以放数组。如下为二维数组
var arr2 = [[23, 5, 6], [6, 7, 8], [5, 7, 8]];
console.log(arr2);
// 数组中是任何数据类型
arr3 = [1, 3, "h3kko", null, undefined, true];
console.log(arr3);
// 即也可以是对象
var obj = { name: "小李" }; //1.创建一个对象
arr[arr.length] = obj; //对象赋值给数组
arr4 = [{ name: "小红" }, { name: "小丽" }]; //2.第二种创建方式,字面量
console.log(arr4);
console.log(arr);
// 5.也可以是函数
arr5 = [function () { alert(1); }, function () { alert(2); }]
console.log(arr5); //取出数组的内容
console.log(arr5[0]()); //取出某个函数并执行里面的内容
</script>
8.3 数组的4个方法
<script type="text/javascript">
// 创建一个数组
var arr = ["小红", "小米", "小青"];
// push() 作用如下注释
var result = arr.push("小亮", "小庄"); //向数组添加了1-多个元素
console.log("result = " + result); //返回数组的最新长度
// pop() 作用如下注释
result = arr.pop();
console.log(arr); //删除数组末尾的最后一个元素
console.log("result = " + result); //返回数组刚刚删除的那个元素
// unshift() 作用如下注释
result = arr.unshift("小刘", "小沙");
console.log(arr); //添加数组开头的1-多个元素
console.log("result = " + result); //返回数组最新长度
// shift() 作用如下注释
result = arr.shift();
console.log(arr); //删除数组开头的第一个元素
console.log("result = " + result); //返回数组刚刚删除的那个元素
</script>
8.4 forEach()方法
- forEach()方法,
用来遍历数组
,只支持IE8以上
的浏览器(移动端不限制
)。 - forEach()方法需要
一个函数作为参数
- 像这种函数,
由我们创建但不由我们调用
,叫回调函数
【function(){}
】 - 数组中
有几个元素函数就会执行几次
。每次执行, 浏览器都会将遍历到的元素以实参
的形式传递进
来,可以定义形参来读取
这些内容(如a,b,c) - 浏览器会在
回调函数
中传递三个参数
:
第一
个参数:就是当前正在遍历的元素(value)
第二
个参数:就是当前正在遍历的元素的索引(index)
第三
个参数:就是当前正在遍历的数组(obj)
<script type="text/javascript">
// 创建一个数组
var arr = ["小红", "小米", "小青"];
arr.forEach(function (a, b, c) {
console.log(" a = " + a); //输出的是正在遍历的元素
console.log(" b = " + b); //输出的是正在遍历的元素的索引
console.log(" c = " + c); //输出的是正在遍历的数组
})
</script>
8.5 slice()
和splice()
slice()
slice()
方法 用来从数组提取
指定元素
- slice()方法
不
会影响原数组
,而是将截取到的元素封装
到一个新数组中并作为返回值返回
参数
:
第一个参数.
截取开始的位置索引。开始索引会显示。
第二个参数
.截取结束的位置索引,结束位置的索引不会显示- 若只有第一个索引,则从开启索引的位置遍历完数组剩下的所有元素
<script type="text/javascript">
// 创建一个数组
var arr = ["小红", "小米", "小青"];
// arr.slice(0, 1);
var result = arr.slice(1);
console.log(arr); //还是输出原数组['小红', '小米', '小青'],说明slice()方法不会影响原数组
console.log(result); //['小红'] 说明该方法是将截取到的元素封装到一个新数组中返回
</script>
splice()
splice()
方法 会影响到原数组
,会将指定元素从原数组中删除
,并将被删除的元素作为返回值返回
- 参数:
第一个参数,表示开始位置的索引
。
第二个参数,表示删除的数量
第三个及以后的参数,可以传递一些新元素
,并自动插入
到开始位置索引前面
<script type="text/javascript">
// splice()方法
result = arr.splice(1, 2);
console.log(arr); //输出['小红'],说明splice()删除的是索引为1开始的2个元素。会影响到原数组数组
console.log(result); //输出['小米', '小青'],说明splice()会将删除的元素作为返回值返回
result = arr.splice(1, 2, "小小", "小夏", "小花");
console.log(arr); //输出['小红', '小小', '小夏', '小花'],说明splice()在第3个参数位置起可以为数组添加元素并放在第一个参数索引位置前。
console.log(result); //输出[],原数组只有0:小红,没有索引为1的元素,所以就返回空。
</script>
8.6 数组的其他方法
concat()
方法,可以连接两个或多个数组
join()
方法,可以将数组转换
为一个字符串
,括号
里可以是任何字符串
,将数组串起来。默认是,
reverse()
方法,用来反转
数组。会直接修改原数组sort()
方法,对元素进行排序
。默认按Unicode编码规则排序- 自定义排序的规则 在sort()函数里添加一个
回调函数
,指定排序规则,回调函数中需要两个形参
。 - 浏览器
自动
会分别用数组中的元素作为实参
去调用回调函数。调用顺序不清楚,但第一个形参调用的数组的值一定在第二个形参前面。(在数组中)
浏览器会根据回调函数的返回值来决定元素的顺序
return 大于0的值
,则元素会交换
位置- return
小于0的值
,则元素不交换
位置 - return
0
,则元素不交换
位置 升序排序,return a-b
降序排序,return b-a
- 自定义排序的规则 在sort()函数里添加一个
<script type="text/javascript">
// 数组的其他函数
// concat()方法 可以连接两个或多个数组
arr = ["小红", "小米", "小青"];
arr1 = ["小丽", "小九", "小南", "小问"];
arr.concat(arr1);
var result = arr.concat(arr1);
console.log(arr); //["小红", "小米", "小青"],说明concat()不会影响原数组
console.log(result); //['小红', '小米', '小青', '小丽', '小九', '小南', '小问'],可以连接两个或多个数组。并将新数组返回
//join()方法 可以将数组转换为一个字符串
arr.join();
result = arr.join();
console.log(typeof arr); //object 说明join()不会影响原数组
console.log(typeof result); //string join()将转换后的字符串作为结果返回
// reverse()方法 用来反转数组。会直接修改原数组
arr.reverse();
console.log(arr); //['小青', '小米', '小红']
//sort()方法
// 对元素进行排序。默认按Unicode编码规则排序
arr.sort();
console.log(arr); //['小米', '小红', '小青']
arr = [1, 3, 6, 8, 12];
arr.sort();
console.log(arr); //[1, 12, 3, 6, 8] 根据Unicode编码排序,所以数字排序不能直接这么写
arr.sort(function (a, b) {
return a - b; //升序排序
});
console.log(arr); //[1, 3, 6, 8, 12]
</script>
九、call()
和 apply()
方法
call()
和apply()
两个方法
都是函数对象的方法
,需要
通过函数对象来调用
- 对函数调用这两个方法时,都会
调用函数执行
,可以将第一个对象指定为参数
,此时这个对象
将成为函数执行时的this
call()
方法可以将实参在对象后依次传递
apply()
方法需要将实参封装到一个数组中统一传递
-this
以apply和call调用时
,this是指定的那个对象
对这句话的理解:对象就是一个房间。你已经在房间里了,(如果只是调用该对象的方法)就只能用房间里的东西;(如果是用了call()
和apply()
的方法)就可以通过它们(比如快递员)来点外卖、拿快递,拿到房间以外的东西。
<script type="text/javascript">
function fun() {
alert(this.name);
}
// fun();
// fun.apply();
// fun.call();
var obj = {
name: "obj",
sayName: function () {
alert(this.name);
}
};
var obj1 = {
name: "obj1",
sayName: function () {
alert(this.name);
}
};
// fun(); //[object Window] this以函数形式调用,this就是window
// fun.apply(obj); //[object Object] this以apply调用时,传的参数是什么对象this就是什么(this就是obj)。
// fun.call(obj); //[object Object] this以call调用时,传的参数是什么对象this就是什么(this就是obj)。
// fun.apply(obj1); //obj1
// obj.sayName(obj1); //obj 结果不是预期的,因为传的是obj1对象,而不是obj对象
// obj.sayName.apply(obj1); //obj1.结果是预期结果。this以apply和call调用时,this是指定的那个对象
// call()方法可以将实参在对象后依次传递
// apply()方法需要将实参封装到一个数组中统一传递
function fun1(a, b) {
console.log("a = " + a);
console.log("b = " + b);
console.log(this.name);
}
// fun1.call(obj1, 2, 3); //a = 2, b = 3, obj1
fun1.apply(obj1, [2, 3]); //a = 2, b = 3, obj1
</script>
十、Date
对象(时间)
- 创建一个Date对象,如果直接使
用构造函数创建一个Date对象
,则会封装为当前代码执行时间
var d = new Date();
- 创建一个
指定的时间对象
,需要在构造函数中传递一个表示时间的字符串
作为参数var d2 = new Date("4/05/2022 20:20:00");
getDate()方法
,获取访问的Date对象是几日(1-31)
getDay()方法
,获取访问的Date对象是一周中的哪一天(0-6),0代表周日
getMonth()方法
,获取访问的Date对象的月份(0-11),0代表1月
getFullYear()方法
,获取访问的Date对象的年份(4位数)
getHours()方法
,获取访问的Date对象的小时(0-23)
getMinutes()方法
,获取访问的Date对象的分钟(0-59)
getMilliseconds()方法
,获取访问的Date对象的毫秒(0-999)
getTime()获取当前的时间戳
,时间戳是指从格林威治时间的1970年1月1日 0时0分0秒到当前日期时间所花费的毫秒数(1秒=1000毫秒),计算机底层保存的时间都是用时间戳保存的
<script type="text/javascript">
// 创建一个Date对象
// 如果直接使用构造函数创建一个Date对象,则会封装为当前代码执行时间
var d = new Date();
console.log(d); //Thu Apr 21 2022 23:54:09 GMT+0800 (中国标准时间)
// 创建一个 指定的时间对象
// 需要在构造函数中传递一个表示时间的字符串作为参数
var d2 = new Date("4/05/2022 20:20:00");
console.log(d2); //Tue Apr 05 2022 20:20:00 GMT+0800 (中国标准时间)
// getDate()方法
// 获取访问的Date对象是几日(1-31)
var date = d.getDate();
console.log("date = " + date); //Date = 22
// getDay()方法
// 获取访问的Date对象是一周中的哪一天(0-6),0代表周日
var day = d.getDay();
console.log("day = " + day); //day = 5
// getMonth()方法
// 获取访问的Date对象的月份(0-11),0代表1月
var month = d.getMonth();
console.log("month = " + month); //month = 3
// getFullYear()方法
// 获取访问的Date对象的年份(4位数)
var year = d.getFullYear();
console.log("year = " + year); //year = 2022
// getHours()方法
// 获取访问的Date对象的小时(0-23)
var hour = d.getHours();
console.log("hour = " + hour); //hour = 0
// getMinutes()方法
// 获取访问的Date对象的分钟(0-59)
var minutes = d.getMinutes();
console.log("mintues = " + minutes); //mintues = 10
// getSeconds()方法
// 获取访问的Date对象的秒数(0-59)
var seconds = d.getSeconds();
console.log("seconds = " + seconds); //seconds = 49
// getMilliseconds()方法
// 获取访问的Date对象的毫秒(0-999)
var milliseconds = d.getMilliseconds();
console.log("milliseconds = " + milliseconds); //seconds = 49
// getTime()获取当前的时间戳
// 时间戳是指从格林威治时间的1970年1月1日 0时0分0秒到当前日期时间所花费的毫秒数(1秒=1000毫秒)
// 计算机底层保存的时间都是用时间戳保存的
var time = d.getTime();
console.log("time = " + time); //time = 1650557680210 单位是毫秒
// 中国与格林威治区域有8小时时间差
var d4 = new Date("1/01/1970 0:0:0");
time = d4.getTime();
console.log("time = " + time); //time = -28800000(因为8小时时差,所以不是0)
</script>
十一、Math 对象
Math 对象
允许您执行数学任务。是一个工具类
- Math
不是构造函数
。Math 的所有属性/方法
都可以通过使用Math
作为对象来调用
,而无需创建它
(即不用创建对象)。
<script type="text/javascript">
// Math.round(); 四舍五入取整
console.log(Math.round(5.6));
// Math.abs(); 用来计算一个数的绝对值
console.log(Math.abs(-1));
// Math.ceil(); 对数值向上取整
console.log(Math.ceil(5.3));
// Math.floor(); 对数值向下取整
console.log(Math.floor(5.4));
// Math.pow(x, y) 对数值x取y次幂
console.log(Math.pow(3, 3));
// Math.sqrt(x, y) 对数值x开y次方
console.log(Math.sqrt(9, 2));
// Math.max(n个数值) 取出最大值
console.log(Math.max(5, 6, 2, 60));
// Math.min(n个数值) 取出最小值
console.log(Math.min(5, 6, 2, 60));
// Math.random() 生成0-1之间的随机数(都是小数)
// Math.round(Math.random() * x) 生成0-x之间的随机数
// console.log(Math.round(Math.random() * (y-x) + x) 生成x-y之间的随机数
for (var i = 0; i < 10; i++) {
console.log(Math.random());
// 取出0-10之间的随机数(整数)
console.log(Math.round(Math.random() * 10));
// 取出0-20之间的随机整数
console.log(Math.round(Math.random() * 20));
// 生成2-10之间的随机整数
console.log(Math.round(Math.random() * 8 + 2));
}
</script>
十二、包装类(将基本数据类型转化为对象)
方法和属性能添加给对象
,不能
添加给基本数据类型
- 当对一些基本数据类型的值去调用属性和方法时, 浏览器会临时使用包装类将其转换为对象,然后在调用对象的属性和方法调用完成后,在将其转换为基本数据类型。(即最后此时的变量仍是基本数据类型,但是不会报错,且其对应的属性/方法下的值获取不到,都是undefined)
- 我们
不用包装类
,主要是浏览器
需要时自动使用。
<script type="text/javascript">
// 方法和属性能添加给对象,不能添加给基本数据类型
var num = new Number(3); //创建一个Number类型的对象
num.age = 90;
console.log(num); //Number{3}
console.log(typeof num); //object
console.log(num.age); //90
console.log(typeof num.age); //number
// 当对一些基本数据类型的值去调用属性和方法时,
// 浏览器会临时使用包装类将其转换为对象,然后在调用对象的属性和方法
// 调用完成后,在将其转换为基本数据类型。
// 即最后此时的变量仍是基本数据类型,但是不会报错,且其对应的属性/方法下的值获取不到,都是undefined
var s = 456;
s = s.toString();
s.hello = "你好";
console.log(s); //456
console.log(typeof s); //string
console.log(s.hello); //undefined
console.log(typeof s.hello); //undefined
var bool = new Boolean(true);
var bool1 = new Boolean(true);
var bool2 = true;
console.log(bool); //Boolean {true}
console.log(bool1); //Boolean {true}
console.log(bool2); //true
console.log(typeof bool); //object
console.log(typeof bool1); //object
console.log(typeof bool2); //boolean
console.log(bool == bool1); //false(因为两个都是对象,地址不一样,这也是我们不用包装类的主要原因)
console.log(bool == bool2); //true
console.log(bool === bool2); //false
</script>
1.String()
- 将基本数据类型的字符串转化为String对象
2.Number()
- 定义:将基本数据类型的数字转化为Number对象
- String方法:
length属性
,可以获取字符串的长度
。也可以像数组那样取出某个字符串内容charAt(index)
获取该index下的字符
charCodeAt(index)
获取该index下字符的字符编码
(Unicode编码数值)concat()
连接字符串,效果同 + 号。fromCharCode()
从字符编码创建一个字符串。只能这样获取:String.fromCharCode(编码数值)
从字符串创建一个字符编码
(一般是十进制
,若是其他进制要标明,如0x)
-indexOf(searchvalue,fromindex)
检索字符串。searchvalue
需检索的字符串值
fromindex
在字符串中开始检索的位置(从前往后找)
。返回
某个指定的字
符在字符串中首次出现的位置
。如果没找到返回-1
.lastIndexOf(searchvalue,fromindex)
, 从后向前搜索字符串。同上
,但是检索是从fromindex开始往前检索。如果没找到返回-1
.(从后往前找
)slice(star,end)
提取字符串的片断,并在新的字符串中返回被提取的部分。 star开始索引位置,end停止索引位置(且不包含这个位置的值)都可以是负数
,负数
表示位置从尾部开始算起
substring(star,end)
提取字符串中两个指定的索引号之间的字符。同上
,但不可以是负数 如果第二个参数 < 第一个参数,自动转换参数位置substr(start,length)
从起始索引号提取字符串中指定数目的字符。start开始索引位置 ,length
要取出的字符串长度
split(separator,howmany)
把字符串分割为字符串数组
。separator要以哪个字符、符合为标准分割,howmany代表生成的数组长度,默认则是转化整个字符串toLocaleUpperCase()
转化为大写字母
-toLocaleLowerCase()
转化为小写字母
<script type="text/javascript">
var str = "yhglg.w;gabj;gn";
// length属性,可以获取字符串的长度。也可以像数组那样取出某个字符串内容
console.log(str.length); //15
console.log(str[8]); //g
// charAt(index) 获取该index下的字符
console.log(str.charAt(5)); //.
// charCodeAt(index) 获取该index下字符的字符编码(Unicode编码数值)
console.log(str.charCodeAt(5)); //46
// concat()连接字符串,效果同 + 号。
console.log(str.concat("你好")); //yhglg.w;gabj;gn你好
// fromCharCode() 用法:只能这样获取:String.fromCharCode(400)
// 从字符串创建一个字符编码(一般是十进制,若是其他进制要标明,如0x)
console.log(String.fromCharCode(400)); //Ɛ
// indexOf(searchvalue,fromindex) searchvalue需检索的字符串值 fromindex在字符串中开始检索的位置(从前往后找)
// 返回某个指定的字符串值在字符串中首次出现的位置。
console.log(str.indexOf("h", 0)); //1 代表从0开始检索,在1的位置找到h
// lastIndexOf(searchvalue,fromindex), 同上,但是检索是从fromindex开始往前检索。如果没找到返回-1.(从后往前找)
console.log(str.lastIndexOf("h", 9)); //1 代表从索引为9的位置开始往前检索,在1的位置找到h
// slice(star,end) star开始索引位置,end停止索引位置(且不包含这个位置的值) 都可以是负数,负数表示位置从尾部开始算起
console.log(str.slice(2, 5)); //glg 取出从索引为2-4的值,5是结束位置,5所在的值不取。
// substring(star,end) 同上,但不可以是负数 如果第二个参数 < 第一个参数,自动转换参数位置
console.log(str.substring(2, 5)); //glg 取出从索引为2-4的值,5是结束位置,5所在的值不取。但是不能是负数
console.log(str.substring(5, 1)); //hglg 第二个参数 < 第一个参数,自动转换参数位置
// substr(start,length) start开始索引位置 length要取出的字符串长度
console.log(str.substr(2, 5)); //glg.w 取出索引为2开始的5个字符。 第二个参数是长度
// split(separator,howmany) separator要以哪个字符、符合为标准分割,howmany代表生成的数组长度,默认则是转化整个字符串
console.log(str.split("", 8)); //['y', 'h', 'g', 'l', 'g', '.', 'w', ';'] ""空串则会把字符串每个字符都形成一个元素,8表示形成数组的长度
// toLocaleUpperCase() 转化为大写字母
console.log(str.toLocaleUpperCase()); //YHGLG.W;GABJ;GN 转化为大写字母
str = "YHGLG.W;GABJ;GN";
console.log(str.toLocaleLowerCase()); //yhglg.w;gabj;gn 转化为小写字母
</script>
</head>
3.Boolean()
- 将基本数据类型的布尔值转化为Boolean对象
十三、正则表达式
1、基本形式
定义:检查一个字符串是否含有a
。i
表示忽略大小写
,g
表示全局匹配模式
- 创建正则表达式对象
语法1:var 变量 = new RegExp("正则表达式","匹配模式")
- 创建正则表达式对象(字面量创建正则表达式)
语法2:var 变量 = /正则表达式/匹配模式
(没有构造方法的灵活【法1】)
-test()
检查字符串是否符合正则表达式的规则
-|
和[]
都是或
的意思。 [A-Z]
任意大写字母[a-z]
任意小写字母[A-z]
任意字母、_[0-9]
任意数字[A-z0-9
] 任意字母、数字、_
-[^x]
除了x(字符串只有x
为false
,不止x/没有x为true
)
<script>
// 创建正则表达式对象 语法1:var 变量 = new RegExp("正则表达式","匹配模式")
var res = new RegExp("a", "i"); //检查一个字符串是否含有a。i忽略大小写,g全局匹配模式
console.log(res); // /a/i
console.log(typeof res); //object
// test()检查字符串是否符合正则表达式的规则
// console.log(res.test("bscda")); //true(字符串含有a)
console.log(res.test("bscdA")); //true(字符串含有A)i忽略大小写
// 创建正则表达式对象(字面量创建正则表达式) 语法2:var 变量 = /正则表达式/匹配模式(没有构造方法的灵活【法1】)
var reg = /ab/i;
console.log(reg.test("bbacd")); //false(必须是ab连在一起,且部分大小写)
console.log(reg.test("abaddd")); //true
console.log(reg.test("Abaddd")); //true
reg = /[ab]/i; //法2
console.log(reg.test("adddggggb")); //true
console.log(reg.test("Adddgggg")); //true
reg = /[A-Z]/;
reg = /[a-z]/;
reg = /[A-z]/;
reg = /[0-9]/;
reg = /[A-z0-9]/;
console.log(reg.test("s"));
reg = /[^a]/i; //除了a
console.log(reg.test("ad"));
</script>
2.正则表达式的方法
split()
方法:stringObject.split(separator,howmany)方法把一个字符串分割成字符串数组。
replace()
方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串
。stringObject.replace(regexp/substr,replacement)match()
方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配
。该方法类似 indexOf() 和 lastIndexOf(),但是它返回
指定的值
,而不是字符串的位置。search()
方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串
。不能设置全局匹配
,只能
查找第一个出现的位置
<script>
var str = "13ndjt5h5j2n5_j6b";
// split(separator,howmany)方法
var result = str.split(/[A-z]/); // ['13', '', '', '', '5', '5', '2', '5', '', '6', '']
result = str.split(/[0-9]/); // ['', '', 'ndjt', 'h', 'j', 'n', '_j', 'b']
result = str.split(/[A-z0-9]/); //['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '']
// replace()
// stringObject.replace(regexp/substr,replacement)
str = "visual studio code";
result = str.replace(/visual/, "Visual");
// match()
// stringObject.match(searchvalue)
// stringObject.match(regexp)
result = str.match(/studio/); //['studio', index: 7, input: 'visual studio code', groups: undefined]
result = str.match(/\d/); //null
result = str.search(/code/i); //14
// search()
// stringObject.search(regexp)
str = "hello children";
result = str.search(/child/i); //6
console.log(result);
</script>
3.正则表达式的量词
<script>
// 量词 (只对它前面的一个内容起作用)
var reg = /a{1}/; //a出现1次
reg = /(ab){3}/g; //ab连续出现3次
reg = /a(b)*/g; //a之后紧跟的b出现 0-多次
reg = /a(b)+/g; //a之后紧跟的b出现 1-多次
reg = /a(bb)?/g; //a之后紧跟0-1个b
reg = /b(?=ab)/g; //匹配任何其后紧接指定字符串 n 的字符串。
reg = /b(?!ab)/g; //匹配任何其后没有紧接指定字符串 n 的字符串。
var str = "abababab_h3";
console.log(reg.test(str));
console.log(str.match(reg));
console.log(str.search(reg));
// 手机号规则
// 1 3 789024554 (11位)
// 1.以1开头 2.第二位从3-9任意数字 3.后9位取任意数字
var phoneStr = "13018957458";
var phoneReg = /^1[3-9][0-9]{9}$/g;
console.log(phoneReg.test(phoneStr));
</script>
4.正则表达式的元字符
- .
元字符用于查找【单个】字符,除了换行和行结束符。
\w
元字符用于查找字母、数字、_\W
元字符用于查找不是(字母、数字、_)的字符\d
元字符用于查找数字\D
元字符用于查找非数字字符\s
元字符用于查找空白字符\S
元字符用于查找非空白字符\b
元字符匹配单词边界。\B
元字符匹配非单词边界。匹配位置的上一个和下一个字符的类型是相同的:
即必须同时是单词,或必须同时是非单词字符。字符串的开头和结尾处被视为非单词字符。邮箱号的正则
/^\w{3,}(\.\w+)*@[A-z0-9]+(\.[A-z]{2,5}){1,2}$/;
<script>
var str = "11_hello today11@#f!.";
var reg = /h.+a/g; // .元字符用于查找【单个】字符,除了换行和行结束符。
reg = /\w/g; //\w 元字符用于查找字母、数字、_
reg = /\W/g; //\W 元字符用于查找不是(字母、数字、_)的字符
reg = /\d/g; //\d 元字符用于查找数字
reg = /\D/g; //\D 元字符用于查找非数字字符
reg = /\s/g; //\s 元字符用于查找空白字符
reg = /\S/g; //\S 元字符用于查找非空白字符
reg = /o\b/g; //\b 元字符匹配单词边界。
reg = /o\B/g; //\B 元字符匹配非单词边界。匹配位置的上一个和下一个字符的类型是相同的:
// 即必须同时是单词,或必须同时是非单词字符。字符串的开头和结尾处被视为非单词字符。
// 检查字符串中是否有 . 字符
reg = /\./g; //要用转义字符 \. 才能显示.字符,否则会被认为是.元字符
result = str.replace(reg);
console.log(reg.test(str));
console.log(str.match(reg));
console.log(str.search(reg));
console.log(result);
// 邮件的正则
// 形式: er2 .eg2 @ egv2 .com.cn
// 注释 任意字母数字_ .任意字母数字_ @ 任意字母数字 .任意字母(2-5位).任意字母(2-5位)
// 对应正则: \w{3,} (\.\w+)* @ [A-z0-9]+ (\.[A-z]{2,5}){1,2}
var email = "13487963abe@35k.com";
var emailReg = /^\w{3,}(\.\w+)*@[A-z0-9]+(\.[A-z]{2,5}){1,2}$/;
console.log(emailReg.test(email));
console.log(email);
</script>
十四、DOM
1.DOM介绍
2.节点
2.1 节点简介
2.2 节点属性
3.事件
3.1 事件的定义
3.2 事件的创建与文档加载
1.文档加载:
- 方式有2种,1种是写在下的
<head>
<title>DOM</title>
<script>
// 文档的加载
// 方式有2种,1种是写在这里,为window绑定 一个onload事件,一种是直接写在要调用事件的代码下
// onload事件会在整个页面加载完成之后才触发
window.onload = function () {
var btn = document.getElementById("btn");
console.log(btn); //<button id="btn">我是一个按钮</button> 说明通过文档对象获取到了button对象,现在btn=button
// 修改按钮文本内容
// btn.innerHTML = "I'm button";
//事件的生成方法2 添加事件处理函数,事件被触发时,对应的函数就会被调用
btn.onclick = function () {
alert("真烦人");
};
}
</script>
</head>
<body>
<button id="btn">我是一个按钮</button>
<!-- 事件的生成方法1 -->
<!-- 直接在属性上添加内容,这样的写法叫结构和行为的耦合。不方便维护 -->
<!-- <button id="btn" οnclick="alert('真烦人');">我是一个按钮</button> -->
<script>
// 获取到按钮对象
var btn = document.getElementById("btn");
console.log(btn); //<button id="btn">我是一个按钮</button> 说明通过文档对象获取到了button对象,现在btn=button
//事件的生成方法2 添加事件处理函数,事件被触发时,对应的函数就会被调用
btn.onclick = function () {
alert("真烦人");
};
</script>
</body>
3.2事件的对象
事件对象
:当事件的响应函数被触发时,浏览器每次都会将一个事件对象作为实参
传递进响应函数。在事件对象中封装了当前事件相关的一切信息,如鼠标的坐标,键盘在哪个按键被按下onmousemove
该事件将会在鼠标在元素中移动时被触发
<script>
window.onload = function () {
// 当鼠标再areaDiv中移动时,再showMsg中来显示鼠标的坐标
var areaDiv = document.getElementById("areaDiv");
var showMsg = document.getElementById("showMsg");
// onmousemove 该事件将会在鼠标在元素中移动时被触发
areaDiv.onmousemove = function (event) {
var x = event.clientX;
var y = event.clientY;
// 考虑浏览器的兼容问题。
// 判断浏览器是否有event这个对象。没有就选择window.event
event = event || window.event;
// 在showMsg中显示鼠标的坐标
showMsg.innerHTML = "x = " + x + ", " + "y = " + y;
};
};
</script>
<body>
<div id="areaDiv"></div>
<div id="showMsg"></div>
</body>
3.3 事件的冒泡
事件的冒泡(Bubble)
:事件向上传导,当后代元素上的事件被触发时,其祖先元素的相同事件也会被触发cancelBubble = true
取消
冒泡行为
<style>
#box {
width: 300px;
height: 300px;
background-color: aqua;
}
#info {
background: green;
}
</style>
<script>
window.onload = function () {
// 事件的冒泡(Bubble):事件向上传导,当后代元素上的事件被触发时,其祖先元素的相同事件也会被触发
var box = document.getElementById("box");
var info = document.getElementById("info");
info.onclick = function (event) {
// 取消冒泡
event = event || window.event;
alert(info.innerHTML);
// cancelBubble = true 取消冒泡行为
event.cancelBubble = true;
};
box.onclick = function (event) {
event = event || window.event;
alert(box.innerHTML);
event.cancelBubble = true;
};
document.body.onclick = function (event) {
alert("我是body");
};
};
</script>
</head>
<body>
<div id="box">
我是div
<p id="info">我是span</p>
</div>
</body>
3.4 事件的委派
- 事件的委派:将事件统一绑定给元素的
共同的祖先元素
,当后代元素上的事件触发时,会一直冒泡
到祖先元素,从而通过祖先元素的响应函数来处理事件。 - 作用:事件委派利用了冒泡,通过委派可以减少事件绑定的次数,提高程序的性能。
<script>
window.onload = function () {
var u1 = document.getElementById("u1");
var btn = document.getElementById("btn");
btn.onclick = function () {
var li = document.createElement("li");
li.innerHTML = "<a href='javascript:;' class='link'>新添加的超链接</a>";
u1.appendChild(li);
};
// 事件的委派
u1.onclick = function () {
if (event.target.className == "link") {
alert("我是ul的响应函数");
}
};
};
</script>
</head>
<body>
<button id="btn">添加超链接</button>
<ul id="u1">
<li><a href="javascript:;" class="link">超链接一</a></li>
<li><a href="javascript:;" class="link">超链接二</a></li>
<li><a href="javascript:;" class="link">超链接三</a></li>
</ul>
</bod
3.5事件的绑定
绑定响应函数有两种形式
法1
: 平常的调用方式语法:对象.事件 = 函数
(但是只能同时为一个元素的一
个事件绑定一
个响应函数)- 法2:用
addEventListener()方法
为元素绑定响应函数
其中需要三个参数
:
1.事件的字符串(不要on)
2.回调函数,当事件触发时该函数会被调用
3.是否在捕获阶段触发事件,需要一个布尔值,一般是false
使用addEventListner()可以同时为一个元素的相同事件同时绑定多个
响应函数。(当事件被触发,响应函数会安装函数的绑定顺序执行)。但是这样写很冗余
,用一个bind函数
来实现 bind绑定函数
:定义一个函数,用来指定元素绑定响应函数。addEventListener()中的this
,是绑定事件的对象
。attachEvent()中的this
,是window
。function bind(obj, eventStr, callback){}
参数:
obj 要绑定事件的对象
eventStr 事件的字符串
callback 回调函数
<script>
window.onload = function () {
// 绑定响应函数有两种形式
// 法1: 平常的调用方式 语法:对象.事件 = 函数 (但是只能同时为一个元素的一个事件绑定一个响应函数)
// var btn = document.getElementById("btn");
// btn.onclick = function () {
// alert("平常的绑定方式");
// };
// 法2:用addEventListener()方法为元素绑定响应函数
// 其中需要三个参数: 1.事件的字符串(不要on)
// 2.回调函数,当事件触发时该函数会被调用 3.是否在捕获阶段触发事件,需要一个布尔值,一般是false
// 使用addEventListner()可以同时为一个元素的相同事件同时绑定多个响应函数。(当事件被触发,响应函数会安装函数的绑定顺序执行)
// 但是这样写很冗余,用一个bind函数来实现
// btn.addEventListener("click", function () {
// alert(1);
// }, false);
// btn.addEventListener("click", function () {
// alert(2);
// }, false);
bind(btn, "click", function () {
alert(1);
});
bind(btn, "click", function () {
alert(2);
});
// ie8以下不兼容,现在基本也不考虑
// 用attachEvent() 绑定事件 参数:1.事件的字符串,要on 2.回调函数
// 这个方法也是用来同时为一个事件绑定多个处理函数,不同的是后绑定先执行(倒序)
// 基本不会用的
// btn.attachEvent("onclick", function () {
// alert("兼容性下的另一个方式。");
// });
// 定义一个函数,用来指定元素绑定响应函数
// addEventListener()中的this,是绑定事件的对象
// attachEvent()中的this,是window
// 参数: obj 要绑定事件的对象 eventStr 事件的字符串,callback 回调函数
function bind(obj, eventStr, callback) {
if (obj.addEventListener) {
// 基本都是这个方式
obj.addEventListener(eventStr, callback, false);
} else {
// 这个方式基本没用了
// this是谁 由调用的方式决定。
obj.attachEvent("on" + eventStr, function () {
callback.call(this);
});
}
}
};
</script>
<body>
<button id="btn">按钮</button>
</body>
3.6事件的传播(了解)
事件传播分成3阶段:
1.捕获阶段
:该阶段时从最外
层的祖先元素(window/document)逐步向目标元素
进行事件的捕获,但是默认不触发(如果要在捕获阶段就出发,把addEventListener()中第三个参数值设为true。正常不这样写)2.目标阶段
:事件捕获到目标元素,捕获结束,开始在目标元素上触发
事件3.冒泡阶段
:事件从目标元素
向它的祖先元素
传递,依次触发祖先元素上的事件
3.7 事件的拖拽
拖拽元素流程
- 1.当鼠标在被拖拽元素上按时,开始拖拽
onmousedown
- 2.当鼠标移动时被拖拽元素跟随鼠标移到
onmousemove
- 3.当鼠标松开时,被拖拽元素固定在当前位置
onmouseup
偏移量:(这样鼠标才会保持在开始点击的坐标位置) 元素的偏移量
鼠标.clientX - 元素.offsetLeft
- 元素的偏移量
鼠标.clientY - 元素.offsetTop
当拖拽一个网页的内容时,浏览器会默认去搜索引擎中搜索内容。也即会导致拖拽功能异常,是浏览器默认的行为。不希望发生,则用return false
取消默认行为
<style>
#box1 {
width: 100px;
height: 100px;
background-color: aqua;
position: absolute;
}
#box2 {
width: 100px;
height: 100px;
background-color: rgb(199, 174, 32);
position: absolute;
left: 200px;
top: 200px;
}
</style>
<script>
window.onload = function () {
var box1 = document.getElementById("box1");
box1.onmousedown = function (event) {
// div的偏移量 鼠标.clientX - 元素.offsetLeft
// div的偏移量 鼠标.clientY - 元素.offsetTop
var ol = event.clientX - box1.offsetLeft;
var ot = event.clientY - box1.offsetTop;
document.onmousemove = function (event) {
var left = event.clientX - ol; //这样才能是鼠标原本指定在哪里就一直停在那,不会自动跳到盒子左上角
var top = event.clientY - ot;
box1.style.left = left + "px";
box1.style.top = top + "px";
};
document.onmouseup = function () {
document.onmousemove = null;
document.onmouseup = null;
};
// 当拖拽一个网页的内容时,浏览器会默认去搜索引擎中搜索内容
// 也即会导致拖拽功能异常,是浏览器默认的行为。不希望发生,则用以下方法取消默认行为
return false;
};
};
</script>
</head>
<body>
<div id="box1"></div>
<div id="box2"></div>
</body>
3.8 事件的滚动
onwheel
是鼠标滚动
的触发函数。向上滚正值,向下负值
- 浏览器有滚动条的话,滚轮滚动,滚动条会随之滚动,这是浏览器的
默认行为
。不希望发生则取消默认行为
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>滚轮事件</title>
<style>
#box {
width: 100px;
height: 100px;
background-color: rgb(236, 33, 33);
}
</style>
<script>
window.onload = function () {
var box = document.getElementById("box");
// onwheel是鼠标滚动的触发函数。向上滚正值,向下负值
box.onwheel = function (event) {
if (event.wheelDelta > 0) {
box.style.height = box.clientHeight - 10 + "px";
} else {
box.style.height = box.clientHeight + 10 + "px";
}
// 浏览器有滚动条的话,滚轮滚动,滚动条会随之滚动,这是浏览器的默认行为
// 不希望发生则取消默认行为
return false;
};
};
</script>
</head>
<body style="height: 2000px;">
<div id="box"></div>
</body>
3.9 键盘事件
onkeydown
键盘按键被按下
, 如果一直按着某个键不松手,事件一直会被触发,第一次和第二次按下的事件间隔长一点,之后都很快(防误操作发生)onkeyup
键盘按键被松开
只会触发一次- 键盘事件一般都会绑定给一些
可以获取到焦点的对象
或document
- 通过
keyCode
来获取按键编码
,通过编码来判断哪个按键被按下。对keyCode,事件对象还提供了几个属性
:altKey(alt)
、ctrlKey(ctrl键)
、shiftKey(shift键)
<head>
<style>
#box {
width: 100px;
height: 100px;
background-color: rgb(153, 10, 10);
position: absolute;
}
</style>
<script>
window.onload = function () {
var speed = 10;
document.onkeydown = function (event) {
// 效果:按下哪个方向,box就往哪个方向移动
// 如果,按下了ctrl键,就加速
if (event.ctrlKey) {
speed = 50;
}
// 键盘方向对应的Unicode编码 37 向左,38向上,39向右,40向下
switch (event.keyCode) {
case 37:
box.style.left = box.offsetLeft - speed + "px";
break;
case 38:
box.style.top = box.offsetTop - speed + "px";
break;
case 39:
box.style.left = box.offsetLeft + speed + "px";
break;
case 40:
box.style.top = box.offsetTop + speed + "px";
break;
}
};
};
</script>
</head>
<body>
<div id="box"></div>
</body>
4.获取元素节点
方式:
通过document对象
调用
- 1.
getElementById()
–通过id
属性获取一个
元素节点对象 - 2.
getElementByTagName()
– 通过标签名
获取一组
元素节点对象 - 3.
getElementByName()
– 通过name
属性获取一组
元素节点对象
5.获取元素节点的子节点
通过具体的元素节点
调用
- 1.
getElementsByTagName()方法
,返回当前节点的指定标签名后代节点 - 2.
childNodes属性
,表示当前节点的所有子节点,包括空白文本节点,(dom标签中标签间的空白会被当成空白文本节点。但IE8及以下就不会有) - 3.
firstChild属性
,表示当前节点的第一个子节点,包括空白文本节点(dom标签中标签间的空白会被当成空白文本节点。但IE8及以下就不会有) - 4.
lastChild属性
,表示当前节点的最后一个子节点,包括空白文本节点(dom标签中标签间的空白会被当成空白文本节点。但IE8及以下就不会有) - 5.
children
属性会获取当前元素下的所有子元素(即子标签)
6.获取父节点和兄弟节点
通过具体的节点
调用
- 1.
parentNode属性
,表示当前节点的父节点 - 2.
previousSibling属性
,表示当前节点的前一个兄弟节点 - 3.
nextSibling属性
,表示当前节点的后一个兄弟节点
4-6的例子放在dom查询练习.html
中,就不显示了。
7.dom查询的其他方法
document.body
获取body标签内的信息document.documentElement
获取HTML根标签内的信息document.all
法1:获取到的是HTML下的所有标签(all),返回并封装到一个数组内document.getElementsByTagName("*")
法2:获取到的是HTML下的所有标签,返回并封装到一个数组内document.getElementsByClassName("box1");
//根据元素的class属性,获取一组元素对象document.querySelector(".box1 div");
querySelector():需要一个选择器
的字符串做参数,可以根据css选择器
来查询一个元素对象。 该方法只会返回一个唯一的元素对象,若符合的有多个结果,只能也只会返回第一个
。document.querySelectorAll(".box1");
querySelectorAll()方法用法与上面类似,但是返回的是把内容封装到一个数组
中的数组。(即使符合的元素只有1个)
<script>
window.onload = function () {
// 获取body标签内的信息
var body = document.body;
console.log(body);
// 获取HTML根标签内的信息
var html = document.documentElement; //获取到的是HTML根标签
console.log(html);
var all = document.all; //法1:获取到的是HTML下的所有标签(all),返回并封装到一个数组内
all = document.getElementsByTagName("*"); //法2:获取到的是HTML下的所有标签,返回并封装到一个数组内
console.log(all);
var class0 = document.getElementsByClassName("box1"); //根据元素的class属性,获取一组元素对象
console.log(class0);
// querySelector():需要一个选择器的字符串做参数,可以根据css选择器来查询一个元素对象
// 该方法只会返回一个唯一的元素对象,若符合的有多个结果,只能也只会返回第一个
var div = document.querySelector(".box1 div");
console.log(div);
// querySelectorAll()方法用法与上面类似,但是返回的是把内容封装到一个数组中的数组。(即使符合的元素只有1个)
var box1 = document.querySelectorAll(".box1");
console.log(box1);
};
</script>
<body>
<div class="box1">
<div></div>
</div>
<div class="box1">
<div></div>
</div>
<div class="box1">
<div></div>
</div>
</body>
8.dom增删改的方法
-
document.createElement("标签名");
创建一个元素节点对象,并将其返回 -
document.createTextNode("文本内容");
用来创建新的文本内容,并将新的节点内容返回值返回 -
appendChild()
;向一个父节点中添加一个子节点。语法:父节点.appendChild(子节点);
-
insertBefore()
在指定父节点前添加新的子节点语法:父节点.insertBefore(新节点,旧节点);
-
replaceChild()
用指定子节点替换已有的子节点语法:父节点.replaceChild(新节点,旧节点);
-
removeChild()
删除一个子节点。语法 父节点.removeChild(子节点);
这个语法一定要有父节点。。。一般更建议
用这个,不需要写出父节点语法 :要删的节点.parentNode.removeChild(要删的节点)
-
用
innerHTML
也可以完成DOM的增删改
相关操作,有两种方法
1) 法1: 直接父节点.innerHTML += "子节点内容";
如:city.innerHTML += "<li>广州</li>";
但是不建议
用这种方法,一旦添加了新的,原先同级的元素全部被删除了重新添加。
2)法2.建议
使用这种方式
li.innerHTML = "广州"; //向li中设置文本 city.appendChild(li); //将li添加到city中
这个模块的例子在:`dom增删改.html`中
十五、样式
1. 获取内联样式:
- 通过
style属性设置的样式都是内联样式
,且内联样式有较高优先级,通过JS
修改的样式往往会立即显示。除了写了最高级的!important
- 通过JS修改元素的样式,
语法: 元素.style.样式名 = 样式值
。如果CSS样式名中有-
,则需要用驼峰命名法
,去掉-
,将-后的字母大写
读取元素样式 语法:元素.style.样式名
(按自己理解应该是:样式名.style.样式属性名)。但是无法
读取样式表中的样式
<style>
#box1 {
width: 100px;
height: 100px;
background-color: aqua;
}
</style>
<script>
window.onload = function () {
var box1 = document.getElementById("box1");
var btn01 = document.getElementById("btn01");
btn01.onclick = function () {
// 通过JS修改元素的样式,语法: 元素.style.样式名 = 样式值
// 如果CSS样式名中有-,则需要用驼峰命名法,去掉-,将-后的字母大写
box1.style.width = "300px";
box1.style.height = "300px";
box1.style.backgroundColor = "blue";
};
var btn02 = document.getElementById("btn02");
btn02.onclick = function () {
// 读取元素样式 语法:元素.style.样式名(按自己理解应该是:样式名.style.样式属性名)
// 但是无法读取样式表中的样式
alert(box1.style.backgroundColor);
}
};
</script>
</head>
<body>
<button id="btn01">按钮</button>
<button id="btn02">读取元素样式</button>
<div id="box1"></div>
</body>
2.1获取样式(只读)
- 一般浏览器读取样式表中的样式方式,这是
window的方法
,可以直接使用。语法:getComputedStyle(元素, null).样式属性名
返回值一般是一个对象,若是要返回具体信息,在后面添加.样式名。这两个参数,第一个:获取样式的元素。 第二个:可以传递一个伪元素,一般是null
- 考虑IE8(目前基本不用到),兼容性问题,用注释的优化法写。用到
getStyle()
<head>
<style>
#box1 {
width: 100px;
height: 100px;
background-color: aqua;
}
</style>
<script>
window.onload = function () {
var box1 = document.getElementById("box1");
var btn = document.getElementById("btn");
btn.onclick = function () {
// 一般浏览器读取样式表中的样式方式,这是window的方法,可以直接使用
// 语法:getComputedStyle(元素, null) 返回值一般是一个对象,若是要返回具体信息,在后面添加.样式名
// 这两个参数,第一个:获取样式的元素。 第二个:可以传递一个伪元素,一般是null
// alert(getComputedStyle(box1, null).width);
// 优化(考虑IE8的兼容问题)
var result = getStyle(box1, "width");
alert(result);
function getStyle(obj, name) {
if (window.getComputedStyle) {
return getComputedStyle(obj, null)[name];
} else {
return obj.currentStyle[name];
}
};
};
};
</script>
</head>
<body>
<button id="btn">按钮</button>
<div id="box1"></div>
</body>
2.2 修改样式(类的操作/class属性的修改)
推荐
:可以通过修改元素的class属性
来间接修改样式,即只要修改一次,即可同时修改多个样式。优点
:浏览器只
需要重新渲染页面一次
,性能更好
。并且能使表现和行为进一步分离
addClass() 方法
,用来向一个元素中添加
指定的class属性值。。。参数
:obj:要添加class属性的元素。
cn:要添加的class值`hasClass()
判断
一个元素是否含有指定的class属性值removeClass()
删除
指定 class属性toggleClass()方法
用来切换
一个类,如果有
该类,则删除
,没有则添加
<style>
.b1 {
width: 100px;
height: 100px;
background-color: aqua;
margin-top: 10px;
}
.b2 {
width: 200px;
height: 200px;
background-color: rgb(228, 48, 48);
margin-top: 10px;
}
</style>
<script>
// 修改box的class属性
// 可以通过修改元素的class属性来间接修改样式,即只要修改一次,即可同时修改多个样式。
// 浏览器只需要重新渲染页面一次,性能更好。并且能使表现和行为进一步分离
window.onload = function () {
var btn = document.getElementById("btn");
var btn01 = document.getElementById("btn01");
var btn02 = document.getElementById("btn02");
var box = document.getElementById("box");
btn.onclick = function () {
// 为box添加样式。
// 法1 使表现和行为不分离,性能差,每执行一次样式就渲染1次页面。
// box.style.width = "300px";
// box.style.height = "300px";
// 法2
// box.className = "b2";
// 对法2的升级 调用addClass()函数。添加class样式
addClass(box, "b2");
// toggleClass(box, "b2");
};
btn01.onclick = function () {
alert(hasClass(box, "b2"));
};
btn02.onclick = function () {
removeClass(box, "b2");
};
// addClass() 方法,用来向一个元素中添加指定的class属性值
// 参数:obj:要添加class属性的元素。 cn:要添加的class值
function addClass(obj, cn) {
// 检查是否有该属性
if (!hasClass(obj, cn)) {
obj.className += " " + cn;
}
}
// hasClass()判断一个元素是否含有指定的class属性值
function hasClass(obj, cn) {
var reg = new RegExp("\\b" + cn + "\\b");
return reg.test(obj.className);
}
// removeClass()删除指定 class属性
function removeClass(obj, cn) {
// 创建一个正则表达式
var reg = new RegExp("\\b" + cn + "\\b");
// 删除class
obj.className = obj.className.replace(reg, "");
}
// toggleClass()方法用来切换一个类,如果有该类,则删除,没有则添加
function toggleClass(obj, cn) {
if (hasClass(obj, cn)) {
removeClass(obj, cn);
} else {
addClass(obj, cn);
}
}
};
</script>
</head>
<body>
<button id="btn">添加按钮</button>
<button id="btn01">检查按钮</button>
<button id="btn02">删除按钮</button>
<div id="box" class="b1"></div>
</body>
3.其他样式相关的属性(只读,不可修改)
clientHeight
获取元素可见高度
;clientHeight
获取元素可见宽度。获取的值不带px
,可
以直接进行计算
。并且获取的高度和宽度只包含内边距
和内容区的大小
,外边距和边框大小不包括。例如 alert(box1.clientHeight);offsetParent
获取当前元素的定位父元素
。 获取到离当前元素最近的开启了定位
的祖先元素。若所有祖先元素都没
开启定位则,则返回body
。例如:alert(box2.offsetParent);offsetLeft
获取当前元素相对于其定位父元素的水平偏移量
;offsetTop
获取当前元素相对于其定位父元素的垂直偏移量。例如:alert(box1.offsetTop);offsetHeight
获取元素的整个高度
;offsetWidth 获取元素的整个宽度。包括内容区,内边距,边框
。例如:alert(box1.offsetHeight);scrollHeight
获取元素整个滚动区域的高度
;scrollWidth
获取元素整个滚动区域的宽度。例如:alert(box3.scrollWidth);scrollLeft
获取水平滚动条的距离
;scrollTop
获取垂直滚动条的距离。例如: alert(box3.scrollLeft);chrome
认为浏览器的滚动条
是body
的,可以通过body.scrollTop
获取。但火狐等
认为浏览器的滚动条是html
的,documentElement.scrollTop
获取- 常应用:
当obj.scrollHeight - obj.scrollTop == obj.clientHeight
说明垂直滚动条滚到底
了。
当obj.scrollWidth - obj.scrollLeft == obj.clientWidth
说明水平滚动条滚到底
了。 clientX和clientY
获取鼠标
在当前的可见窗口的坐标。
div的偏移量是相对整个页面的。所以他们两会因为滚动条的滚动,而使鼠标离div左顶点的位置有一段和滚动条一样的距离pageX和pageY
可以获取鼠标
相对于当前页面的坐标,但是在ie8不兼容,正常不需要考虑这两个的例子在div跟着鼠标移动.html
)
<head>
<style>
#box1 {
width: 100px;
height: 100px;
background-color: aqua;
padding: 10px;
border: 10px solid black;
margin: 10px;
}
#box3 {
width: 200px;
height: 200px;
background-color: aqua;
overflow: auto;
}
#box4 {
width: 400px;
height: 400px;
background-color: rgb(7, 134, 24);
}
</style>
<script>
window.onload = function () {
var btn01 = document.getElementById("btn01");
var box1 = document.getElementById("box1");
var box2 = document.getElementById("box2");
var box3 = document.getElementById("box3");
var box4 = document.getElementById("box4");
btn01.onclick = function () {
// clientHeight 获取元素可见高度
// clientHeight 获取元素可见宽度
// 获取的值不带px,可以直接进行计算。并且获取的高度和宽度只包含内边距和内容区的大小,外边距和边框大小不包括
// alert(box1.clientHeight);
// alert(box1.clientHeight);
// offsetParent 获取当前元素的定位父元素
// 获取到离当前元素最近的开启了定位的祖先元素。若所有祖先元素都没开启定位则,则返回body
// alert(box2.offsetParent);
// alert(box2.offsetParent.id);
// offsetLeft 获取当前元素相对于其定位父元素的水平偏移量
// offsetTop 获取当前元素相对于其定位父元素的垂直偏移量
// alert(box1.offsetTop);
// offsetHeight 获取元素的整个高度
// offsetWidth 获取元素的整个宽度
// 包括内容区,内边距,边框
// alert(box1.offsetHeight);
// scrollHeight 获取元素整个滚动区域的高度
// scrollWidth 获取元素整个滚动区域的宽度
// alert(box3.scrollWidth);
// scrollLeft 获取水平滚动条的距离
// scrollTop 获取垂直滚动条的距离
// alert(box3.scrollLeft);
// alert(box3.clientHeight); //183
// 当obj.scrollHeight - obj.scrollTop == obj.clientHeight说明垂直滚动条滚到底了。
// 当obj.scrollWidth - obj.scrollLeft == obj.clientWidth说明水平滚动条滚到底了。
alert(box3.scrollHeight - box3.scrollTop); //400
};
};
</script>
</head>
<body>
<button id="btn01">按钮</button>
<div id="box1" style="position: relative;">
<div id="box2" style="position: absolute;"> </div>
</div>
<div id="box3">
<div id="box4"></div>
</div>
</body>
十五、BOM
15.1 简介
- BOM是浏览器对象模型,BOM让我们通过JS来操作浏览器
- 在BOM中为我们提供一组对象,用来完成对浏览器的操作
15.2 BOM对象(5个)
Window
代表整个浏览器窗口
,同时window也是网页中的全局对象Navigato
r代表的是当前浏览器的信息
,通过该对象来识别不同的浏览器
- Navigator 代表当前浏览器的信息,通过对象可以来识别不同的浏览器。 由于历史原因,Navigator对象中的大部分属性已经不能帮我们识别浏览器。一般只会用userAgent(字符串)来判断浏览器的信息
Location
代表当前浏览器的地址栏信息
,通过Location可以获取地址栏信息,或者操作浏览器跳转页面
alert(location)
; //直接返回当前页面的完整地址
(url)assign()
跳转到其他页面,作用和直接修改location一样,且可
以跳转后回退
。如: location.assign("DOM.html");
reload()
重新加载页面,作用同刷新,但是不会清空缓存,除非在方法中传递一个true,作为参数,强制清空缓存。如:location.reload(true);
replace()
用新的页面替换当前页面,调用完毕也会跳转页面。但不会回退
(因为不会生成历史记录)如:location.replace("DOM.html");
History
代表浏览器的历史记录
,通过该对象来操作浏览器的历史记录,但是不能获取到具体的记录,只能向前/向后翻页。且只在当次访问时有效
length 属性
代表当前访问链接的数量back()
退回到上一个页面,相当于浏览器的回退按钮forward()
跳转到下一个页面,相当于浏览器的前进按钮go()
退回/前进到第n个页面,n为整数
,正
整数代表前进
,负
整数代表后退
Screen
代表用户的屏幕的信息
,通过该对象可以获取到用户的显示器的相关信息- 这些BOM对象在浏览器中都作为window对象的属性保存,可以
通过window对象使用,也可以直接使用
15.3 JavaScript Timing事件(定时器和延时器)
15.3.1 定时器
定时器
:可以让一段程序,每隔一段时间执行一次setInterval() 定时调用
。可以将一个函数,每隔一段时间执行一次。参数
:1.回调函数
,该函数每隔一段时间被调用一次。2
.每次调用间隔的时间
,单位:毫秒
。 该方法的返回值
:返回一个Number类型的数据,这个数字用来作为定时器的唯一标识
clearInterval(参数);
关闭
定时器。参数
为定时器的标识
(同上的参数)。clearInterval可以接收任意数据类型参数
,如果该参数不是一个有效标识,则什么都不做
<head>
<script>
window.onload = function () {
var count = document.getElementById("count");
var num = 1;
var time = setInterval(function () {
count.innerHTML = num++;
if (num == 6) //当num==6时。关闭定时器,此时6不会被显示出来
{
// clearInterval(参数); 关闭定时器。参数为定时器的标识。
clearInterval(time);
}
}, 1000);
console.log(time);
};
</script>
</head>
<body>
<h1 id="count"></h1>
</body>
15.3.2 延时器(延时调用)
延时调用:语法:setTimeout(function () { }, 3000);
:延时调用一个函数不马上执行,而是等一段时间后再执行,且只会执行一次
- 使用
clearTimeout(参数)
来关闭
一个延时调用 - 延时调用和定时调用的
区别
:延时调用只会执行一次,而定时调用会执行多次 - 延时调用和定时调用实际
可以互相代替
<head>
<script>
window.onload = function () {
var num = 1;
var timer = setTimeout(function () {
console.log(num++);
}, 3000);
// 使用clearTimeout()来关闭一个延时调用
clearTimeout(timer);
};
</script>
</head>
十六、JSON
- 产生原因:JS 中的对象只有JS自己认识,其他语言都不认识。
- JSON就是一个
特殊格式的字符串
,这个字符串可以被任意语言识别
,并且可以转换为任意语言中的对象
- JSON
作用
:在开发中主要用来数据的交互
- JSON介绍:JavaScript Object Notation(JavaScript 对象标记法)。是一种存储和交换数据的语法。 是通过 JavaScript 对象标记法书写的文本。
- JSON和JS对象的格式一样,只不过JSON字符串中的
属性名必须添加双引号
,且对象不包括也不能是函数对象
- JSON 类:
1.对象{}
2.数组[]
- JSON
允许的值
:1.字符串 2.数值 3.布尔值 4.null 5.对象 6.数组
<script>
// json
var obj = '{"name":"小小","age":5}';
var arr = '[2,5,6,"hhhh",true]';
console.log(typeof obj);
console.log(arr);
// JSON是js提供的一个工具类
// JSON.parse() 把 JSON 转换为 js对象。
alert(JSON.parse(obj));
alert(JSON.parse(obj).name);
var obj1 = { name: "小小", age: 5 };
// JSON.stringify() 把 js对象 转换为 JSON,会返回一个JSON字符串
console.log(JSON.stringify(obj1));
</script>