JS基础知识

本文详细介绍了JavaScript的基础语法,包括变量声明、数据类型、运算符、流程控制等。深入讲解了函数的使用,如call和apply方法,以及arguments对象。还涉及到了正则表达式、日期对象、DOM操作、事件处理和事件冒泡。此外,讨论了BOM中的Window、Location、History对象,以及定时器的使用。最后提到了浏览器的垃圾回收机制和对象的生命周期。
摘要由CSDN通过智能技术生成

JS

简介

特点

  • 解释性语言
  • 类似于C和Java的语法结构
  • 动态语言
  • 基于原型的面向对象

基本语法

输出语句

    <script type="text/javascript">
        // 控制浏览器弹出一个警告框
        alert("这是我的第一行js代码")
        // 让计算机在页面中输出一个内容 在Body中写入一个内容
        document.write("123")
        // 向控制台输出一个内容
        console.log("控制台输出")
    </script>

位置

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 
        可以将js代码编写到外部js文件中,然后通过script标签引入
        写到外部文件中可以在不同的页面中同时引用,也可以利用到浏览器的缓存机制
     -->
     <!-- 
         script标签一旦用于引入外部文件了,就不能再编写代码了,即使编写了浏览器也会忽略
         如果需要则可以创建一个新的script标签用于编写内部代码
      -->
    <script type="text/javascript" src="js/script.js"></script>
</head>
<body>
    <!-- 
        可以将JS代码编写到标签的onclick属性中,当我们点击按钮时,js代码才会执行
        虽然可以写在标签属性里面,但是他们属于结构和行为耦合,不方便维护,不推荐使用 
    -->
    <button onclick="alert('123')">点我一下</button>

    <!-- 可以将js代码写在超链接的href属性中,这样当点击超链接时,会执行js代码-->
    <a href="javascript:alert('321')">点链接</a></a>
</body>

特点

1、严格区分大小写

2、JS中每一条语句以分号结尾,如果不写分号,浏览器会自动添加,但是会消耗一些资源,而且有些时候,浏览器会加错分号,所以在开发中分号必须写

3、JS会忽略多个空格和换行。所以可以利用空格和换行对代码进行格式化

声明变量

使用var关键字来声明一个变量

数据类型

数据类型指的就是字面量的类型

在JS中有六种数据类型

String 字符串 Number 数值 Boolean 布尔值 Null 空值 Undefined 未定义 Object 对象

除了Object属于引用数据类型,其他都属于基本数据类型

String

String字符串:

  • 在JS中字符串需要使用引号引起来
  • 使用双引号或单引号都可以,但是不要混着用
  • 引号不能嵌套,双引号里面不能放双引号,单引号里面不能放单引号

字符串中我们可以使用\来表示转义字符,当表示一些特殊符号时可以使用\进行转义

Number

在JS中所有的数值都是Number类型,包括整数和浮点数

typeof 变量 可以检查一个变量的类型

如果使用Number表示的数字超过了最大值,则会返回一个Infinity表示正无穷

NaN 是一个特殊的数字,表示Not A Number 使用typeof 检查一个NaN也会返回number

JS中整数的运算基本可以保证精确,但是浮点数的计算可能得到一个不精确的结果,所以不要用js进行对精确度要求比较高的运算

Boolean
Null和Undefined

null这个值专门用来表示一个为空的对象,使用typeof检查一个null值时,会返回object

undefined 类型的值只有一个,就是Undefined,当声明一个变量,但是并不给变量赋值时,它的值是Undefined,使用typeof检查一个undefined时返回一个undefined

强制转换

转换成String

方法1:调用被转换数据类型的toString()方法,该方法不会影响到原变量,它会将转换的结果返回,但是注意:null和undefined这两个值没有toString方法,如果调用会报错

方法2:调用String()函数,并将被转换的数据作为参数传递给函数,对于Number和Boolean实际上就是调用的toString()方法,但是对于null和undefined,就不会调用toString()方法,它会将null和undefined转换为字符串

