计算啊啊啊

day15 事件对象

1.回顾

2.==懒加载==

  • 懒加载的应用场景:在一些电商类平台网站上 由于页面要加载的数据量较庞大,因此如果直接将页面所有内容都加载出来,会导致页面的加载时间过长,导致页面白屏。

    因此,开发者们想出了懒加载的办法——只加载用户看得见的部分,看不见的部分不加载。这样单次加载的内容就相对较少,加载时间减短,从而提升用户体验。

  • 懒加载实现思路:

    • 第一步:先渲染图片结构,把图片资源先暂时给img的src1属性

    • 第二步:显示第一屏效果,只要图片的位置小于窗口可视高度就显示出来

      • 只加载可视区域内的照片

      • 窗口的可视高度 document.documentElement.clientHeight

      • 图片在页面中的位置 图片.offsetTop

      • 默认情况所有的图片都不显示 先将图片路径给自定义属性src1 如果要显示该图片将src1给src

    • 第三步:当滚动滚动的时候,再次判断图片是否在可视范围内容

      • 判断范围:页面的可视高度+页面卷起的高度 document.documentElement.scrollTop + document.documentElement.clientHeight

<body>
    <ul></ul>
    <script>
        // 1.通过for循环渲染结构
        var oUl = document.getElementsByTagName("ul")[0];
        var str = "";
        for (var i = 0; i < arr.length; i++) {
            str += `<li><img src1="${arr[i]}" alt=""></li>`
        }
        // console.log(str);
        oUl.innerHTML = str;
​
        // 2.显示第一屏效果
        /*
                只加载可视区域内的照片
                 窗口的可视高度 document.documentElement.clientHeight
                 图片在页面中的位置  图片.offsetTop
                 默认情况所有的图片都不显示  先将图片路径给自定义属性src1 如果要显示该图片将src1给src
        */
        var oImg = document.getElementsByTagName("img");
        for (var i = 0; i < oImg.length; i++) {
            // console.log(oImg[i].offsetTop);
            if (oImg[i].offsetTop <= document.documentElement.clientHeight) {
                console.log("第" + i + "张图片");
                oImg[i].src = oImg[i].getAttribute("src1");
            }
        }
​
        // 2.页面滚动  显示可视范围内容的数据
        window.onscroll = function () {
            var sT = document.documentElement.scrollTop + document.documentElement.clientHeight
            // 将所有的图片再判断一次
            for (var i = 0; i < oImg.length; i++) {
                if (oImg[i].offsetTop <= sT) {
                    console.log("第" + i + "张图片");
                    oImg[i].src = oImg[i].getAttribute("src1");
                }
            }
        }
    </script>
</body>

3.==事件对象==

3.1事件对象

  • 事件对象:每一个事件都会有一个对象,这个对象用来记录和该事件有关的一些信息

  • 如何获取事件对象

    • 标准浏览器和IE浏览器:window.event

    • 低版本火狐浏览器:火狐低版本浏览器 在事件处理函数中的第一个参数就是事件对象

  • 兼容事件对象

    • window.event || 第一个参数

<body>
    <div></div>
    <script>
        var oDiv = document.getElementsByTagName("div")[0];
        oDiv.onclick = function (eve) {
            console.log(window.event);//标准浏览器和IE浏览器
            // 火狐低版本浏览器  在事件处理函数中的第一个参数就是事件对象
            console.log(eve);
            // 兼容事件对象   window.event || 第一个参数
            var ev = window.event || eve;
            console.log(ev);
        }
    </script>
</body>
  • 事件对象中的属性

    • altKey/shiftKey/ctrlKey:表示在执行事件的时候,是否同时按住alt shift ctrl键,执行的时候按住是返回true,否则返回false

    • clientX/clientY:表示鼠标都可视窗口左侧和上侧的距离

    • pageX/pageY:表示鼠标位置到页面左侧和上侧的距离,==存在IE兼容问题==

      • pageX = clientX + 页面卷起的宽度

      • pageY = clientY + 页面卷起的高度

      • 在IE低版本去获取pageX和pageY,因为在IE版本没有办法获取Pagex和pageY,所以我们可以用卷起的高度+clientx

    • target:目标源/事件源,事件触发事件的元素,==存在IE兼容问题==

      • 标准浏览器:事件对象.target

      • IE低版本:事件对象.srcElement

    • type:添加事件的类型,没有on

