懒加载和事件对象

1.懒加载

  • 懒加载的应用场景

    • 在各大电商平台的网站上,由于页面需要记载很多很多图片,如果直接网页上的所有的图片都加载出来,数据比较庞大,会导致页面加载过程,页面会出现白屏效果,对用户体验不友好
  • 懒加载的实现思路

    • 在页面加载的时候 判断哪些内容是在用户的可视区域,只加载用户可视范围的内容,看不见的部分暂时不加载,等滚动条滚动到该区域的时候,再起加载图片
  • 实现代码

     var list = document.getElementsByTagName("ul")[0];
            // 1.追加结构
            // 如果直接将结构给innerHTML 会一直重写,也会影响页面性能 所以先将结构给一个空字符串,再将空字符串给页面结构
            var str = "";
            for (var i = 0; i < arr.length; i++) {
                // innerHTML有重写的功能
                str += `<li>
                           <img a="${arr[i]}" alt="">
                        </li>`
            }
            list.innerHTML = str
    
            // 2.显示第一屏效果
            /* 
                只要在页面的可视范围内  都将图片显示出来
                    页面的可视范围高度   doucument.documentElement.clientHeight
                    图片在页面中的位置   图片.offsetTop
                    图片显示出来     将自定义属性src1 给src属性
            */
            var oImg = document.getElementsByTagName("img");
            var pageClientHeight = document.documentElement.clientHeight;
            console.log(pageClientHeight)
            for (var i = 0; i < oImg.length; i++) {
                if (oImg[i].offsetTop <= pageClientHeight) {
                    console.log("这是第一屏效果", "这是第" + i + "张图")
                    oImg[i].src = oImg[i].getAttribute("a")
                }
            }
    
            // 2.页面滚动  显示可视范围内容的数据
    			  /*
    			  	  页面的范围:页面的可视高度+页面卷起的高度
    			  */	
            window.onscroll = function () {
                // 页面卷去的高度
                var sT = document.documentElement.scrollTop || document.body.scrollTop
                for (var i = 0; i < oImg.length; i++) {
                    if (oImg[i].offsetTop <= (pageClientHeight + sT)) {
                        console.log("第" + i + "张图", "window.onscroll判断")
                        oImg[i].src = oImg[i].getAttribute("a")
                    }
                }
            }
    

2.事件对象

2.1什么是事件对象

  • 每一个事件都有事件对象 这个对象中用来记录和该事件有关的一些信息
  • 注意:在事件处理函数中才可以使用事件对象
  • 如何获取事件对象
    • 标准浏览器和IE浏览器 window.event
    • 老版本火狐浏览器 在事件处理函数中的第一个参数作为事件对象
  • 事件对象兼容
    • 标签.事件类型 = function(eve){ var ev = window.event || eve }

2.2事件对象中的属性

  • altKey/shiftKey/ctrlKey
    • 作用:用户在执行事件的时候,有没有同时按住alt shift ctrl键 如果按住了返回值为true,否者为false
  • clientX和clientY
    • 作用:获取鼠标的位置 表示鼠标位置相对于可视窗口左侧和上侧的距离
  • pageX和pageY
    • 作用:获取鼠标位置 表示鼠标位置到页面左侧和上侧的距离
      • pageX = clientX + 卷去的宽度
      • pageY = clientY + 卷去的高度
    • 注意pageX和pageY存在IE低版本兼容问题 可以通过其他方式获取
      • document.body.scrollLeft + clientX
      • document.body.scrollTop + clientY
  • target(标准浏览器)/srcElement(IE低版本)
    • 作用:表示添加事件中实际触发的元素

2.3事件对象的相关练习