转换为Number

方式1:使用Number()函数:

  • 字符串转换数字

如果是纯数字的字符串,则直接转换为数字

如果字符串中有非数字的内容,则转换为NaN

如果字符串是一个空串或者是一个全是空格的字符串,则转换成0

  • 布尔转换成数字

true 转成 1

false 转成 0

  • Null 转换成数字

0

  • undefined转成数字

NaN

方式2:这种方式专门适用字符串

parseInt() 把一个字符串转换成一个整数,可以将字符串中有效的整数内容取出来,转换为Number

parseFloat() 把一个字符串转换为一个浮点数,作用同上

转换成Boolean

使用Boolean()函数

  • 数字转换成Boolean

除了0和NaN,其余的都是true

  • 字符串转换成Boolean

除了空串,其余都是true

  • null和undefined都会转换成为false
  • 对象也会转换为true

其他进制的数字

表示16进制,需要以0x开头,表示8进制,以0开头,表示2进制0b开头

像070这种字符串,有些浏览器会当成8进制解析,有些会当成10进制解析

对象

对象字面量

//创建一个对象
var obj = new Object();
//使用对象字面量来创建一个对象
obj = {};

使用对象字面量,可以在创建对象时,直接指定对象中的属性,

语法:{属性名:属性值,属性名:属性值…}

对象字面量的属性名可以加引号也可以不加,建议不加,如果要使用一些特殊的名字,则必须加引号

this

// 解析器在调用函数每次都会向函数内部传递一个隐含的参数
// 这个隐含的参数就是this。this指向的是一个对象
// 这个对象我们称为函数执行的上下文对象
// 根据函数的调用方式的不同,this会指向不同的对象
// 		1.以函数的形式调用,this永远都是window
// 		2.以方法的形式调用,this就是调用方法的那个对象
//      3.以构造函数的形式调用,This就是新创建的那个对象
function fun(){
    console.log(this.name);
}

// 创建一个对象
var obj = {
    name:"zzh",
    sayName:fun
};

//方法调用
obj,sayName();
//函数调用 相当于window.fun()
fun();

补充:

var name = "全局";

//创建一个fun()函数
function fun(){
	console.log(this.name)
}

//创建两个对象
var obj = {
	name:"zzh",
    sayName:fun
}

var obj2 = {
	name:"gj",
    sayName:fun
}

//使用obj调用
obj.sayName();
//使用obj2调用
obj2.sayName();

使用工厂方法创建对象

function createPerson(name, age, gender){
	//创建一个新的对象
	var obj = new Object();
	
	//向对象中添加属性
	obj.name = name;
    obj.age = age;
    obj.gender = gender;
    obj.sayName = function(){
        alert(this.name);
    }
    //最新的对象发现
    return obj;
}

var obj2 = createPerson("zzh",30,"男");

使用工厂方法创建的对象,使用的构造函数都是Object,所以创建的对象都是Object这个类型,就导致我们无法区分出多种不同类型的对象

构造函数

创建一个构造函数,专门用来创建Person对象的,构造函数就是一个普通的函数,创建方式和普通函数没有区别,不同的是构造函数习惯上首字母大写

构造函数和普通函数的区别就是调用的方式不同,普通函数就是直接调用,而构造函数需要使用new关键字来调用

构造函数的执行流程:

1、立刻创建一个新的对象

2、将新建的对象设置为函数中This,在构造函数中可以使用this来引用新建的对象

3、逐行执行函数中的代码

4、将新建的对象作为返回值返回

使用instanceof可以检查一个对象是否是一个类的实例

使用同一个构造函数创建的对象,我们称为一类对象,也将一个构造函数称为一个类。我们将通过一个构造函数创建的对象,称为是该类的实例

原型

我们所创建的每一个函数,解析器都会向函数中添加一个属性prototype

这个属性对应一个对象,这个对象就是我们所谓的原型对象