3.2事件绑定

3.2.1之前绑定事件

  • 语法:标签.事件类型 = function(){}

  • ==缺点:同种事件类型一次只能绑定一个,后者会覆盖前者==

 <button>按钮1</button>
    <script>
        // 1.之间的方式绑定事件
        var btn = document.getElementsByTagName("button")[0];
        // 标签.事件类型 = function(){}  缺点:只能绑定一个事件
        // 程序员1
        btn.onclick = function () {
            console.log("按钮1")
        }
        // 程序员2
        btn.onclick = function () {
            console.log("按钮2")
        }
     </script>

3.2.2事件绑定

基础语法

  • 标准浏览器:标签.addEventListener(事件类型(不加on),事件处理函数,事件捕获)

  • IE低版本浏览器:标签.attachEvent(事件类型(加on),事件处理函数)

  //标准浏览器
        btn.addEventListener("click", function () {
            console.log("按钮1")
        })
        btn.addEventListener("click", function () {
            console.log("按钮2")
        })
​
        // IE低版本
        btn.attachEvent("onclick", function () {
            console.log("按钮3")
        })
        btn.attachEvent("onclick", function () {
            console.log("按钮4")
        })

==两者区别==

  • ==面试题:addEventListener和attachEvent事件绑定有什么区别?==

    • addEventListener 事件类型不加on,有事件捕获,执行顺序从前往后执行

    • attachEvent 事件类型加on 没有事件捕获 执行顺序从后往前执行

浏览器兼容

  • 事件绑定浏览器兼容 if(判断某个方法是否存在){}else{}

 // 事件绑定兼容   方法兼容  window.getComputedStyle()
        if (btn.addEventListener) {//标准浏览器
            console.log("标准浏览器");
            btn.addEventListener("click", function () {
                console.log("按钮1");
            })
        } else {//IE低版本浏览器
            console.log("IE低版本");
            btn.attachEvent("onclick", function () {
                console.log("按钮1")
            })
        }

==事件绑定函数封装==

function bind(elem, type, fun) {
    //elem:绑定事件的标签  type:事件类型 fun:事件处理函数
    if (elem.addEventListener) {//标准浏览器
        console.log("标准浏览器");
        elem.addEventListener(type, fun)
    } else {//IE低版本浏览器
        console.log("IE低版本");
        elem.attachEvent("on" + type, fun)
    }
}
​
        //调用
        bind(btn, "click", function () {
          console.log("按钮1")
        })
        bind(btn, "click", function () {
            console.log("按钮2")
        })

3.3事件取消

3.3.1之间的事件取消

  • 标签.事件类型 = null

 // 之间的事件绑定
        btn.onclick = function () {
            console.log("按钮1");
            // 执行一次之后  解除事件  标签.事件类型 = null
            btn.onclick = null;
        }

3.3.2事件取消

基础语法

  • 标准浏览器:标签.removeEventListener(事件类型(不加on),事件处理函数,是否捕获)

  • IE低版本:标签.detachEvent(事件类型(加on),事件处理函数)

// 标准浏览器 事件取消
btn.removeEventListener("click", fun1)
// IE低版本  事件取消
btn.detachEvent("onclick", fun1)

浏览器兼容

 // 浏览器兼容  事件取消 
            if (btn.removeEventListener) {
                btn.removeEventListener("click", fun1)
            } else {
                btn.detachEvent("onclick", fun1);
            }

事件取消函数封装

 //事件取消
        function unbind(elem, type, fun) {
            if (elem.removeEventListener) {
                elem.removeEventListener(type, fun)
            } else {
                elem.detachEvent("on" + type, fun);
            }
        }

3.4事件流

  • 事件流:当事件发生的时候,事件在字符节点之间的固定传递顺序

  • 捕获型事件(标准) 冒泡性事件

  • 事件流会经历三个阶段

    • 捕获阶段:当事件发生的时候 事件从window开始往子元素传递

    • 确定目标:确定真正触发事件的元素

    • 冒泡阶段:目标源接受到事件之后开始处理事件,处理完成之后,会将事件从当前往父节点传递 直到window

