一、js编写位置
1、可以将js编写到标签的onclick属性中,如下所示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--可以将js编写到标签的onclick属性中-->
<button onclick="alert('讨厌,点我干嘛')">点我一下</button>
</body>
</html>
2、可以将js代码写在超链接的href属性中,这样当点击超链接时会执行js代码,如下所示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--可以将js代码写在超链接的href属性中,这样当点击超链接时会执行js代码-->
<a href="javascript:alert('让你点你就点!!!');">你也点我一下</a>
</body>
</html>
3、可以将JS代码编写到script标签中,如下所示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--可以将JS代码编写到script标签中-->
<script type="text/javascript">
alert('我是script标签中的代码!!')
</script>
</head>
<body>
</body>
</html>
4、可以将JS代码编写到外部JS文件中,然后通过script标签引入,script标签一旦用于引入外部文件了,就不能再编写代码了,即使编写了浏览器也会忽略。如果需要则可以再创建一个新的script标签用于编写内部代码,如下所示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--
可以将JS代码编写到外部JS文件中,然后通过script标签引入,
script标签一旦用于引入外部文件了,就不能再编写代码了,即使编写了浏览器也会忽略。
如果需要则可以再创建一个新的script标签用于编写内部代码
-->
<script type="text/javascript" src="../js/script.js"></script>
</head>
<body>
</body>
</html>
二、js数据类型
数据类型指的是字面量的类型,在JS中一共有6中数据类型,分别是:
基本数据类型:
String 字符串
Number 数值
Boolean 布尔值
Null 空值
Undefined 未定义
引用数据类型:
Object 对象
1、String
2、Number
● 包括整数和浮点数(小数)
● 在JS中可以使用 typeof 检测一个变量的类型,语法:typeof 变量
● JS中可以表示的数字的最大值:Number.MAX_VALUE,如果使用Number表示的数字超过了最大值,则会
返回一个 Infinity 表示正无穷,使用 typeof Infinity 也会返回 number
● JS中可以表示的数字的最小值:Number.MIN_VALUE,值是 5e-324,它是大于0的最小值
● 除了 Infinity 表示正无穷以外,还有 - Infinity 表示负无穷
● 如 var a = “abc” * “bcd” 这样的语法,算出来的值是 NaN,表示 Not A Number(不是一个数字),使用
typeof NaN 也会返回 number
3、Boolean
4、Null
● Null 类型的值只有一个,就是 null。null 这个值专门用来表示一个为空的对象,如:
var a = null,但是 typeof null 输出是 object
5、Undefined
● Undefined 类型的值也只有一个,就是 undefined,它表示未定义,即声明了一个变量,但是未赋值,
如:var b; console.log(b),此时输出就是 undefined,使用 typeof undefined 也是返回 undefined
● 注意 console.log(null == undefined) 输出为 true
6、Object
三、js强制类型转换
1、将其他数据类型转换为String
方式1:调用被转换数据类型的 toString() 方法,但是注意,null和undefined这两个值没有 toString() 方法
<script type="text/javascript">
var a = 123;
//a.toString() 这种方式是将a临时包装为Number对象,然后调用对象的toString方法
var b = a.toString();
console.log(typeof b);
console.log(b)
</script>
方式2:调用 String() 函数,并将被转换的数据作为参数传递给函数。注意,对于 Number 和 Boolean 实际
上就是调用的 toString() 方法,但是对于 null 和 undefined 就不会调用 toString() 方法,它会将 null 和
undefined 直接转换为 “null” 和 “undefined”,如:
<script type="text/javascript">
var i = 222;
var j = String(i);
console.log(typeof j);
console.log(j);
console.log(typeof String(null));
console.log(String(null))
</script>
2、将其他数据类型转换为Number
方式1:调用 Number() 函数
● 调用 Number() 函数,如:
<script type="text/javascript">
var a = "123";
var b = Number(a);
console.log(typeof b);
console.log(b)
</script>
● 如果 a 不是一个数字,而是一个字母或者其他的字符,也会转换为 Number 类型,但是值是 NaN,如:
<script type="text/javascript">
a = "abc";
b = Number(a);
console.log(typeof b);
console.log(b)
</script>
结果是:number NaN
● 如果 a 是一个空串或者全部是空格,它会转换为 0,如:
<script type="text/javascript">
a = ""
b = Number(a);
console.log(typeof b);
console.log(b)
</script>
结果是:number 0
● 如果 a 是一个布尔值,true 会转换为1,false 会转换为 0,如:
<script type="text/javascript">
a = true;
b = Number(a);
console.log(typeof b);
console.log(b)
a = false;
b = Number(a);
console.log(typeof b);
console.log(b)
</script>
● 如果 a 是 null,转换为数字后为 0,如果 a 是 undefined,转换为数据后为 NaN
方式2:这种方式专门用来对付字符串,如 “123px”,“12.54abc”
parseInt():把一个字符串转换为一个整数
parseFloat():把一个字符串转换为一个浮点数
<script type="text/javascript">
var a = "123px";
var b = parseInt(a);
console.log(typeof b) //number
console.log(b) //123
var a = "123.45px";
var b = parseInt(a);
console.log(typeof b) //number
console.log(b) //123
var a = "123.23px";
var b = parseFloat(a);
console.log(typeof b) //number
console.log(b) //123.23
</script>
JS中的进制:
● 16进制表示:以 0x 开头,如:0xff,0x10
● 8进制表示:以 0 开头,如:070,032
● 2进制表示:以 0b 开头,如:0b10,但是不是所有浏览器都支持
在浏览器中,执行如下代码:
<script type="text/javascript">
var a = "070";
var b = parseInt(a);
console.log(b)
</script>
不同浏览器会解析不同,有的根据8进制解析(56),有的根据10进制解析(70),这样就会出现不同的结果,
为了解决这个问题,可以在 parseInt()函数中多传递一个参数,指定根据什么进制解析,如:
var a = "070";
var b = parseInt(a, 10) //以10进制解析
3、将其他数据类型转换为Boolean
将其他的数据类型转换为Boolean,使用Boolean()函数即可
● 数字转 Boolean,除了0和NaN,其他的都是true,如:
<script type="text/javascript">
/*
* 将其他的数据类型转换为Boolean
* - 使用Boolean() 函数
* */
var a = 123; //true
a = -123; //true
a = 0; //false
a = NaN; //false
a = Boolean(a);
console.log(typeof a);
console.log(a)
</script>
● 字符串转Boolean,除了空串(“”)以外,其他的都是true,包括空格,如:
<script type="text/javascript">
var b = "abc"; //true
b = " " //true
b = "" //false
b = Boolean(b);
console.log(typeof b);
console.log(b)
</script>
● null和undefined转换为Boolean,都是false
四、js的对象
1、对象的分类
● 内建对象:由ES标准中定义的对象,在任何的ES实现中都可以使用,如:
Math,String,Number,Boolean,Function,Object…
● 宿主对象:由JS的运行环境提供的对象,目前来讲主要指由浏览器提供的对象,如:
BOM,DOM
● 自定义对象:由开发人员自己创建的对象
2、对象的基本操作
● 创建对象:
使用 new 关键字调用的函数,是构造函数 constructor,构造函数是专门用来创建对象的函数
var obj = new Object();
● 向对象添加属性:在对象中保存的值称为属性
var obj = new Object();
obj.name = "孙悟空";
● 读取对象中的属性,如果读取对象中没有的属性,不会报错,而是返回 undefined
var obj = new Object();
obj.name = "孙悟空";
console.log(obj.name)
● 删除对象中的属性
var obj = new Object();
obj.name = "孙悟空";
delete obj.name
● 如果要使用特殊的属性名,不能采用 . 的方式操作,需要使用另一种方式,语法:
对象[“属性名”] = 属性值,如:
var obj = new Object();
obj["123"] = 555;
console.log(obj.123) //报错
console.log(obj["123"]) //取的时候也要用[]获取
3、对象的字面量
● 使用对象字面量来创建一个对象,如:
var obj = {}
● 使用对象字面量,可以在创建对象时,直接指定对象中的属性,属性名可以加双引号也可以不加,建议不加
但是如果要使用特殊的符号作为属性名时,需要使用双引号,如:
var obj = {
name: "猪八戒",
age: 34,
"@$$#@": "hello"
}
4、对象的属性值可以是函数
var obj = new Object();
obj.name = "孙悟空";
obj.sayName = function(){
console.log(obj.name);
}
//调用
obj.sayName();
var obj2 = {
name: "猪八戒";
sayName: function(){
console.log(obj2.name)
}
}
5、枚举对象中的属性
语法:
使用 for … in 语句
var obj = {
name: "孙悟空",
age: 13,
gender: "男",
address: "花果山"
}
for(var n in obj){
console.log(n); //将对象中的属性名打印出来:name age gender address
consoel.log(obj[n]) //打印属性值
}
6、构造函数
构造函数和普通函数没什么区别,不同的是构造函数习惯上首字母大写;
构造函数和普通函数的区别就是调用方式不同,普通函数是直接调用,而构造函数需要使用new关键字来调
用
构造函数的执行流程:
①、立刻创建一个新的对象
②、将新建的对象设置为函数中 this,在构造函数中可以使用this来引用新建的对象
③、逐行执行函数中的代码
④、将新建的对象作为返回值返回
function Person(name, age, gender){
this.name = name;
this.age = age;
this.gender = gender;
this.sayName = function(){
alert(this.name)
}
}
var per = new Person("孙悟空", 18, "男");
console.log(per)
7、构造函数的修改
使用上面方式创建对象时,每个对象中的 sayName 方法都是不一样的,即每创建一个对象都会有一个
sayName 方法,而 sayName 这个方法都是一模一样的,没有必要创建这么多次,我们可以在全局作用域
中创建 sayName 函数,然后构造函数中的sayName属性指向全局作用域中的 sayName即可
function Person(name, age, gender){
this.name = name;
this.age = age;
this.gender = gender;
this.sayName = fun
}
function fun(){
alert(this.name)
}
var per = new Person("孙悟空", 18, "男");
console.log(per)
注意:使用这种方式也是不好的,它污染了全局作用域的命名空间,而且定义在全局作用域中也是很不安全
的,我们可以使用下面说的原型来进行进一步修改完善
五、js的函数
1、创建函数
方式1:使用构造函数创建函数对象
var fun = new Function();
可以将要封装的代码以字符串的形式传递给构造函数,如:
var fun = new Function("console.log('Hello 这是我的第一个函数')");
//调用
fun();
//打印
console.log(fun)
//可以在函数对象中添加属性
fun.hello = "Hello";
console.log(fun.hello)
方式2:使用函数声明创建函数对象
语法:
function 函数名([形参1,形参2,…,形参N]){
}
function fun2(value){
console.log(value)
}
方式3:使用函数表达式创建函数
var fun = function(value1, value2){
}
2、匿名函数
function(){
}
3、立即执行函数
立即执行函数在创建完后就执行了 ,立即执行函数只会调用一次
(function(value){
console.log(value)
})(1)
六、js的作用域
1、全局作用域
● 直接编写在script标签中的 JS 代码,都是全局作用域
● 全局作用域在页面打开时创建,在页面关闭时销毁
● 在全局作用域中有一个全局对象 window,我们可以直接使用,它代表的是一个浏览器窗口,由浏览器创建
● 在全局作用域中,创建的变量都会作为 window 对象的属性保存
● 在全局作用域中,创建的函数都会作为 window 对象的方法保存
● 全局作用域中的变量都是全局变量,在页面的任意部分都可以访问的到
2、函数(局部)作用域
● 调用函数时创建函数作用域,函数执行完毕以后,函数作用域销毁
● 每调用一次函数就会创建一个新的函数作用域,他们之间是互相独立的
● 在函数作用域中可以访问到全局作用域的变量,但是在全局作用域中无法访问到函数作用域的变量
● 当在函数作用域操作一个变量时,它会先在自身作用域中寻找,如果有就直接使用,如果没有则向上一级作
用域中寻找,直到找到全局作用域,如果全局作用域中依然没有找到,则会报错 ReferenceError
注意下面这段代码:
var e = 33
function fun(e){
alert(e)
}
fun() //调用后打印的是undefined,这是因为在定义函数数,如果有形参,那么形参相当于已经定义了
3、变量的声明提前
使用 var 关键字声明的变量,会在所有的代码执行之前被声明(但是不会赋值),但是如果声明变量时不使用
var 关键字,则变量不会被声明提前
在函数作用域中也有声明提前的特性,使用 var 关键字声明的变量,会在函数中所有的代码执行之前被声明
<script type="text/javascript">
var a = 123
console.log(a) //打印出123
b = 123
console.log(b) //也是打印123,它相当于 window.b = 123
console.log(c) //此处会报错,因为c没有定义
c = 123
console.log(d) //不会报错,会打印出 undefined,这是因为使用var声明的变量会声明提前
var d = 123
function fun(){
console.log(e) //不会报错,会打印 undefined
var e = 35
}
</script>
4、函数的声明提前
使用函数声明形式创建的函数 function 函数名(){},它会在所有的代码执行之前就被创建,所以我们可以在函
数声明前来调用函数
使用函数表达式创建的函数,不会被声明提前,所以不能在声明前调用;
在函数作用域中也有函数声明提前的特性
<script type="text/javascript">
fun1(); //不会报错,可以正常执行
fun2(); //报错
function fun1(){
console.log("fun1")
}
var fun2 = function(){
console.log("fun2")
}
function fun3(){
fun4(); //不会报错
function fun4(){
}
}
</script>
七、原型
我们所创建的每一个函数,解析器都会向函数中添加一个属性 prototype,这个属性对应着一个对象,这个对象
就是我们所谓的原型对象
如果函数作为普通函数调用 prototype 没有任何作用
当函数以构造函数的形式调用时,它所创建的对象中都会有一个隐含的属性,指向该构造函数的原型对象,我
们可以通过 __proto__来访问该属性
原型对象就相当于一个公共的区域,所有同一个类的实例都可以访问到这个原型对象,我们可以将对象中共有
的内容统一设置到原型对象中
当我们访问对象的一个属性或者方法时,它会先在对象自身中寻找,如果有则直接使用,如果没有则会去原型
对象中寻找,如果找到则直接使用
function MyClass(){ //它有一个属性 prototype
}
var mc = new MyClass();
var mc2 = new MyClass();
console.log(mc.__proto__ == MyClass.prototype) //返回true
console.log(mc2.__proto__ == MyClass.prototype) //返回true
MyClass.prototype.a = 123
console.log(mc.a) //打印123
使用 in 检查对象中是否含有某个属性时,如果对象中没有但是原型中有,也会返回 true
function MyClass(){
}
MyClass.prototype.name = "我是原型中的名字";
var mc = new MyClass();
console.log("name" in mc) //打印true
可以使用对象的 hasOwnProperty()函数来检查对象自身中是否含有该属性
console.log(mc.hasOwnProperty("name")) //false
console.log(mc.hasOwnProperty("hasOwnProperty")) //false
从对象中寻找属性时,会一直往原型找,如果原型没有再去原型的原型找,直到找到Object的原型,Object对
象的原型没有原型,如果在Object的原型中依然没有找到,则会返回undefined
console.log(mc.__proto__.__proto__.__proto__) //null
八、数组
1、创建数组对象
数组中可以存基本数据类型,也可以存放对象,函数,数组
方式1:
var arr = new Array();
console.log(typeof arr) //返回 object
var arr1 = new Array(10,20,30)
console.log(arr1) //打印 10,20,30;表示创建长度为3的数组
var arr2 = new Array(10) //里面只有一个参数时,这种方式表示创建一个长度为10的数组
console.log(arr2) //打印 ,,,,,,,,,
方式2:使用字面量创建数组
var arr = [1,2,'abc',true]
2、添加元素
var arr = new Array();
console.log(typeof arr) //返回 object
arr[0] = 10
arr[1] = 20
console.log(arr)
console.log(arr[3]) //如果读取不存在的索引,它不会报错,而是返回undefined
3、获取数组长度
对于非连续的数组,使用length会获取到数组的最大的索引加1;
修改length:
如果修改的length大于原长度,则多出的部分会空出来
如果修改的length小于原长度,则多出的元素会被删除
var arr = new Array();
console.log(typeof arr) //返回 object
arr[0] = 10
arr[1] = 20
console.log(arr.length) //2
arr[90] = 11
console.log(arr.length) //91
4、数组的四个方法
● push:该方法可以向数组的末尾添加一个或多个元素,并返回数组的新长度。可以将要添加的元素作为方
法的参数传递,这样这些元素将会自动添加到数组的末尾
//创建一个数组
var arr = ["孙悟空", "猪八戒", "沙和尚"]
var result = arr.push("唐僧", "蜘蛛精", "白骨精")
console.log(arr)
console.log("result= " + result) //6
● pop:该方法可以删除数组的最后一个元素,并将被删除的元素作为返回值返回
var arr1 = ["刘备", "关羽", "张飞", "诸葛亮"]
result = arr1.pop()
console.log(arr1) //"刘备", "关羽", "张飞"
console.log(result) //诸葛亮
● unshift:向数组的开头添加一个或多个元素,并返回新的数组长度
var arr2 = ["刘备", "孙权", "曹操"]
result = arr2.unshift("孙策", "曹丕")
console.log(arr2) //"孙策", "曹丕", "刘备", "孙权", "曹操"
console.log(result) //4
● shift:可以删除数组的第一个元素,并将被删除的元素作为返回值返回
var arr3 = ["宋江", "武松", "鲁智深"]
result = arr3.shift();
console.log(arr3) //"武松", "鲁智深"
console.log(result) //宋江
5、数组的遍历
方式1:使用 for 循环进行遍历
方式2:使用 forEach 进行遍历
一般我们都是使用 for 循环去遍历数组,JS 中还为我们提供了一个方法,用来遍历数组,就是 forEach,
但是注意:这个方法只支持 IE8 以上的浏览器
forEach() 方法需要一个函数作为参数,这种函数称为回调函数,数组中有几个元素函数就会执行几次,每
次执行时,浏览器将会遍历到的元素以实参的形式传递进来,我们可以定义形参,来读取这些内容;
浏览器会在回调函数中传递三个参数:
第一个参数,就是当前正在遍历的元素
第二个参数,就是当前正在遍历的元素的索引
第三个参数,就是正在遍历的数组
<script type="text/javascript">
//创建一个数组
var arr = ["孙悟空", "猪八戒", "沙和尚"]
arr.forEach(function (value, index, obj) {
console.log(value + ", " + index + ", " + obj)
})
</script>
6、slice和splice
● slice():可以用来从数组提取指定元素,该方法不会改变元素数组,而是将截取到的元素封装到一个数组中
返回,它有两个参数,参数如下:
1. 截取开始的位置的索引(包含)
2. 截取结束的位置的索引(不包含),第二个参数可以省略不写,此时会截取从开始索引(包含)往后的
所有元素;还可以传递一个负值,如果传递一个负值,则从后往前计算
-1 表示倒数第二个,-2 表示倒数第三个
<script type="text/javascript">
var arr = ["孙悟空", "猪八戒", "沙和尚", "蜘蛛精", "玉兔精"]
var result = arr.slice(0, 2)
console.log(arr) //"孙悟空", "猪八戒", "沙和尚", "蜘蛛精", "玉兔精"
console.log(result) //"孙悟空", "猪八戒"
result = arr.slice(1)
console.log(result) //"猪八戒", "沙和尚", "蜘蛛精", "玉兔精"
result = arr.slice(1, -1)
console.log(result) //"猪八戒", "沙和尚", "蜘蛛精"
</script>
● splice():可以用于删除数组中的指定元素并添加新元素;使用 splice 会影响到原数组,会将指定元素从原
数组中删除,并将被删除的元素作为返回值返回
参数:
第一个:表示开始位置的索引
第二个:表示删除的数量
第三个及以后:可以传递一些新的元素,这些新的元素将会自动插入到第一个参数的位置的前边
<script type="text/javascript">
var arr = ["孙悟空", "猪八戒", "沙和尚", "蜘蛛精", "玉兔精"]
var result = arr.splice(0, 2)
console.log(arr) //"沙和尚", "蜘蛛精", "玉兔精"
console.log(result) //"孙悟空", "猪八戒"
var arr2 = ["牛魔王", "铁扇公主", "红孩儿"]
result = arr2.splice(1, 0, "如来", "观音")
console.log(arr2) //""牛魔王", "如来", "观音", "铁扇公主", "红孩儿"
console.log(result) //""
</script>
7、数组的其他方法
● concat ():可以连接两个或多个数组,并将新的数组返回,该数组不会将原数组产生影响
var arr = ["孙悟空", "猪八戒"]
var arr2 = ["白骨精", "玉兔精"]
var arr3 = ["二郎神", "太上老君"]
var result = arr.concat(arr2)
console.log(result) //"孙悟空", "猪八戒", "白骨精", "玉兔精"
console.log(arr) //"孙悟空", "猪八戒"
console.log(arr2) //"白骨精", "玉兔精"
result = arr.concat(arr2, arr3, "牛魔王")
console.log(result) //"孙悟空", "猪八戒", "白骨精", "玉兔精", "二郎神", "太上老君", "牛魔王
● join():该方法可以将数组转换为一个字符串,该方法不会对原数组产生影响,而是将转换后的字符串作为
结果返回;在 join 中可以指定一个字符串作为参数,这个字符串将会成为数组中元素的连续符
var arr = ["孙悟空", "猪八戒", "沙和尚"]
result = arr.join()
console.log(result) //孙悟空, 猪八戒, 沙和尚
console.log(typeof result) //string
result = arr.join("==")
console.log(result) //孙悟空==猪八戒==沙和尚
● reverse():该方法用来反转数组,前边的去后边,后边的去前边,该方法会对原数组产生影响
var arr = ["孙悟空", "猪八戒", "沙和尚"]
arr.reverse()
console.log(arr) //""沙和尚", "猪八戒", 孙悟空"
● sort():该方法用来对数组中的元素进行排序,它会影响原数组,默认使用 unicode 编码排序;
对于纯数字的数组,使用 sort() 排序时,也会按照 Unicode 编码来排序,所以对数字进行排序时,可能会
得到错误的结果;我们可以自己来指定排序的规则,我们可以在 sort() 方法中添加一个回调函数,用来
指定排序规则,回调函数中需要定义两个参数,浏览器将会分别使用数组的元素作为实参调用回调函
数,如果返回一个大于0的值,则元素会交换位置,如果返回一个小于0的值,则元素位置不变,如果返
回0,也不交换位置
var arr = ["b", "d", "e", "a", "c"]
arr.sort()
console.log(arr) //"a", "b", "c", "d", "e"
/***************************************************************************************/
var arr = [5, 7, 3, 6, 11]
arr.sort()
console.log(arr) //11,3,5,6,7
/***************************************************************************************/
var arr = [5, 3, 11, 44, 33]
arr.sort(function (a, b) {
return a - b;
})
console.log(arr) //[3, 5, 11, 33, 44]
九、函数的方法
call() 和 apply():
● 这两个方法都是函数对象的方法,需要通过函数对象来调用
● 当对函数调用 call() 和 apply() 都会调用函数执行
● 在调用 call() 和 apply() 可以将一个对象指定为第一个参数,此时这个对象将会成为函数执行时的this
● call() 方法可以将实参在对象之后依次传递
● apply() 方法需要将实参封装到一个数组中统一传递
function fun1() {
alert("我是fun函数")
}
fun1.call() //调用fun函数
fun1.apply() //调用fun函数
fun1() //这个和上面两个是一样的调用
/***************************************************************************************/
function fun2() {
alert(this)
}
var obj = {}
fun2() //此时调用时,打印的this是window
fun2.call(obj) //此时函数中的this是 obj 对象
fun2.apply(obj) //此时函数中的this是 obj 对象
/***************************************************************************************/
function fun3(a, b){
console.log("a= " + a)
console.log("b= " + b)
}
var obj = {}
fun3.call(obj, 2, 3)
//fun3.apply(obj, 2, 3) //会报错
fun3.apply(obj, [2, 3])
十、this的情况
1、以函数调用时,this永远都是window
2、以方法的形式调用时,this是调用方法的对象
3、以构造函数的形式调用时,this是新创建的那个对象
4、使用 call 和 apply 调用时,this是指定的那个对象
十一、arguments
在调用函数时,浏览器每次都会传递两个隐含的参数:
1、函数的上下文对象 this
2、封装实参的对象 arguments
● arguments 是一个类数组对象,它也可以通过索引来操作数据
● arguments.length 可以获取长度
● 在调用函数时,我们所传递的实参都会在arguments中保存
● 即使我们不定义新参,也可以获取实参
● 它里面有一个属性 callee,这个属性对应一个函数对象,就是当前正在执行的函数的对象
<script type="text/javascript">
function fun() {
console.log(arguments)
console.log(arguments.callee)
for(var i = 0 ; i < arguments.length ; i++){
console.log(arguments[i])
}
}
fun("hello", true)
</script>
十二、包装类
在JS中为我们提供了三个包装类,通过这三个包装类可以将基本数据类型的数据转换为对象,分别是:
String:可以将基本数据类型字符串转换为String对象
Number:可以将基本数据类型数字转换为Number对象
Boolean:可以将基本数据类型布尔值转换为Boolean对象
十三、正则表达式
1、创建正则表达式对象
语法:var 变量 = new RegExp(“正则表达式”, “匹配模式”)
var reg = new RegExp("a")
console.log(reg) // 打印 /a/
正则表达式的方法:
test()
使用这个方法可以用来检测一个字符串是否符合正则表达式的规则,如果符合则返回true,否则返回
false
var reg = new RegExp("a") //这个正则表达式可以用来检测字符串中是否含有a
console.log(reg) // 打印 /a/
var str = "a"
var result = reg.test(str)
console.log(result) //true
在构造函数中可以传递一个匹配模式作为第二个参数,可以是 i 和 g
i:表示忽略大小写
g:表示全局匹配模式
var reg = new RegExp("a", "i")
str = "Abc"
result = reg.test(str)
console.log(result) //true
2、使用字面量创建正则表达式
语法:var 变量 = /正则表达式/匹配模式 ------注意:没有加引号,不是字符串
var reg = /a/i;
console.log(reg.test("Abc")) //true
3、正则表达式举例
//创建一个正则表达式,检测一个字符串中是否有a或b或c
//[]里面的内容也是或的关系
//[0-9] 表示0到9任意的数字
var reg = /a|b|c/ 或者 var reg /[abc]/
//创建一个正则表达式,检测一个字符串中是否有字母
var reg = /[A-z]/ 或者 var reg = /[A-Z]/i
//检测一个字符串中是否含有 abc 或 adc 或 aec
var reg = /a[bde]c/
//[^ ]表示除了的意思,如 [^ab] 表示找除了ab以外的字符
console.log(/[^ab]/.test("abc")) //返回true,因为除了ab以外有一个c
//通过量词可以设置一个内容出现的次数,量词只对它前边的一个内容起作用
//{n}:表示正好出现n次
var reg = /a{3}/ //表示a出现3次,即aaa
var reg = /ab{3}/ //匹配abbb
var reg = /ab{3}c/ //匹配abbbc
//{m, n} 表示出现 m 到 n 次,如 {1,3} 表示可以出现1次,出现2次,出现3次
var reg = /ab{1,3}/ //可以匹配ab,abb,abbb
//{m, } 表示出现m次以上
//+表示至少一个,相当于{1, }
var reg = /ab+c/ //表示b至少出现1次
//*表示至少出现0个,相当于{0,}
var reg = /ab*c/ //表示b可以是0个或多个
//?表示0个或1个,相当于{0,1}
var reg = /ab?c/ //表示可以匹配ac或abc
//检查一个字符串是否以a开头
var reg = /^a/
//检查是否以a结尾
var reg = /a$/
//检查一个字符是否含有.
//在正则表达式规则中.表示任意字符,我们可以在正则表达式中使用\作为转义字符,\. 来表示.
var reg = /\./
var reg = new RegExp("\.") //这种不能转义,在构造函数中,传入的参数是字符串,字符串中的\也需要使用转义字符表示,所以要使用下面的方式
var reg = new RegExp("\\.")
//\w: 任意字母、数字、_, 相当于[A-z0-9_]
//\W: 除了字母、数字、_, 相当于[^A-z0-9_]
//\d: 任意的数字, 相当于[0-9]
//\D: 除了数字, 相当于[^0-9]
//\s: 空格
//\S: 除了空格
//\b: 单词边界
//\B: 除了单词边界
//举例1:判断是否是单词child
var reg = /\bchild\b/
//举例2:去除单词前后空格
var reg = /^\s*|\s*$/g
4、字符串的正则表达式
● split():可以将一个字符串拆分为一个数组,这个方法即使不指定全局匹配也会全部拆分
var str = "1a2b3c4d5e"
var result = str.split(/[A-z]/)
console.log(result) //1,2,3,4,5
● search():可以搜索字符串中是否含有指定内容,如果搜索到指定内容,则会返回第一次出现的索引,如果
没有搜索到则会返回-1,它可以接受一个正则表达式作为参数,然后会根据正则表达式去检索字符串,它
只会查找第一个,即使设置全局匹配也没用
var str = "hello abc hello aec afc"
//检索字符串中是否含有 abc 或 aec 或 afc
var result = str.search(/a[bef]c/)
console.log(result) //6
● match():可以根据正则表达式从一个字符串中将符合条件的内容提取出来;默认情况下我们的match只会
找到第一个符合要求的内容,找到以后就停止检索;我们可以设置正则表达式为全局匹配模式,这样就会
匹配到所有的内容
var str = "1a2b3c4d5eAB"
var result = str.match(/[A-z]/)
console.log(result) //只会打印a
result = str.match(/a-z/gi) //即全局匹配又忽略大小写, gi和ig都可以
console.log(result) //会将a b c d e 都打印,会将结果封装到一个数组中
● replace():可以将字符串中指定内容替换为新的内容,参数:
1、被替换的内容
2、新的内容
默认只会替换第一个,可以使用正则表达式
var str = "abcdeaba"
var result = str.replace("a", "@@")
console.log(result) //"@@bcdeaba"
var result = str.replace(/a/g, "@@")
console.log(result) //"@@bcde@@b@@"
十四、DOM
文档对象模型
1、文档的加载
浏览器在加载一个页面时,是按照自上向下的顺序加载的,读取到一行就运行一行,如果将scrpit标签写到页
面的上边,在代码执行时,页面还没有加载,页面没有加载则DOM对象也没有加载,会导致无法获取到
DOM对象
onload 事件会在整个页面加载完成之后才触发,为 window 绑定一个 onload 事件
— 该事件对应的响应函数将会在页面加载完成之后执行,这样可以确保我们的代码执行时所有的DOM对象
已经加载完毕了
window.onload = function(){
}
2、dom查询
1)、获取元素节点:通过 document 对象调用
● getElementById():通过id属性获取一个元素节点对象
<ul id="city">
<li id="bj">北京</li>
<li>上海</li>
<li>东京</li>
<li>首尔</li>
</ul>
<script type="text/javascript">
//查找id为bj的节点
var bj = document.getElementById("bj")
//innerHTML 通过这个属性可以获取到元素内部的html代码
console.log(bj.innerHTML) //北京
</script>
● getElementsByTagName():通过标签名获取一组元素节点对象
<ul id="city">
<li id="bj">北京</li>
<li>上海</li>
<li>东京</li>
<li>首尔</li>
</ul>
<script type="text/javascript">
//查找所有li节点
//getElementsByTagName 可以根据标签名来获取一组元素节点对象
//这个方法会给我们返回一个类数组对象,所有查询到的元素都会封装到对象中
var lis = document.getElementsByTagName("li")
for(var i = 0 ; i < lis.length ; i++){
console.log(lis[i].innerHTML) //北京,上海,东京,首尔
}
</script>
● getElementsByName():通过name属性获取一组元素节点对象
gender:
<input type="radio" name="gender" value="male">Male
<input type="radio" name="gender" value="female">Female
<script type="text/javascript">
var inputs = document.getElementsByName("gender")
for(var i = 0 ; i < inputs.length ; i++){
//innerHTML用于获取元素内部的HTML代码,对于自结束标签,这个属性没有意义
console.log(inputs[i].innerHTML)
//如果需要读取元素节点属性,直接使用 元素.属性名
//例如:元素.id 元素.name 元素.value,但是 class属性不能使用这种方式读取,
//需要使用 元素.className
console.log(inputs[i].value) //male, female
}
</script>
2)、获取元素节点的子节点:通过具体的元素节点调用
● getElementsByTagName():这是一个方法,返回当前节点的指定标签名后代节点
<ul id="city">
<li id="bj">北京</li>
<li>上海</li>
<li>东京</li>
<li>首尔</li>
</ul>
<script type="text/javascript">
//查询#city下所有li节点
var city = document.getElementById("city")
var lis = city.getElementsByTagName("li")
for(var i = 0 ; i < lis.length ; i++){
console.log(lis[i].innerHTML)
}
</script>
● childNodes:这是一个属性,表示当前节点的所有子节点;
children属性可以获取当前元素的所有子元素,不会返回空白文本元素
<ul id="city">
<li id="bj">北京</li>
<li>上海</li>
<li>东京</li>
<li>首尔</li>
</ul>
<script type="text/javascript">
//获取id为city的节点
var city = document.getElementById("city")
/*
* childNodes属性会获取包含文本节点在内的所有节点,根据DOM标签,标签空白也会当成文本
* 节点,注意:在IE8及以下的浏览器中,不会将空白文本当成子节点,所以该属性在IE8会返回
* 4个子元素而其他浏览器会返回9个
* */
var cns = city.childNodes
console.log(cns.length) //返回9
//children属性可以获取当前元素的所有子元素,不会返回空白文本元素
var cns2 = city.children
console.log(cns2.length)
</script>
● firstChild:这是一个属性,表示当前节点的第一个子节点
firstElementChild获取当前元素的第一个子元素,不包括空白文本节点
<ul id="phone">
<li>IOS</li>
<li id="android">Android</li>
<li>Windows Phone</li>
</ul>
<script type="text/javascript">
//获取id为phone的元素
var phone = document.getElementById("phone")
//返回#phone的第一个子节点
//phone.childNodes[0]
//firstChild可以获取到当前元素的第一个子节点(包括空白文本节点)
var fir = phone.firstChild
console.log(fir)
//firstElementChild获取当前元素的第一个子元素
//firstElementChild 不支持IE8及以下的浏览器,如果需要兼容尽量不要使用
fir = phone.firstElementChild
console.log(fir)
</script>
● lastChild:这是一个属性,表示当前节点的最后一个子节点,lastChild同firstChild类似
3)、获取父节点和兄弟节点:通过具体的节点调用
● parentNode:这是一个属性,表示当前节点的父节点
<ul id="city">
<li id="bj">北京</li>
<li>上海</li>
<li>东京</li>
<li>首尔</li>
</ul>
<script type="text/javascript">
//获取id为bj的节点
var bj = document.getElementById("bj")
//返回#bj的父节点
var pn = bj.parentNode
console.log(pn) //打印的是ul以及它的子节点的html标签
/*
* innerText
* - 该属性可以获取到元素内部的文本内容
* - 它和 innerHTML 类似,不同的是它会自动将html去除
*/
console.log(pn.innerText) //打印 北京,上海, 东京, 首尔
</script>
● previousSibling:这是一个属性,表示当前节点的前一个兄弟节点
previousElementSibling 获取前一个兄弟元素,IE8及以下不支持,不会获取空白文本节点
<ul id="phone">
<li>IOS</li>
<li id="android">Android</li>
<li>Windows Phone</li>
</ul>
<script type="text/javascript">
//获取id为android的元素
var and = document.getElementById("android")
//返回#android的前一个兄弟节点,可能获取到空白的文本
var ps = and.previousSibling;
console.log(ps.innerHTML)
//previousElementSibling 获取前一个兄弟元素,IE8及以下不支持
var pe = and.previousElementSibling
console.log(pe.innerHTML)
</script>
● nextSibling:这是一个属性,表示当前节点的后一个兄弟节点,跟previousSibling类似
3、dom查询的其他方法
1)、获取html、body以及页面中所有元素标签
<script type="text/javascript">
//获取body标签
var body = document.getElementsByName("body")[0]
/*
* 在 document 中有一个属性 body,它保存的是 body 的引用,可以直接获取 body 标签
* */
var body = document.body
console.log(body)
/***************************************************************************************/
/*
* document.documentElement 保存的是 html 根标签
* */
var html = document.documentElement
console.log(html)
/***************************************************************************************/
/*
* document.all 代表页面中所有的元素
* */
var all = document.all
all = document.getElementsByTagName("*") //和 document.all是一样的
console.log(all.length) //输出6
for(var i = 0 ; i < all.length ; i++){
console.log(all[i])
}
</script>
2)、根据元素的class属性值查询一组元素节点对象(getElementsByClassName)
<div class="box1"></div>
<script type="text/javascript">
/*
* 根据元素的class属性值查询一组元素节点对象
* getElementsByClassName()可以根据class属性获取一组元素节点对象,
* 但是该方法不支持IE8及以下的浏览器
*/
var box1 = document.getElementsByClassName("box1")
console.log(box1.length)
</script>
3)、获取class为box1中的所有的div(querySelector,querySelectorAll)
<div class="box2">
<div></div>
</div>
<div></div>
<script type="text/javascript">
//获取class为box2中所有的div
/*
* document.querySelector()
* - 需要一个选择器的字符串作为参数,可以根据CSS选择器来查询一个元素节点对象
* - 虽然IE8中没有getElementsByClassName()但是可以使用querySelector()代替
* - 使用该方法总会返回唯一的一个元素,如果满足条件的元素有多个,那么它只会返回第一个
* */
var div = document.querySelector(".box2 div")
console.log(div)
/***************************************************************************************/
/*
* document.querySelectorAll(".box2")
* - 该方法和 querySelector() 用法类似,不同的是它会将符合条件的元素封装到一个数组中返回
* 即使只有一个,也会封装到一个数组中
* */
var box2 = document.querySelectorAll(".box2")
console.log(box2.length)
</script>
4、节点的属性
修改属性直接使用:元素.属性名 = 属性值
获取属性值直接使用:元素.属性名
节点的属性:
nodeName(节点名) | nodeType(节点类型) | nodeValue(节点值) | |
---|---|---|---|
文档节点 | #document | 9 | null |
元素节点 | 标签名 | 1 | null |
属性节点 | 属性名 | 2 | 属性值 |
文本节点 | #next | 3 | 文本内容 |
5、dom增删改
html 文档如下:
<div id="total">
<div class="inner">
<p>
你喜欢哪个城市?
</p>
<ul id="city">
<li id="bj">北京</li>
<li>上海</li>
<li>东京</li>
<li>首尔</li>
</ul>
</div>
</div>
1)、创建元素节点–语法:document.createElement()
创建文本节点–语法:document.createTextNode()
添加新的子节点–语法:父节点.appendChild(子节点)
<script type="text/javascript">
//创建广州节点<li>广州</li>
//创建li元素节点
/*
* document.createElement()
* 可以用于创建一个元素节点对象
* 它需要一个标签名作为参数,将会根据该标签名创建元素节点对象
* 并将创建好的对象作为返回值返回
* */
var li = document.createElement("li")
/***************************************************************************************/
//创建广州文本节点
/*
* document.createTextNode()
* 可以用来创建一个文本节点对象
* 需要一个文本内容作为参数,将会根据该内容创建文本节点,并将新节点返回
* */
var gzText = document.createTextNode("广州")
/***************************************************************************************/
//将gzText设置为li的子节点
/*
* appendChild()
* - 向一个父节点中添加一个新的子节点
* - 用法:父节点.appendChild(子节点)
* */
li.appendChild(gzText)
//将广州添加到city中
city.appendChild(li)
</script>
2)、在指定的子节点前面插入新的子节点–语法:父节点.insertBefore(新节点, 旧节点)
<script type="text/javascript">
//创建一个广州节点
var li = document.createElement("li")
var gzText = document.createTextNode("广州")
li.appendChild(gzText)
//获取id为bj的节点
var bj = document.getElementById("bj")
//获取city
var city = document.getElementById("city")
/*
* insertBefore()
* - 可以在指定的子节点前插入新的子节点
* - 语法:
* 父节点.insertBefore(新节点, 旧节点)
* */
city.insertBefore(li, bj)
</script>
3)、用新的子节点替换已有的子节点–语法:父节点.replaceChild(新节点, 旧节点)
<script type="text/javascript">
//创建一个广州节点
var li = document.createElement("li")
var gzText = document.createTextNode("广州")
li.appendChild(gzText)
//获取id为bj的节点
var bj = document.getElementById("bj")
//获取city
var city = document.getElementById("city")
/*
* replaceChild()
* - 可以使用指定的子节点替换已有的子节点
* - 语法:
* 父节点.insertBefore(新节点, 旧节点)
* */
city.replaceChild(li, bj)
</script>
4)、删除子节点–语法:父节点.removeChild(子节点)
<script type="text/javascript">
//获取id为bj的节点
var bj = document.getElementById("bj")
//获取city
var city = document.getElementById("city")
/*
* removeChild()
* - 可以删除一个子节点
* - 语法:父节点.removeChild(子节点)
* */
city.removeChild(bj)
//更方便的删除方式
bj.parentNode.removeChild(bj)
</script>
5)、修改
<script type="text/javascript">
var bj = document.getElementById("bj")
//将id为bj的元素中的内容替换为昌平
bj.innerHTML = "昌平"
/***************************************************************************************/
//向 city 中添加广州
var city = document.getElementById("city")
city.innerHTML += "<li>广州</li>"
</script>
6、操作样式
1)、操作内联样式
使用style属性只能操作内联样式,不能操作样式表中的样式
html、css如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
#box1{
width: 200px;
height: 200px;
background-color: red;
}
</style>
</head>
<body>
<button id="btn01">点我一下</button>
<div id="box1"></div>
</body>
</html>
● 修改样式和获取样式
<script type="text/javascript">
//获取box1
var box1 = document.getElementById("box1")
var btn01 = document.getElementById("btn01")
btn01.onclick = function () {
//修改box1的宽度
/*
* 通过JS修改元素的样式:
* 语法:元素.style.样式名 = 样式值
* 注意:如果CSS的样式名中含有 - ,这种名称在JS中是不合法的,比如:
* background-color,需要将这种样式名修改为驼峰命名法,去掉 - ,然后
* 将 - 后面的字母大写
*
* 我们通过style属性设置的样式都是内联样式,而内联样式有比较高的优先级,所以
* 通过JS修改的样式往往会立即生效
* 但是如果在样式表中写了 !important,则此时样式表中的样式会有最高的优先级,
* 即使通过JS代码修改也不能覆盖该样式,此时将会导致JS修改样式失效,
* 所以尽量不要为样式添加 !important
* */
box1.style.width = "300px"
box1.style.height = "300px"
box1.style.backgroundColor = "yellow"
}
//读取样式
/*
* 获取box1的样式:
* 语法:
* 元素.style.样式名
* 通过style属性设置和读取的都是内联样式,无法获取样式表中的样式
*
* */
console.log(box1.style.width)
</script>
2)、获取元素样式
● 获取元素的当前显示的样式(包括样式表中的样式或内联样式)
IE8及以下浏览器只能使用 元素.currentStyle.样式名 获取样式,不支持其他浏览器
其他浏览器只能使用 getComputedStyle() 方法获取样式,不支持IE8
<script type="text/javascript">
var box1 = document.getElementById("box1")
var btn02 = document.getElementById("btn02")
btn02.onclick = function () {
/*
* 获取元素的当前显示样式
* 语法:元素.currentStyle.样式名
* 它可以用来读取当前元素正在显示的样式
* 如果当前元素没有设置该样式,则获取它的默认值
*
* currentStyle只有IE浏览器支持,其他的浏览器都不支持
* */
alert(box1.currentStyle.width)
alert(box1.currentStyle.height)
/*
* 在其他浏览器中可以使用
* getComputedStyle() 这个方法来获取元素当前的样式
* 这个方法是window的方法,可以直接使用
* 该方法会返回一个对象,对象中封装了当前元素对于的样式
* 可以通过返回的对象,通过 对象.样式名 来读取样式
* 如果获取的样式没有设置,则会获取到真是的值,而不是默认值,比如:
* 没有设置width,它不会获取到auto,而是一个长度
*
* 但是该方法不支持IE8及以下的浏览器
*
* 通过currentStyle和getComputedStyle()读取到的样式都是只读的,不能修改,
* 如果要修改必须通过style属性
* */
var obj = getComputedStyle(box1, null)
alert(obj.width)
}
</script>
3)、获取样式的通用的方法
/*
* 定义一个函数,用来获取指定元素的当前的样式
* 参数:
* obj:要获取样式的元素
* name:要获取的样式名
* */
function getStyle(obj, name) {
if(window.getComputedStyle) {
//正常浏览器的方式
return getComputedStyle(obj, null)[name]
} else{
//IE8的方式
return obj.currentStyle[name]
}
}
4)、其他样式相关的属性
这些属性都是不带px的,返回都是一个数字,可以直接进行计算
html文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
#box1{
width: 100px;
height: 100px;
background-color: red;
}
</style>
</head>
<body>
<button id="btn01">点我一下</button>
<br><br>
<div id="box1"></div>
</body>
</html>
1)、clientWidth–获取元素的宽度,包括内容区和内边距
clientHeight–获取元素的高度,包括内容区和内边距
/*
* clientWidth
* clientHeight
* - 这两个属性可以获取元素的可见宽度和高度
* - 这些属性都是不带px的,返回都是一个数字,可以直接进行计算
* - 会获取元素宽度和高度,包括内容区和内边距
* - 这些属性都是只读的,不能修改
* */
alert(box1.clientWidth)
alert(box1.clientHeight)
box1.clientHeight = 300 //修改不起作用,因为它包含内容区和内边距,无法确定修改哪个
2)、offsetWidth–获取元素的整个宽度,包括内容区、内边距和边框
offsetHeight–获取元素的整个高度,包括内容区,内边距和边框
/*
* offsetWidth
* offsetHeight
* - 获取元素的整个的宽度和高度,包括内容区、内边距和边框
* */
alert(box.offsetWidth)
3)、offsetParent–获取到离当前元素最近的开启了定位的祖先元素
/*
* offsetParent
* - 可以用来获取当前元素的定位父元素
* - 会获取到离当前元素最近的开启了定位的祖先元素
* 如果所有的祖先元素都没有开启定位,则返回body
* */
var op = box1.offsetParent
console.log(box1.id)
4)、offsetLeft–当前元素相对于其定位父元素的水平偏移量
offsetTop–当前元素相对于其定位父元素的垂直偏移量
/*
* offsetLeft
* - 当前元素相对于其定位父元素的水平偏移量
* offsetTop
* - 当前元素相对于其定位父元素的垂直偏移量
* */
alert(box1.offsetLeft)
5)、scrollWidth–获取元素整个滚动区的宽度
scrollHeight–获取元素整个滚动区的高度
<style type="text/css">
#box2{
width: 200px;
height: 200px;
background-color: yellow;
overflow: scroll;
}
#box3{
width: 100px;
height: 600px;
background-color: red;
}
</style>
<button id="btn02">再点我一下</button>
<div id="box2">
<div id="box3"></div>
</div>
<script type="text/javascript">
var box2 = document.getElementById("box2")
var box3 = document.getElementById("box3")
var btn02 = document.getElementById("btn02")
btn02.onclick = function () {
/*
* scrollWidth
* scrollHeight
* - 获取元素整个滚动区的宽度和高度
* */
alert(box2.scrollHeight) //输出600
}
</script>
6)、scrollLeft–可以获取水平滚动条的滚动距离
scrollTop–可以获取垂直滚动条滚动的距离
/*
* scrollLeft
* - 可以获取水平滚动条的滚动距离
* scrollTop
* - 可以获取垂直滚动条滚动的距离
* */
alert(box2.scrollLeft)
alert(box2.scrollTop)
//当满足 scrollHeight - scrollTop = clientHeight 时,说明垂直滚动条滚动到底了
//当满足 scrollWidth - scrollLeft = clientWidth 时,说明水平滚动条滚动到底了
/*
* onscroll
* - 该事件会在元素的滚动条滚动时触发
* */
box2.onscroll = function () {
alert("我滚了。。。")
}
input输入框有一个 disabled 属性,可以设置一个元素是否禁用
如果设置为true,则元素禁用
如果设置为false,则元素可用
<input type="text" id="input1">
<input type="checkbox" id="input2">
<script type="text/javascript">
var input1 = document.getElementById("input1")
var input2 = document.getElementById("input2")
input1.disabled = true
input2.disabled = true
</script>
7、事件对象-event
<script type="text/javascript">
var areaDiv = document.getElementById("areaDiv")
var showMsg = document.getElementById("showMsg")
/*
* onmousemove
* - 该事件将会在鼠标在元素中移动时触发
*
* 事件对象:
* - 当事件的响应函数被触发时,浏览器每次都会将一个事件对象作为实参传递进响应函数
* 在事件对象中封装了当前事件相关的一切信息,比如:鼠标的坐标,键盘哪个按键被按下,
* 鼠标滚轮滚动的方向等等
* */
areaDiv.onmousemove = function (event) {
/*
* 在IE8中,响应函数被触发时,浏览器不会传递事件对象,
* 在IE8及以下的浏览器中,是将事件对象作为window对象的属性保存
* */
if(!event){
event = window.event
}
//使用以下方式更简洁
event = event || window.event
/*
* clientX:可以获取鼠标指针的水平坐标,它是相对于当前窗口的
* clientY:可以获取鼠标指针的垂直坐标,它是相对于当前窗口的
* */
console.log(event.clientX + ", " + event.clientY)
}
</script>
8、div跟随鼠标移动
div跟随鼠标移动注意三点:
1)、鼠标移动事件不能绑定在div上,因为绑定在div上时,只有鼠标在div内移动时才会触发事件,一旦鼠标
不在div内部移动,将不会触发事件,那么div就不会移动了
2)、clientX和clientY是鼠标相对于视图窗口的距离,而页面内的元素的偏移量是相对于页面的大小偏移的,
所以,如果浏览器页面高度和宽度大于整个视图窗口,当把滚动条移动时,div的左上角与鼠标会偏差滚
动条滚动的距离
3)、chrome认为浏览器的滚动条时body的,可以通过doby.scrollTop来获取。而火狐等浏览器认为浏览器
的滚动条时html的。我们可以使用下面方式获取页面滚动条的滚动距离:
var st = document.body.scrollTop || document.documentElement.scrollTop
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
#box1{
width: 100px;
height: 100px;
background-color: red;
position: absolute;
}
</style>
</head>
<body style="height: 1000px">
<div id="box1"></div>
<script type="text/javascript">
//获取box1
var box1 = document.getElementById("box1")
//绑定鼠标移动事件
//当使用box1绑定鼠标移动事件时,鼠标只有在box1内部移动时,div才会跟着移动,如果
//鼠标不是在div内部移动时,div不会移动,所以我们可以利用document绑定鼠标移动事件
//box1.onmousemove = function (event) {
document.onmousemove = function (event) {
//解决兼容问题
event = event || window.event
//获取页面滚动条滚动的距离
/*
* chrome认为浏览器的滚动条时body的,可以通过doby.scrollTop来获取
* 火狐等浏览器认为浏览器的滚动条时html的
* 我们可以使用下面方式获取页面滚动条的滚动距离
* */
var st = document.body.scrollTop || document.documentElement.scrollTop
var sl = document.body.scrollLeft || document.documentElement.scrollLeft
//获取鼠标的坐标
/*
* clientX和clientY
* 用于获取鼠标在当前的可见窗口的坐标
* div的偏移量,是相对于整个页面的
*
* pageX和pageY可以获取鼠标相对于当前页面的坐标
* 但是这两个属性在IE8中不支持,所以如果需要兼容IE8,则不要使用
* */
//如果给doby设置高度为1000px,当把滚动条的距离往下移时,鼠标不会在div的左上角
//var left = event.clientX
//var top = event.clientY
var left = event.clientX + sl
var top = event.clientY + st
//设置div的偏移量
box1.style.left = left + "px"
box1.style.top = top + "px"
}
</script>
</body>
</html>
9、事件的冒泡
所谓的事件冒泡就是事件的向上传导,当后代元素上的事件被触发时,其祖先元素的相同事件也会被触发;
在开发中大部分的冒泡都是有用的,如果不希望发生事件冒泡可以通过事件对象来取消冒泡;
取消冒泡:可以将事件对象的cancelBubble设置为true,即可取消冒泡,即 event.cancelBubble = true
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
#box1{
width: 200px;
height: 200px;
background-color: yellowgreen;
}
#s1{
background-color: yellow;
}
</style>
</head>
<body>
<div id="box1">
我是box1
<span id="s1">我是span</span>
</div>
<script type="text/javascript">
/*
* 事件的冒泡(Bubble)
* - 所谓的事件冒泡就是事件的向上传导,当后代元素上的事件被触发时,其祖先元素的相同事件也会被触发
* - 在开发中大部分的冒泡都是有用的,如果不希望发生事件冒泡可以通过事件对象来取消冒泡
* */
var s1 = document.getElementById("s1")
s1.onclick = function (event) {
alert("我是span的单击响应函数")
//取消冒泡
//可以将事件对象的cancelBubble设置为true,即可取消冒泡
event.cancelBubble = true
}
var box1 = document.getElementById("box1")
box1.onclick = function () {
alert("我是box1的单击响应函数")
}
document.body.onclick = function () {
alert("我是body的单击响应函数")
}
</script>
</body>
</html>
10、事件的委派
指将事件统一绑定给元素的相同的祖先元素,这样当后代元素上的事件触发时,会一直冒泡到祖先元素,从
而通过祖先元素的响应函数来处理事件。事件委派是利用了冒泡,通过委派可以减少事件绑定的次数,提高程
序的性能
举例:当在一个ul存放多个li,而每一个li中有一个超链接,当我们对所以的超链接绑定事件后,这些已有的超
链接可以得到相应函数,但是如果其他的操作可以在ul中新增li和超链接后,新增的超链接是不会绑定单击响应
事件的,这时我们可以利用事件的委派,将事件绑定到所有超链接的祖先元素(ul),这时如果新增超链接后,还
是一样会有单击响应事件
注意:这里利用了一个 event.target 对象,这个 target 可以获取到触发事件的对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button id="btn01">添加超链接</button>
<ul id="ul">
<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>
<script type="text/javascript">
var ul = document.getElementById("ul")
//点击按钮以后添加超链接
var btn01 = document.getElementById("btn01")
btn01.onclick = function () {
//创建一个li
var li = document.createElement("li")
li.innerHTML = "<a href='javascript:;' class='link'>新建的超链接</a>"
//将li添加到ul中
ul.appendChild(li)
}
/*
* 为每一个超链接都绑定一个单击响应函数
* 这里我们为每一个超链接都绑定了一个单击响应函数,这种操作比较麻烦
* 而且这些操作只能为已有的超链接设置事件,而新添加的超链接必须重新绑定
* */
//获取所有的a
var allA = document.getElementsByTagName("a")
//遍历
for(var i = 0 ; i < allA.length ; i++){
allA[i].onclick = function () {
alert("我是a的单击响应函数!!")
}
}
/*
* 我们希望,只绑定一次事件,即可应用到多个元素上,即使元素是后添加的。
* 我们可以尝试将其绑定给元素的共同的祖先元素
*
* 事件的委派:
* - 指将事件统一绑定给元素的相同的祖先元素,这样当后代元素上的事件触发时,会一直
* 冒泡到祖先元素,从而通过祖先元素的响应函数来处理事件
* - 事件委派是利用了冒泡,通过委派可以减少事件绑定的次数,提高程序的性能
* */
//为ul绑定一个单击响应函数
ul.onclick = function (event) {
event = event || window.event
//alert("我是ul的单击响应函数")
/*
* target
* - event 中的target表示的触发事件的对象
* */
//如果触发事件的对象时我们期望的元素,则执行,否则不执行
if(event.target.className == "link"){
alert("我是ul的单击响应函数")
}
}
</script>
</body>
</html>
11、事件的绑定
使用 对象.事件 = 函数 的形式绑定响应函数,它只能同时为一个元素的一个事件绑定一个响应函数,不能绑定
多个,如果绑定了多个,则后边会覆盖掉前边的
addEventListener():通过这个方法也可以为元素绑定响应函数
参数:
1、事件的字符串,不要on
2、回调函数,当事件触发时该函数会被调用
3、是否在捕获阶段触发事件,需要一个布尔值,一般都传 false
使用 addEventListener() 可以同时为一个元素的相同事件同时绑定多个响应函数。这样当事件被触发时,响
应函数将会按照函数的绑定顺序执行,这个方法不支持IE8及以下的浏览器,在 addEventListener() 方法中的
this,是绑定事件的对象
attachEvent():在IE8中可以使用attachEvent()来绑定事件
参数:
1、事件的字符串,要on
2、回调函数
这个方法也可以同时为一个事件绑定多个处理函数,不同的是它是后绑定先执行,执行顺序和
addEventListener() 相反,在 attachEvent() 中的this,是window
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button id="btn01">点我一下</button>
<script type="text/javascript">
/*
* 点击按钮以后弹出一个内容
* */
//获取按钮对象
var btn01 = document.getElementById("btn01")
/*
* 使用 对象.事件 = 函数 的形式绑定响应函数
* 它只能同时为一个元素的一个事件绑定一个响应函数
* 不能绑定多个,如果绑定了多个,则后边会覆盖掉前边的
* */
//为btn01绑定一个单击响应
btn01.onclick = function () {
alert(1)
}
//为btn01绑定第二个单击响应
btn01.onclick = function () {
alert(2)
}
/*
* addEventListener()
* - 通过这个方法也可以为元素绑定响应函数
* - 参数:
* 1、事件的字符串,不要on
* 2、回调函数,当事件触发时该函数会被调用
* 3、是否在捕获阶段触发事件,需要一个布尔值,一般都传 false
*
* 使用 addEventListener() 可以同时为一个元素的相同事件同时绑定多个响应函数。
* 这样当事件被触发时,响应函数将会按照函数的绑定顺序执行
*
* 这个方法不支持IE8及以下的浏览器
* */
btn01.addEventListener("click", function () {
alert(1)
}, false)
btn01.addEventListener("click", function () {
alert(2)
}, false)
/*
* attachEvent()
* - 在IE8中可以使用attachEvent()来绑定事件
* - 参数:
* 1、事件的字符串,要on
* 2、回调函数
*
* - 这个方法也可以同时为一个事件绑定多个处理函数,不同的是它是后绑定先执行,
* 执行顺序和 addEventListener() 相反
* */
btn01.attachEvent("onclick", function () {
alert(1)
})
</script>
</body>
</html>
12、事件绑定(bind)函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script type="text/javascript">
//定义一个函数,用来为指定元素绑定响应函数
/*
* addEventListener() 中的this,是绑定事件的对象
* attachEvent() 中的this,是window
* 需要统一两个方法的this
*
* 参数:
* obj:要绑定事件的对象
* eventStr:事件的字符串
* callback:回调函数
* */
function bind(obj, eventStr, callback) {
if(obj.addEventListener){
//大部分浏览器兼容的方式
obj.addEventListener(eventStr, callback, false)
} else {
/*
* this是谁由调用方式决定
* callback.call(obj)
* */
//IE8及以下
obj.attachEvent("on"+eventStr, function () {
//在匿名函数中调用回调函数
callback.call(obj)
})
}
}
</script>
</body>
</html>
13、事件的传播
● 关于事件的传播网景公司和微软公司有不同的理解
● 微软公司认为事件是由内向外传播,也就是当事件触发时,应该先触发当前元素上的事件,然后再想当前元素
的祖先元素上传播,也就说事件应该在冒泡阶段执行
● 网景公司认为事件应该是由外向内传播的,也就是当前事件触发时,应该先触发当前元素的最外层的祖先元素
的事件,然后再向内传播给后代元素
● W3C综合了两个公司的方案,将事件传播分成了三个阶段
1)、捕获阶段
在捕获阶段时从最外层的祖先元素,向目标元素进行事件的捕获,但是默认此时不会触发事件
2)、目标阶段
事件捕获到目标元素,捕获结束开始在目标元素上触发事件
3)、冒泡阶段
事件从目标元素向它的祖先元素传递,依次触发祖先元素上的事件
如果希望在捕获阶段就触发事件,可以将addEventListener()的第三个参数设置为true,一般情况下我们不会希
望在捕获阶段触发事件,所以这个参数一般都是false
IE8及以下的浏览器中没有捕获阶段
14、鼠标的滚轮事件
onmousewheel:鼠标滚轮滚动的事件,会在滚轮滚动时触发,但是火狐不支持该属性。在火狐中需要使用
DOMMouseScroll 来绑定滚动事件,注意该事件需要通过 addEventListener()
event.wheelDelta:可以获取鼠标滚轮滚动的方向
wheelDelta这个属性火狐中不支持,在火狐中使用event.detail来获取滚动的方向
当滚轮滚动时,如果浏览器有滚动条,滚动条会随之滚动,这是浏览器的默认行为,如果不希望发生,则可
以使用 return false 取消默认行为,但是使用 addEventListener() 方法绑定响应函数,取消默认行为时不能
使用 return false,需要使用event来取消默认行为event.preventDefault(),但是IE8不支持
event.preventDefault(),如果直接调用会报错,可以使用event.preventDefault || event.preventDefault()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
#box1{
width: 100px;
height: 100px;
background-color: red;
}
</style>
</head>
<body>
<div id="box1"></div>
<script type="text/javascript" src="../js/common.js"></script>
<script type="text/javascript">
/*
* 当鼠标滚轮向下滚动时,box1变长
* 当鼠标滚轮向上滚动时,box1变短
* */
//获取id为box1的div
var box1 = document.getElementById("box1")
/*
* 为box1绑定一个鼠标滚轮滚动的事件
*
* onmousewheel:鼠标滚轮滚动的事件,会在滚轮滚动时触发,但是火狐不支持该属性
* 在火狐中需要使用 DOMMouseScroll 来绑定滚动事件,注意该事件需要通过 addEventListener() 函数来绑定
* */
box1.onmousewheel = function (event) {
event = event || window.event
//判断鼠标滚轮滚动的方向
//event.wheelDelta:可以获取鼠标滚轮滚动的方向
//wheelDelta这个值不看大小,只看正负
//wheelDelta这个属性火狐中不支持,在火狐中使用event.detail来获取滚动的方向
//event.wheelDelta
//兼容火狐
//event.detail
if(event.wheelDelta > 0 || event.detail < 0){
//alert("向上滚")
box1.style.height = box1.clientHeight - 10 + "px"
} else {
//alert("向下滚")
box1.style.height = box1.clientHeight + 10 + "px"
}
/*
* 使用 addEventListener() 方法绑定响应函数,取消默认行为时不能使用 return false
* 需要使用event来取消默认行为event.preventDefault();
* 但是IE8不支持event.preventDefault(),如果直接调用会报错
* */
event.preventDefault || event.preventDefault()
/*
* 当滚轮滚动时,如果浏览器有滚动条,滚动条会随之滚动,这是浏览器
* 的默认行为,如果不希望发生,则可以取消默认行为
* */
return false
}
//兼容火狐浏览器滚轮滚动事件
bind(box1, "DOMMouseScroll", box1.onmousewheel)
</script>
</body>
</html>
15、键盘事件
onkeydown:
- 键盘被按下
- 对于onkeydown来说如果一直按着某个按键不松手,则事件会一直触发
- 当onkeydown连续触发时,第一次和第二次之间会间隔稍微长一点,其他的会非常的快,这种设计是为
了防止误操作的发生
onkeyup:
- 键盘被松开
键盘事件一般都会绑定给一些可以获取到焦点的对象或者是document
可以通过keyCode来获取按键的编码,通过它可以判断哪个按键被按下,除了keyCode,事件对象中还提供了几
个属性:altKey,ctrlKey,shiftKey。这三个用来判断alt ctrl shift是否被按下,如果按下则返回true,否则返
回false
在文本框中输入内容,属于onkeydown的默认行为,如果在onkeydown中取消了默认行为,则输入的内容不会
出现在文本框中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<input type="text">
<script type="text/javascript">
/*
* 键盘事件:
* onkeydown:
* - 键盘被按下
* - 对于onkeydown来说如果一直按着某个按键不松手,则事件会一直触发
* - 当onkeydown连续触发时,第一次和第二次之间会间隔稍微长一点,其他的会非常的快
* 这种设计是为了防止误操作的发生
* onkeyup:
* - 键盘被松开
*
* 键盘事件一般都会绑定给一些可以获取到焦点的对象或者是document
* */
document.onkeydown = function (event) {
//console.log("按键被按下了")
event = event || window.event
/*
* 可以通过keyCode来获取按键的编码,通过它可以判断哪个按键被按下
* 除了keyCode,事件对象中还提供了几个属性
* altKey
* ctrlKey
* shiftKey
* - 这三个用来判断alt ctrl shift是否被按下,如果按下则返回true,否则返回false
* */
//判断y是否被按下
if(event.keyCode == 89){
console.log("y被按下了")
}
//判断y和ctrl是否同时被按下
if(event.keyCode == 89 && event.ctrlKey){
console.log("ctrl和y都被按下了")
}
//获取input
var input = document.getElementsByTagName("input")[0]
input.onkeydown = function (event) {
event = event || window.event
console.log("按键被按下了")
//使文本框中不能输入数字
//数字的编码是 48-57
if(event.keyCode >= 48 && event.keyCode <= 57){
/*
* 在文本框中输入内容,属于onkeydown的默认行为,如果在
* onkeydown中取消了默认行为,则输入的内容不会出现在文本框中
* */
return false
}
}
}
document.onkeyup = function () {
console.log("按键松开了")
}
</script>
</body>
</html>
十五、BOM
-
浏览器对象模型
-
BOM可以使我们通过JS操作浏览器
-
在BOM中为我们提供了一组对象,用来完成对浏览器的操作
-
BOM
-
Window
- 代表的是整个浏览器的窗口,同时Window也是网页中的全局对象
-
Navigator
- 代表的当前浏览器的信息,通过该对象可以来识别不同的浏览器
-
Location
- 代表当前浏览器的地址栏信息,通过Location可以获取地址栏信息,或者操作浏览器跳转页面
-
History
- 代表浏览器的历史记录,可以通过该对象来操作浏览器的历史记录,由于隐私原因,该对象不能获取到具体的历史记录,只能操作浏览器向前或向后翻页,而且该操作只在当次访问时有效
-
Screen
- 代表用户的屏幕的信息,通过该对象可以获取到用户的显示器的相关信息
这些BOM对象在浏览器中都是作为window对象的属性保存的,可以通过window对象来使用,也可以直
接使用
-
1、Navigator
-
代表的当前浏览器的信息,通过该对象可以来识别不同的浏览器
-
由于历史原因,Navigator对象中的大部分属性都已经不能帮助我们识别浏览器了
-
一般我们只会使用userAgent来判断浏览器的信息
-
userAgent时一个字符串,这个字符串中包含有用来描述浏览器信息的内容,不同的浏览器会有不同的userAgent,注意:userAgent可以识别IE8、IE9、IE10,但是IE11中已经将微软和IE相关的标识都已经去除了,所以我们基本已经不能通过userAgent来识别一个浏览器是否是IE11了。但是我们还可以通过一些浏览器的特有的对象,来判断浏览器的信息,比如ActiveXObject,这个属性只有IE中有,可以通过
“ActiveXObject” in window 判断是否是IE
各个浏览器的userAgent如下:
Chrome的userAgent:
Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.87 Safari/537.36
IE的userAgent:
Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; McAfee; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; rv:11.0) like Gecko
-
2、History
History对象可以用来操作浏览器向前或向后翻页
length:属性,可以获取到当前访问的链接数量
back():可以用来回退到上一个页面,作用和浏览器的回退按钮一样
forward():可以调整下一个页面,作用和浏览器的前进按钮一样
go():可以用来跳转到指定的页面,它需要一个整数作为参数,参数可以是以下值:
1、表示向前跳转一个页面,相当于forward()
2、表示向前跳转两个页面
-1、表示向后跳转一个页面
-2、表示向后跳转两个页面
3、Location
- 该对象中封装了浏览器的地址栏的信息
- 如果直接打印location,则可以获取到地址栏的信息(当前页面的完整的路径)
- 如果直接将location属性修改为一个完整的路径,或相对路径,则我们页面会自动跳转到该路径,并且会生成响应的历史记录
- 方法:
- assign():用来跳转到其他的页面,作用和直接修改location一样
- reload():用于重新加载当前页面,作用和刷新按钮一样。如果在方法中传递一个true作为参数,则会强制情况缓存刷新页面
- replace():可以使用一个新的页面替换当前页面,调用完毕也会跳转页面,它不会生成历史记录,不能使用回退按钮回退
- assign():用来跳转到其他的页面,作用和直接修改location一样
十六、定时器
1、定时调用
setInterval():
● 定时调用
● 可以将一个函数每隔一段时间执行一次
● 参数
1、回调函数,该函数会每隔一段时间被调用一次
2、每次调用间隔的事件,单位是毫秒
● 返回值:返回一个Number类型的数据,这个数字用来作为定时器的唯一标识
clearInterval():可以用来关闭一个定时器,方法中需要一个定时器的标识作为参数,这样将关闭标识对应的定
时器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script type="text/javascript">
/*
* setInterval()
* - 定时调用
* - 可以将一个函数每隔一段时间执行一次
* - 参数
* 1、回调函数,该函数会每隔一段时间被调用一次
* 2、每次调用间隔的事件,单位是毫秒
* - 返回值
* 返回一个Number类型的数据,这个数字用来作为定时器的唯一标识
* */
var num = 1
var timer = setInterval(function () {
num++
}, 1000)
/*
* clearInterval()可以用来关闭一个定时器,方法中需要一个
* 定时器的标识作为参数,这样将关闭标识对应的定时器
* */
clearInterval(timer)
</script>
</body>
</html>
2、延时调用
setTimeout()
● 延时调用一个函数不会马上执行,而是隔一段事件以后执行,而且只会执行一次
● 延时调用和定时调用的区别:定时调用会执行多次,而延时调用只会执行一次
clearTimeout():使用clearTimeout()来关闭一个延时调用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script type="text/javascript">
/*
* 延时调用:
* 延时调用一个函数不会马上执行,而是隔一段事件以后执行,而且只会执行一次
*
* 延时调用和定时调用的区别:定时调用会执行多次,而延时调用只会执行一次
* */
var timer = setTimeout(function () {
alert("hello")
}, 1000)
//使用clearTimeout()来关闭一个延时调用
clearTimeout(timer)
</script>
</body>
</html>
十七、类(class,样式)的操作
1、我们可以通过修改元素的class属性来间接地修改样式,这样一来,我们只需要修改一次,即可同时修改多个
样式,浏览器只需要重新渲染页面一次,性能比较好,并且这种方式,可以是表现和行为进一步分离,如
box.className = “b2”
十八、JSON
● JavaScript Object Notation – JS对象表示法
● JSON和JS对象的格式一样,只不过JSON字符串中的属性名必须加双引号,其他的和JS语法一直
● json 字符串转 js 对象:
JSON.parse(json字符串)
可以将以JSON字符串转换为js对象
它需要一个JSON字符串作为参数,会将该字符串转换为js对象
● js 对象转换为JSON
JSON.stringify(js对象)
可以将一个JS对象转换为JSON字符串
需要一个js对象作为参数,会返回一个JSON字符串
● JSON这个对象在IE7及以下的浏览器中不支持,所以在这些浏览器中调用时会报错,可以使用eval()函数,但
是这种方式不建议使用,首先它的执行性能比较差,然后它还具有安全隐患,在IE7及以下的浏览器如果要进
行JSON转换我们更多的是引入一个外部json2.js文件
● eval()
这个函数可以用来执行一段字符串形式的JS代码,并将执行结果返回,如果使用eval()执行的字符串中含有
{},它会将{}当成是代码块,如果不希望将其当成代码块解析,则需要在字符串前后各加一个()