同步和异步
- 浏览完提供了同步和异步的机制,但是JS是单线程,提供给了两个队列,一个是主队列,另一个是异步队列
同步
- 所有的代码按顺序执行,每一部分代码执行完后才能执行下面的代码
异步
- 这块代码执行后,可以去做其他事情,等这块代码执行完后再回来处理这里的事项
- 异步的性能会高些 例如:回调函数,ajax,定时器,事件......
- 同步代码执行完才会执行异步代码
异步回调地狱 Promise处理
- 异步的代码当成同步代码来写 升级版:async +await
- Promise是构造函数,new去运行,参数是一个回调函数
- 回调函数有两个参数:resolve(表示执行成功的回调)和reject(表示执行失败的回调)
- Promise的实例会调用then方法,是Promise类原型上的方法,通过实例调用,then有两个参数,第一个表示成功的回调,第二个表示失败的回调
- then方法返回的新的Promise的实例,所有可以继续调用then方法(勒斯于jQuery的链式写法)
p.then(function (data) {
console.log(data);
},function () {
throw new Error("error1");//只有手动抛出异常状态才会变成失败的状态,其他都是成功状态(前提是没有再返回Promise对象)
}).then(function () {
console.log("b");
},function () {
console.log("error2");
})
- Promise有三种状态,第一种是pending(等待),第二种是fulfilled(成功),第三种是rejected(失败)
let p = new Promise(function (resolve,reject) {
window.setTimeout(function () {//属于pending(等待状态),要异步
resolve("s");
},1000)
});
p.then(function (data) {
console.log(data);
},function () {
console.log(2);
})
事件
- 是一件事
- 事件是已经存在的,系统处理好的
鼠标事件
- click/mouseover/mouseout/mouseenter/mousemove/mouseleave/mousewheel
键盘事件
- keydown(按下时触发)/keyup(抬起来时触发)/ketpress(按下并抬起来时触发)
系统事件
- resize(浏览器窗口发生改变时触发)/scroll(滚动条发生改变时触发)/DOMContentLoaded(DOM元素加载完后再触发)
表单元素
- change(表单元素发生改变时触发)/input(移动端,表单元素输入时触发)/blur(光标离开表单元素时触发)/focus(光标在表单元素时触发)
事件绑定
- 事件(行为)发生时做些具体的事情
- DOM0级事件绑定和DOM2级事件绑定
oDiv.onclick = function () {//DOM0级绑定
alert(1);
}
//标准浏览器下DOM2级事件
//第一个参数:事件类型
//第二个参数:事件绑定的行为
//第三个参数:事件传播的方式
oDiv.addEventListener("click", function () {
alert(1);
}, false)
- DOM0级事件的绑定问题:对同一事件绑定多个行为时,后面的行为会覆盖前面的行为,最终只会执行最后一次绑定的行为
oDiv.addEventListener("click", function () {
alert(1);
}, false);
oDiv.addEventListener("click", function () {
alert(2);
}, false);
//会先弹出1后弹出2
- IE6 - IE8 DOM2级事件绑定
oDiv.attachEvent("onclick",function () {
alert(3);
})
- DOM0级事件的移除
oDiv.onclick = null;
- 标准浏览器 DOM2级事件移除
oDiv.removeEventListener("click",fn,false);
- IE6-IE8 DOM2级事件移除
oDiv.detachEvent("onclick",fn)
- IE没有处理重复绑定,标准浏览器处理了重复绑定
- IE下事件绑定行为是window,标准浏览器下事件绑定行为中this是绑定的元素
- IE下事件绑定行为执行的顺序是乱的,标准浏览器下是按照先后绑定的顺序执行
事件对象 e
- 浏览器记录了事件
var oDiv = document.getElementById("div1");
oDiv.onclick = function (e) { //鼠标事件相关信息
console.log(e);//天生存在的用来存储事件的相关信息
console.log(e.clientX);//到窗口左边的距离
console.log(e.clientY);//到窗口上边的距离
console.log(e.pageX);//到文档左边的距离 IE下不支持
console.log(e.type);//事件的类型
console.log(e.target);//事件源 事件绑定的元素 IE下不支持
console.log(e.srcElement)//IE支持事件源
e.preventDefault();//阻止默认行为 IE低版本浏览器 e.returnValue = false;
e.stopPropagation();//阻止冒泡 IE低版本浏览器 e.cancelBubble = true;
//ie6 - ie8
console.log(window.event);//接受事件对象
//为了所有浏览器都能拿到事件对象
e = e || window.event;
}
DOM事件绑定阻止默认行为
var oA = document.getElementById("a");
oA.onclick = function () {
alert(1);
return false;//DOM0级事件绑定阻止默认行为
};
oA.addEventListener("click",function () {
alert(1);
e.preventDefault();//DOM2级事件绑定只能通过e.preventDefault()来阻止
})
事件传播:冒泡和捕获
-
事件冒泡:当前元素被触发后,其祖先元素的相同事件也会被触发,由内往外
-
事件捕获:当前元素被触发后,其祖先元素的相同事件会被触发,由外向内
-
标准浏览器下DOM2级事件绑定方式才有)
-
mouseover事件问题
- 通过事件冒泡的机制,盒子的mouseover触发时,会导致绿色盒子mouseover事件也被触发
- 从红盒子到绿盒子时又会导致绿盒子的mouseover,还是mouseover事件自己的原因
- 以上两个问题都可以通过mouseenter事件解决(仅局限于绿盒子里,在绿盒子外还是事件冒泡)
- mouseover->mouseenter/mouseout->mouseleave