<body>
    <div class="box1">
        box1盒子
        <div class="box2">
            box2盒子
            <div class="box3">box3盒子</div>
        </div>
    </div>
    <script>
        // 1.绑定事件 addEventListener(事件类型,事件处理函数,是否事件捕获) true事件捕获 false事件冒泡  默认是false
        var oDiv = document.getElementsByTagName("div");
        oDiv[0].addEventListener("click", function () {
            console.log("box1")
        })
        oDiv[1].addEventListener("click", function () {
            console.log("box2")
        })
        oDiv[2].addEventListener("click", function () {
            console.log("box3")
        })
    </script>
</body>
​

3.5阻止事件冒泡

  • 标准浏览器 事件对象.stopPropagation()

  • IE低版本 事件对象.cancelBubble = true

  • 阻止事件冒泡兼容

    • ev.stopPropagation ? ev.stopPropagation() : ev.cancelBubble = true

<body>
    <button>按钮1</button>
    <script>
        document.documentElement.onclick = function () {
            console.log("这是全局window的事件")
        }
        var btn = document.getElementsByTagName("button")[0];
        btn.onclick = function (eve) {
            console.log("按钮1");
            // 阻止冒泡 
            // 标准浏览器  事件对象.stopPropagation()
            var ev = window.event || eve;//事件对象
            // ev.stopPropagation();
            // IE低版本   事件对象.cancelBubble = true
            // ev.cancelBubble = true
            // 阻止事件冒泡兼容  
            ev.stopPropagation ? ev.stopPropagation() : ev.cancelBubble = true
        }
    </script>

3.6阻止默认行为

 有很多标签都是有默认行为的,例如:a标签的跳转、右键菜单、图片拖拽保存等等
  • return false; ==只适用用绑定方式是:标签.事件类型=function(){}==

  • 标准浏览器:事件对象.preventDefault()

  • IE低版本:事件对象.returnValue = false;

  • 阻止事件默认行为兼容

    • ev.preventDefault ? ev.preventDefault() : ev.returnValue = false;

<body>
    <a href="">跳转</a>
    <script>
        var oA = document.getElementsByTagName("a")[0];
        oA.onclick = function (eve) {
            console.log(1);
            return false;//阻止默认行为,但是只适用于绑定方式是标签.事件类型这种方法
            // 标准浏览器:事件对象.preventDefault()
            var ev = window.event || eve;
            ev.preventDefault();
            // IE低版本:事件对象.returnValue = false;
            ev.returnValue = false;
​
            // 阻止默认行为兼容
            ev.preventDefault ? ev.preventDefault() : ev.returnValue = false;
        }
​
        oA.addEventListener("click", function (eve) {
            //return false 没有效果
            var ev = window.event || eve;
            console.log(2);
            ev.preventDefault ? ev.preventDefault() : ev.returnValue = false;
        })
​
    </script>
</body>

3.7事件委托

  • 在我们需要添加大量事件的时候,为了节省性能,我们一般会用到事件委托(事件代理)

  • 实现场景:我们现在有10000个li标签,要给给每个li标签都添加点击事件,如果用for循环添加 需要执行的时间比较长,会浪费计算机性能 此时我们推荐用事件委托

  • 事件委托实现的思路

    • 给所有要添加事件元素的父元素添加事件

    • 在父元素执行的时候,找到目标源执行操作

 // 事件委托:给li添加点击事件  点谁就改变谁的背景色
        // 1.找添加事件元素的共同父元素,将事件添加给共同父元素
        var oul = document.getElementsByTagName("ul")[0];
        oul.onclick = function (eve) {
            // 2.找目标源 真正触发事件的元素  事件对象.target || 事件对象.srcElement
            var ev = window.event || eve;//事件对象
            var target = ev.target || ev.srcElement;
            console.log(target)
            // 3.判目标源是不是真正要添加事件的元素  nodeName 节点的名称
            if (target.nodeName == "LI") {
                //4.执行操作
                target.style.backgroundColor = "red";
            }
        }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值