前端基础27:同步异步/事件绑定等问题

1,661 阅读4分钟

同步和异步

  • 浏览完提供了同步和异步的机制,但是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