如果函数作为普通函数调用prototype没有任何作用,当函数以构造函数的形式调用时,它所创建的对象中都会有一个隐含的属性,指向该构造函数的原型对象,我们可以通过__ proto __来方位该属性

原型对象就相当于一个公共的区域,所有同一个类的实例都可以访问到这个原型对象,我们可以将对象中共有的内容,统一设置到原型对象中

当我们访问对象的一个属性或方法时,它会先在对象自身中寻找,如果有则直接使用,如果没有则会去原型对象中寻找,如果找到则直接使用

以后我们创建构造函数时,可以将这些对象共有的属性和方法,统一添加到函数的原型对象中,这样不用分别为每一个对象添加,也不会影响到全局作用域,就可以使每个对象都具有这些属性和方法了

function MyClass(){

}
//向Myclass的原型中添加属性a
MyClass.prototype.a = 123;

var mc = new MyClass();
//console.log(MyClass.prototype);
//console.log(mc.__proto__);
console.log(mc.a);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u67gC3jv-1630464238500)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210829173704345.png)]

原型对象

原型对象也是对象,所以它也有原型

当我们使用一个对象的属性或方法时,会先在自身中寻找,自身中如果有,则直接使用。如果没有则去原型对象中寻找,如果原型对象中有,则使用。如果没有则去原型的原型中寻找,直到找到Object对象的原型

Object对象的原型没有原型,如果在Object中依然没有找到,则返回undefined

function MyClass(){

}
//向MyClass的原型添加一个name属性
MyClass.prototype.name = "原型中的名字";

var mc = new MyClass();
mc.age = 18

console.log(mc.name);

//使用in检查对象中是否含有某个属性时,如果对象中没有但是原型中有,也会返回true
console.log("name" in mc);

//可以使用对象的hasOwnProperty()来检查对象自身中是否含有该属性
//使用该方法只有对象自身含有属性时,才会返回true
console.log(mc.hasOwnProperty("age"));//true

console.log(mc.hasOwnProperty("hasOwnProperty"));//false

console.log(mc.__proto__.hasOwnProperty("hasOwnProperty"));//false

console.log(mc.__proto__.__proto__.hasOwnProperty("hasOwnProperty"));//true

toString

function Person(name, age, gender){
	this.name = name;
	this.age = age;
	this.gender = gender;
}

//创建一个Person实例
var per = new Person("zzh",30,);

//当我们直接在页面打印一个对象时,事实上是输出对象的toString()方法的返回值
//如果我们希望在输出对象不输出[Object Object],可以为对象添加一个toSTirng()方法
per.toString = function(){
    return "123";
};


var result = per.toString();
console.log(result);
//console.log(per.__protp__.__proto__,hasOwnProperty("toString"));
console.log(per);//123

垃圾回收

当一个对象没有任何的变量或属性对它进行引用,此时我们将永远无法操作该对象,此时这种对象就是一个垃圾,这种对象过多会占用大量的内存空间,导致程序允许变慢,所以这种垃圾必须进行清理。

在JS中拥有自动的垃圾回收机制,会自动将这些垃圾对象从内存中销毁,我们不需要也不能进行垃圾回收的操作

我们需要做的是将不再使用的对象设置为null即可

函数

call 和 apply

  • call()和apply()都是函数对象的方法,需要通过函数对象来调用

  • 当对函数调用call()和apply()都会调用函数执行

  • 在调用call()和apply()可以将一个对象指定为第一个参数,此时这个对象将会成为函数执行的this

  • call()方法可以将实参在对象之后依次传递

  • apply()方法需要将实参封装到一个数组中统一传递

function fun(){
	alert(this.name);
}

var obj = {
	name:"obj",
	sayName.fucntion(){
        alert(this.name);
    }
}

var obj2 = {
	name:"obj2",
	sayName.fucntion(){
        alert(this.name);
    }
}

obj.sayName.apply(obj2);//obj2

arguments

