JavaScript基础

一、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(节点值)
文档节点#document9null
元素节点标签名1null
属性节点属性名2属性值
文本节点#next3文本内容
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():可以使用一个新的页面替换当前页面,调用完毕也会跳转页面,它不会生成历史记录,不能使用回退按钮回退
十六、定时器
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()执行的字符串中含有

​ {},它会将{}当成是代码块,如果不希望将其当成代码块解析,则需要在字符串前后各加一个()

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值