2.3.1元素跟随鼠标移动
2.3.2卡屏效果
<body>
    <script>
        document.documentElement.onmousemove = function(eve){
            var ev = window.event || eve
            // 每次移动都会生成一个div标签
            var oDiv = document.createElement("div");
            // 设置div标签的定位位置  
            oDiv.style.left = ev.clientX + "px";
            oDiv.style.top = ev.clientY + "px";
            // 设置背景色  背景色的范围是0-255
            var r = Math.floor( Math.random()*(255-0+1)+0 )
            var g = Math.floor( Math.random()*(255-0+1)+0 )
            var b = Math.floor( Math.random()*(255-0+1)+0 )
            oDiv.style.backgroundColor = "rgb("+r+","+g+","+b+")"
            document.body.appendChild(oDiv);
        }
    </script>
</body>

2.4事件绑定和封装

事件绑定有两种方式

2.4.1普通方式绑定
  • 标签.事件类型 = function(){ //要做的事 }

  • 缺点:不能给同一个标签添加多次同事件类型

     // 1.普通方式绑定
            // 第一个人的逻辑
            btn.onclick = function(){
                console.log("第一次按钮")
            }
            // 第二个人的逻辑
            btn.onclick = function(){
                console.log("第二次按钮")
            }
            btn.onmouseover = function(){
                console.log("移入按钮")
            }
    
2.4.2事件绑定
  • 标准浏览器的事件绑定
    • 标签.addEventListener(事件类型(不加on),事件处理函数,是否捕获(默认值是false))
      // addEventListener  基础用法
        btn.addEventListener("click",function(){
            console.log("第一次按钮");
        })
        btn.addEventListener("click",function(){
            console.log("第二次按钮")
        })

        // 将函数提出来
        function btn1(){
            console.log("第一次按钮");
        }
        btn.addEventListener("click",btn1)

        function btn2(){
            console.log("第二次按钮")
        }
        btn.addEventListener("click",btn2)
  • IE低版本浏览器
    • 标签.attachEvent(事件类型(加on),事件处理函数)
       // 2.IE低版本浏览器
        var  add = document.getElementsByTagName("button")[1];
        add.attachEvent("onclick",function(){
            console.log("ie低版本浏览器第一次执行")
        })
        add.attachEvent("onclick",function(){
            console.log("ie低版本第二次执行")
        })
2.4.3两者绑定有什么区别
  • addeventListener 和attachEvent有什么区别
    • addeventListener 事件类型不需要加on 执行顺序是正序 从上到下 有事件捕获
    • attachEvent 事件类型需要加on 执行顺序是倒叙 从后往前执行 没有事件捕获、
2.4.4 事件绑定浏览器兼容
 // 4.方法兼容   如果是两个方法的兼容 判断某个方法是否为true
        function fun1(){
            console.log("这是兼容")
        }
        var add1 = document.getElementsByTagName("button")[2];
        if(add1.addEventListener){ //标准浏览器
            // 标签.addEventListener(事件类型,事件处理函数)
            add1.addEventListener("click",fun1)
        }else{ // IE低版本浏览器
            // 标签.attachEvent(事件类型,事件处理函数)
            add1.attachEvent("onclick",fun1)
        }
2.4.5事件绑定函数封装
 // 事件绑定函数封装
        function bind(elem,type,fun) {
            if (elem.addEventListener) { //标准浏览器
                elem.addEventListener(type, fun);  //标准浏览器绑定
            } else { // IE低版本
                elem.attachEvent("on"+type, fun);// iE低版本
            }
        }

2.5事件取消(解绑)和封装

2.5.1普通事件解绑
  • 添加事件:标签.事件类型 = function(){}
  • 取消事件:标签.事件类型 = null
  • 说明:其实就是重新给事件对象赋值 后者覆盖前者 就重新赋值null
2.5.2事件解绑
  • 标准浏览器解绑

    • 绑定方式是addEventListner

      • 解绑方法:元素.removeEventListener(要解绑的事件类型,要解绑的事件处理函数,是否捕获)
      btn2.removeEventListener("click",fun1)
      
  • IE低版本浏览器解绑

    • 绑定方式是attachEvent

      • 解绑方法:元素.detachEVent(要解绑的事件类型(加on),要解绑的事件处理函数)
       btn2.detachEvent("onclick",fun1)
      
2.5.3事件解绑浏览器兼容
  // 兼容  判断某个方法是否存在  xxxx
            if(btn2.removeEventListener){ //标准浏览器的解绑
                btn2.removeEventListener("click",fun1)
            }else{ //IE低版本的解绑
                btn2.detachEvent("onclick",fun1)
            }
2.5.4 事件解绑函数封装
function unbind(elem,type,fun) {
    if (elem.removeEventListener) { //标准浏览器
        elem.removeEventListener(type, fun)
    } else { // IE低版本浏览器
        elem.detachEvent("on" + type, fun)
    }
}

2.6DOM事件流

2.6.1什么是事件流
  • 事件流:当事件发生的时候 事件在父子节点之间固定的传递顺序
  • 事件流包含两种事件机制
    • 捕获型事件
      • 第一步:捕获阶段:当事件发生的时候,事件从window(全局)开始往子元素传递
      • 第二步:确定目标:确定鼠标的事件源
    • 冒泡性事件
      • 事件源收到事件后开始处理事件 处理完成后,会依次往父元素查找事件,如果找到就执行,直到找到window(全局)
<body>
    <div class="box1">box1
        <div class="box2">box2
            <div class="box3">box3</div>
        </div>
    </div>
    <script>
        var oBox  = document.getElementsByTagName("div");
        function fun1(){
            console.log(this.className)
        }
        // addEventListener 第三个参数是是否捕获  默认是false(不捕获就是冒泡)  true捕获
        oBox[0].addEventListener("click",fun1,false);
        oBox[1].addEventListener("click",fun1,false);
        oBox[2].addEventListener("click",fun1,false);
				//如果是捕获 输出结果是box1 box2 box3
				//如果是冒泡 输出结果是box3 box2 box1
    </script>
</body>
2.6.2阻止事件冒泡
  • 标准浏览器:ev.stopPropagation()
  • IE浏览器:ev.cancelBubble = true
  • 兼容:ev.stopPropagation ? ev.stopPropagation() : ev.cancelBubble = true
2.6.3阻止默认行为
  • 普通方式绑定事件阻止默认行为 return false即可
  • 事件绑定方式阻止默认行为
    • 标准浏览器:ev.preventDefault();
    • IE低版本浏览器:ev.returnValue = false;
    • 兼容:ev.preventDefault ? ev.preventDefault() : ev.returnValue = false;

2.7事件代理

  • 事件代理的引用场景
    • 我们需要给大量标签添加事件的时候,为了节省性能,我们一般会使用事件代理(事件委托)
    • 假设一种场景:我们现在需要给10000个li添加点击事件,点击li输入对应的文本内容,如果按照之间的写法 需要循环10000次,会影响页面性能 浪费计算机性能
    • 解决方法:采用事件代理
      • 第一步:给所有要添加事件的元素的共同父元素添加事件
      • 第二步:在父元素事件执行的时候 判断事件源的节点名称是不是li 如果是li就执行内容
<script>
        // for(var i = 0;i<10000;i++){ //同步执行  在这里执行10000次需要花费很长的事件
        //     li[i].onclick = function(){
        //         // 输出对应的文本内容
        //     }
        // }
        // 1.事件代理
        // 给父元素添加点击事件
        var list = document.getElementsByTagName("ul")[0]
        // 给父元素添加事件
        list.onclick = function(eve){
            var ev = window.event || eve;//兼容事件对象
            // 当事件发生的时候去找事件目标(事件源)
            var target = ev.target || ev.srcElement //兼容事件目标
            // 判断元素节点是不是li
            if(target.nodeName == "LI"){
                // 执行逻辑
                target.style.backgroundColor = "teal";
            }
        }
    </script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值