在调用函数时,浏览器每次都会传递两个隐含的参数:函数的上下文对象this和封装实参的对象 arguments

arguments是一个类数组对象,它也可以通过索引来操作数据,也可以获取长度

在调用函数时,我们所传递的实参都会在arguments中保存

我们即使不定义形参,也可以通过argument来使用实参,只不过比较麻烦,arguments[0] 表示第一个实参

其中有一个属性callee,这个属性对应一个函数对象,就是当前正在指向的函数的对象

function fun(){
	console.log(arguments instanceof Array);
    console.log(Array.isArray(argument));
    console.log(arugument.length);//实参的长度
    console.log(argument[1]);
}

fun("hello", true);

Date

//创建一个Date对象
//如果直接使用构造器创建一个Date对象,则会封装为当前代码执行的时间
var d = new Date();

//创建以恶搞指定的时间对象
//需要在构造函数中传递一个表示时间的字符串作为参数
var d2 = new Date("12/03/2016");

console.log(d2);

包装类

在JS中提供了三个包装类,通过三个包装类可以将基本数据类型转换为对象

String() 可以将基本数据类型字符串转为String对象

Number() 可以将基本数据类型的数字转换为Number对象

Boolean() 可以将基本数据类型的布尔值转换为Boolean对象

但是我们在实际应用中不会使用基本数据类型的对象,如果使用基本数据类型的对象,在做一些比较时可能会带来一些不可预料的结果

方法和属性能添加给对象,不能添加给基本数据类型,当我们使用一些基本数据类型的值去调用属性和方法时,浏览器会临时使用包装类将其转换为对象,然后再调用对象的属性和方法。调用完以后,在将其转换为基本数据类型

var a = 123;

s = s.toString();

console.log(s); //123
console.log(typeof s); //string

正则表达式

正则表达式用于定义一些字符串的规则

//创建正则表达式的对象:

var 变量 = new RegExp("正则表达式",“匹配模式")

//正则表达式的方法 test() 用来检查一个字符串是否符合正则表达式
//在构造函数中可以传递一个匹配模式作为第二个参数:
//可以是 i 忽略大小写 g 全局匹配模式
                    
// 使用字面量来创建正则表示式更简单
// 使用构造函数创建更加灵活                   
var reg = /a/i;                    

正则表达式的使用:

// | 表示或 []也表示或 [a-z] 任意小写字母 [A-Z] 任意大写字母 [A-z]任意字母
// [^ ] 除了
支持正则表达式的String对象的方法

search 检索与正则表达式相匹配的值

match 找到一个或多个正则表达式的匹配

replace 替换与正则表达式匹配的子串

split 把字符串分割为字符串数组

正则表达式语法

量词 通过量词可以设置一个内容出现的次数

var reg = /a{3}/; //a出现3次

reg = /ab{1,3}c/; //限制b出现1到3次

reg = /ab{3,}c/; //b出现3次以上

reg = /ab+c/; //至少一个b

reg = /ab*c/; //0个或多个

reg = /ab?c/; //0个或1个

req = /^a/; //以a开头

req = /a$/; //$表示结尾 

req = /^a|a$/; //以a开头或以a结尾

手机号的规则:

1、以1开头

2、第二位3-9任意数字

3、三位以后任意数字9个

req = /^1[3,9][0-9]{9}$/

正则表达式中\表示转义字符 .表示任意字符

在使用构造函数时,由于它的参数是一个字符串,而\是字符串中的转义字符,如果要使用\则需要使用 \ \来代替

\w 任意字母,数字,_
\W 除了字母,数字,_
\d 任意的数字
\D 除了数字
\s 空格
\S 除了空格
\b 单词边界
\B 除了单词边界

//去除字符串中前后的空格
str = str.replace(/^\s*|\s*$/g, "");

邮件的正则

任意字母数字下划线.任意字母数字下划线@ 任意字母数字.任意字母(2-5位)

var emailReg = /^\w{3,}(\.\w+)@[A-z0-9]+(\.[A-z]{2,5}){1,2}$/;

DOM

DOM 全称Document Object Model 文档对象模型

JS通过DOM来对HTML文档进行操作,只要理解了DOM就可以随心所欲的操作WEB界面

文档表示的就是整个的HTML网页文档,对象表示将网页中的每一个部分都转换为了一个对象,使用模型来表示对象之间的关系,这样方便我们获取对象

节点是构成我们网页的最基本的组成部分,网页中的每一个部分都可以称为是一个节点,标签称为元素节点,属性称为属性节点,文本称为文本节点,文档称为文档节点

节点的类型不同,属性和方法也都不尽相同、[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W0db4wh6-1630464238503)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210830171947519.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NgVhXXP6-1630464238504)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210830171913971.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hAp4sEM2-1630464238507)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210830172048942.png)]

浏览器已经为我们提供文档节点,可以在页面中直接使用,文档节点代表的是整个网页

<body>
    <button id="btn">
        这是一个按钮
    </button>
    <script type="text/javascrpit">
    	//获取到button对象
		var btn = document.getElementById(”btn“);
		
		//修改按钮的文字
		btn.innerHTML = "修改";
    </script>
</body>

事件

JS与HTML之间的交互是通过事件来实现的,我们可以在事件对应的属性中设置一些js代码,这样当事件被触发时,这些代码将会执行

可以为按钮的对应事件绑定处理函数的形式来响应事件

这样当事件被触发时,其对应的函数将会被调用

//获取按钮对象
var btn = document.getElementById("btn");

//绑定一个单击事件
//像这样为单击事件绑定的函数,我们称为单击响应函数
btn.onclick = function(){
    alert("123");
}

文档的加载

浏览器在加载一个页面时,是按照自上向下的顺序加载的,读取到一行就运行一行,如果将script标签写到页面的上边,在代码执行时,页面还没有加载

将js代码编写到页面下部就是为了可以在页面加载完毕以后再执行js代码

onload事件会在整个页面加载完成之后才能触发,该事件对应的响应函数会在页面加载完成之后执行,这样可以确保我们的代码执行所有的DOM对象已经加载完毕了

//为window绑定一个onload事件
window.oncload = function(){
	alert("hello");
}

DOM查询

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wVVEvYqx-1630464238508)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210830183954453.png)]

innerHTML用于获取元素内部的HTML代码的,对于自结束标签,这个属性没有意义 比如input

如果需要读取元素节点属性,直接使用元素.属性名,class属性不能使用这种方式,读取class属性需要使用元素.className

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mqphFe9J-1630464238510)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210830190243724.png)]

childNode属性 在IE8以上会包括空白文本,IE8以下不包括,所以推荐使用children属性,可以获取当前元素的所有子节点,并且兼容

firstChild也包括空白文本节点,firstElementChild获取当前元素的第一个子元素(不包括空白文本节点),但是它不支持IE8及以下的浏览器,如果需要兼容,尽量不要使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FEmVbVs0-1630464238511)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210830191653832.png)]

在document中有一个属性body,它保存的是body的引用

//获取body标签
var body = document.body;

var html = document.documentElement;

//document.all代表页面中所有元素
var all = document.all;

for(var i=0;i<all.length;i++){
    console.log(all[i]);
}

all = document.getElementByTagName("*");

//根据元素class属性查询一组元素节点对象
//getElementByClassName()根据class属性值获取一组元素节点对象,但是该方法不支持IE8及其以上
var box1 = document.getElementByClassName("box1");

//获取class为box1中的所有div
//querySelector()需要一个选择器的字符串来作为参数,可以根据一个CSS选择器来查询一个元素节点对象
//IE8可以使用querySelector()代替getElementByClassName()
//使用该方法会返回唯一的一个元素,如果满足条件的元素有多个,则只会返回第一个
document.querySelector(".box1 div");

document.querySelector(".box1");
console.log(div.innerHTML);

//把所有符合条件的元素封装成数组
//即使符合条件的元素只有一个,它也会返回数组
var box1 = document.querySelectorAll(".box1")

DOM增删改

document.createElement()

可以用于创建一个元素节点对象,它需要一个标签名作为参数,将会根据标签名创建元素节点对象,并将创建好的对象作为返回值返回

document.createTextNode()

可以用来创建一个文本节点对象,需要一个文本内容作为参数,将会根据该内容创建文本节点,并将新的节点返回

appendChild()

向一个父节点中添加一个新的子节点

insertBefore()

可以在指定的子节点前插入新的子节点(父节点来调用)

repladeChild()

可以使用指定子节点来替换已有子节点

removeChild()

可以删除一个子节点。子节点.parentNode可以调用父节点

window.onload = function(){
    //创建一个"广州"节点,添加到city下
    myClick("btn01", function(){
        //创建广州节点<li>广州<li>
        //创建li节点
        var li = document.createElement("li");
        //创建广州文本节点
        var gzText = document.createTextNode();
        li.appendChild(gzText);\
        //获取id为city的节点
        var city = document.getElementById("city");
        //将广州添加到city下
        city.appendChild(li);
    })
    //添加广州节点的另一种方式,推荐使用这种
    var li = document.createElement("li");
    //向li中设置文本
    li.innerHTML = "广州";
    //将li添加到city中
    city.appendChild(li);
}
function myClick(idStr, fun){
    var btn = document.getElementById(idStr);
    btn.onclick = fun;
}

for循环

for循环在页面加载完成之后立即执行,而响应函数会在超链接被点击时才执行,当响应函数执行时,for循环早已经执行完毕

操作内联样式

通过js修改元素的样式:

如果CSS样式名中含有- 这种名称在JS中是不合法的比如background-color

需要将这种样式名修改为驼峰命名法 去掉 -,然后将- 后的字母大写

我们通过style属性设置的样式都是内联样式 ,而内联样式具有较高的优先级,所有通过JS修改的样式往往会立即现实

但是如果在样式中写了!important,则此时样式会有最高的优先级,即使通过JS也不能覆盖该样式,此时将会导致JS修改样式失败,所以尽量不要为样式添加!important

通过style属性设置和读取的都是内联样式,无法读取样式表中的样式

window.onload = function(){
    //点击按钮以后,修改box1的大小
    var box1 = document.getElementById("box1");
    //为按钮绑定单击响应函数
    var btn01 = document.getElementById("btn01");
    btn01.onclick = function(){
        //修改box1的宽度
        box1.style.width = "300px";
        box1.backgroundColor = "yellow";
    }
}
读取元素样式

获取元素当前显示的样式

元素.currentStyle.样式名

它可以用来读取当前元素正在显示的样式,如果当前元素没有设置该样式,则去读取它的默认值,但是只有IE浏览器支持,其他浏览器都不支持


在其他浏览器中可以使用getComputeStyle()这个方法来获取元素当前的样式,这个方法是window的方法,可以直接使用

需要两个参数,第一个是要获取样式的元素,第二个是可以传递一个伪元素,一般都传null

该方法会返回一个对象,对象中封装了当前元素对应的样式,可以通过对象.样式名来读取样式,如果获取的样式没有设置,则会获取到真实的值,而不是默认值

但是该方法不支持IE8及以下的浏览器

事件对象

事件对象:当事件的响应函数被触发时,浏览器每次都会将一个事件对象传递进响应函数

在事件对象中封装了当前事件相关的一切信息

onmousemove 该事件将会在鼠标在元素中移动时触发

在IE8中,响应函数被触发时,浏览器不会传递事件对象。在IE8及以下的浏览器中,是将事件对象作为window对象的属性保存的

//当鼠标在areaDiv中移动时,在showMsg中显示鼠标的坐标
var areaDiv = document.getElementById("areaDix");
var showMsg = document.getElementById("showMsg");

areaDiv.onmousemove = function(event){
    //clientX 表示x坐标 clientY 表示y坐标
    var x = event.clientX;
    var y = event.clientY;
    
    //在showMsg中显示鼠标的坐标
    showMsg.innerHTML = x + y;
}

事件冒泡

事件的冒泡:

所谓的冒泡指的就是事件的向上传导,当后代元素上的事件被触发时,其祖先元素的相同事件也会被触发

在开发中大部分情况冒泡都是有用的,如果不希望发生事件冒泡可以通过事件对象来取消冒泡

event.cancelBubble = true

事件的委派

事件的委派

指将事件统一绑定给元素共同的祖先元素,这样当后代元素上的事件触发时,会一直冒泡到祖先元素,从而通过祖先元素的响应函数来处理事件

事件委派是利用了冒泡,通过委派可以减少事件绑定的次数,提供程序的性能

//只绑定一次事件,即可应用到多个元素上,即使元素是后添加的
//可以尝试将其绑定给元素的共同的祖先元素
ul.onclick = function(event){
    event = event || window.event;
    
    //target event中的target表示触发事件的对象
    if(event.target,className == "link"){
        alert("123");
    }
}

事件的绑定

使用对象.事件 = 函数的方法绑定函数,它只能为一个元素的一个事件绑定一个响应函数,不能绑定多个,如果绑定了多个,则后面的会覆盖掉前面的

addEventListener() 通过这个方法也可以为元素绑定响应函数,可以同时为一个元素的相同事件同时绑定多个响应函数,这样当事件触发时,响应函数将会按函数的绑定顺序执行

这个方法不支持IE8及以下的浏览器

参数:

1、事件的字符串,不要on

2、回调函数,当事件触发时该函数会被调用

3、是否在捕获阶段触发事件,需要一个新的布尔值,一般都传false


attachEvent()

在IE8中可以使用attchEvent()来绑定事件,可以为一个事件绑定多个函数,不同的是它后绑定先执行,执行顺序和addEventListener()相反

参数:

1、事件的字符串,要on

2、回调函数


定义绑定函数

//定义一个函数,用来为指定元素绑定响应函数
//addEventListener()中的this,是绑定事件的对象
//attachEvent()中的this 是window

//参数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(){
            //call改变This指定的对象
            callback.call(obj)
        });
    }
    
}

事件的传播

关于事件的传播网景公司和微软公司有不同的理解

微软公司认为事件应该是由内向外传播,也就是当事件传播时,应该先触发当前元素上的事件,然后再向当前元素的祖先元素上传播,也就是事件应该在冒泡阶段执行

网景公司认为事件是由外向内传播的,也就是当前事件触发时,应该先触发当前元素的最外层的祖先元素的事件

W3C综合了两个公司的方案,将事件传播分成了三个阶段:

1、捕获阶段

在捕获阶段时从最外层的祖先元素,向目标元素进行事件的捕获,但是默认此时不会触发事件

2、目标阶段

事件捕获到目标元素,捕获结束开始在目标元素上触发事件

3、冒泡阶段

事件从目标元素向它的祖先元素传递,依次触发祖先元素上的事件

如果希望在捕获阶段就触发事件,可以将addEventListener()的第三个参数设置为true

剩下的内容跳过了。。

BOM

BOM是浏览器对象模板,BOM可以使我们通过JS来操作浏览器,在BOM中为我们提供了一组对象,用来完成对浏览器的操作

BOM对象:

  • Window 代表整个浏览器的窗口,同时window也是网页中的全局对象
  • Navigator 代表的当前浏览器的信息,通过该对象可以来识别不同的浏览器
  • Location 代表当前浏览器的地址栏信息,通过Location可以获取地址栏信息,或者操作浏览器跳转页面
  • History 代表浏览器的历史记录,可以通过该对象来操作浏览器的历史记录,由于隐私问题,该对象不能获取的具体的历史记录,只能操作浏览器向前或向后翻页,而且此操作只能在当次访问有效
  • Screen 代表用户的屏幕信息,通过该对象可以获取到用户显示器的相关信息

Navigator

由于历史原因,Navigator对象中的大部分属性已经不能帮助我们识别浏览器了,一般我们只会使用userAgent来判断浏览器的信息

userAgent是一个字符串,这个字符串中包含有用来描述浏览器信息的内容,不同浏览器会有不同的userAgent

如果使用userAgent不能判断,还可以通过一些浏览器中特有的对象,来判断浏览器的信息,比如ActiveObejct

history

history.length() 可以获取到当前访问的链接数量

history.back() 可以用来回退到上一个页面,作用和浏览器的回退按钮一样

history.forward() 可以跳转到下一个页面,作用和浏览器的前进按钮一样

history.go() 可以用来跳转到指定页面,它需要一个整数作为参数,1表示向前跳转一个页面

Location

如果直接打印location,则可以获取到地址栏的信息(当前页面的完整路径)

如果直接将location属性修改为一个完整的路径,或相对路径,则我们页面将会自动跳转到该路径

assgin() 用来跳转到其他页面,作用和直接修改location一样

reload() 用来更新加载当前页面,作用和刷新按钮一样,如果在方法中传递一个true,作为参数,则会强制清空缓存刷新页面

replace() 可以使用一个新的页面替换当前页面,调用完毕也会跳转页面,不会生成历史记录,不能使用回退按钮回退

定时器

setInterval() 定时调用,可以将一个函数,每隔一段时间执行一次

参数:

1、回调函数,该函数每隔一段时间被调用一次

2、每次调用间隔的事件,单位是毫秒

返回值是一个Number类型的数据,这个数字用来作为定时器的唯一标识

ocation可以获取地址栏信息,或者操作浏览器跳转页面

  • History 代表浏览器的历史记录,可以通过该对象来操作浏览器的历史记录,由于隐私问题,该对象不能获取的具体的历史记录,只能操作浏览器向前或向后翻页,而且此操作只能在当次访问有效
  • Screen 代表用户的屏幕信息,通过该对象可以获取到用户显示器的相关信息

Navigator

由于历史原因,Navigator对象中的大部分属性已经不能帮助我们识别浏览器了,一般我们只会使用userAgent来判断浏览器的信息

userAgent是一个字符串,这个字符串中包含有用来描述浏览器信息的内容,不同浏览器会有不同的userAgent

如果使用userAgent不能判断,还可以通过一些浏览器中特有的对象,来判断浏览器的信息,比如ActiveObejct

history

history.length() 可以获取到当前访问的链接数量

history.back() 可以用来回退到上一个页面,作用和浏览器的回退按钮一样

history.forward() 可以跳转到下一个页面,作用和浏览器的前进按钮一样

history.go() 可以用来跳转到指定页面,它需要一个整数作为参数,1表示向前跳转一个页面

Location

如果直接打印location,则可以获取到地址栏的信息(当前页面的完整路径)

如果直接将location属性修改为一个完整的路径,或相对路径,则我们页面将会自动跳转到该路径

assgin() 用来跳转到其他页面,作用和直接修改location一样

reload() 用来更新加载当前页面,作用和刷新按钮一样,如果在方法中传递一个true,作为参数,则会强制清空缓存刷新页面

replace() 可以使用一个新的页面替换当前页面,调用完毕也会跳转页面,不会生成历史记录,不能使用回退按钮回退

定时器

setInterval() 定时调用,可以将一个函数,每隔一段时间执行一次

参数:

1、回调函数,该函数每隔一段时间被调用一次

2、每次调用间隔的事件,单位是毫秒

返回值是一个Number类型的数据,这个数字用来作为定时器的唯一标识

clearInterval() 可以用来关闭一个定时器,方法需要一个定时器的标识作为参数,关闭对应的定时器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qtayu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值