最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 事件-PC 与 mobile phone

    正文概述 掘金(fhsWar)   2021-01-11   449

    事件

    • 注意点: 事件方法都是没有驼峰的
    • ==移动端和 PC 端各自有特有的事件==
    • css 的 pointerevents: none; 能使对应选择器选到的 dom 不响应不拦截事件 css 的 pointerevents: none; 能使对应选择器选到的 dom 不响应不拦截事件

    移入, 移出, 移动 (移动端没有移入移出事件)

    • .onmouseover .onmouseenter
    • .onmouseout .onmouseleave
    • .onmousemove
    • 淦!居然没驼峰
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>13-JavaScript-移入移出事件</title>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            div{
                width: 300px;
                height: 300px;
                background: red;
            }
        </style>
    </head>
    <body>
    <div></div>
    <script>
        let oDiv = document.querySelector("div");
        // 1.移入事件
        // oDiv.onmouseover = function () {
        //     console.log("移入事件");
        // }
        // 注意点: 对于初学者来说, 为了避免未知的一些BUG, 建议使用onmouseenter
        oDiv.onmouseenter = function () {
            console.log("移入事件");
        }
    
        // 2.移出事件
        // oDiv.onmouseout = function () {
        //     console.log("移出事件");
        // }
        // 注意点: 对于初学者来说, 为了避免未知的一些BUG, 建议使用onmouseleave
        oDiv.onmouseleave = function () {
            console.log("移出事件");
        }
        3.移动事件
        oDiv.onmousemove = function () {
            console.log("移动事件");
        }
    </script>
    </body>
    </html>
    

    表单焦点事件

    • .onfocus
    • .onblur
    • .onchange (只在失焦后才能拿到修改后的数据)
    • .oninput (实时获取到修改后的数据)
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>17-JavaScript-焦点事件</title>
    </head>
    <body>
    <input type="text">
    <script>
        let oInput = document.querySelector("input");
        // 1.监听input获取焦点
        oInput.onfocus = function () {
            console.log("获取到了焦点");
        }
        // 2.监听input失去焦点
        oInput.onblur = function () {
            console.log("失去了焦点");
        }
        // 3.监听input内容改变
        // 注意点: onchange事件只有表单失去焦点的时候, 才能拿到修改之后的数据
        oInput.onchange = function () {
            console.log(this.value);
        }
        // oninput事件可以时时获取到用户修改之后的数据, 只要用户修改了数据就会调用(执行)
        // 注意点: oninput事件只有在IE9以上的浏览器才能使用
        // 在IE9以下, 如果想时时的获取到用户修改之后的数据, 可以通过onpropertychange事件来实现
        oInput.oninput = function () {
            console.log(this.value);
        }
    </script>
    </body>
    </html>
    

    添加事件的三种方式

    1. element.onxxx
    2. element.attachEvent (上古, 了解即可)
    3. element.addEventListener (现代,可选事件冒泡 or 捕获)

    方法一:onxxx

    注意点:

    1. 由于是给属性赋值, 所以后赋值的会覆盖先赋值
    2. 缺点很明显: 不能通过一个事件触发多个方法, 不利于维持方法的细粒度
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>onclick</title>
    </head>
    <body>
    <button id="btn">我是按钮</button>
    <script>
        // 这点击事件只会输出 777, 原理就是给对象属性重赋值会对原有的值进行覆盖
        var oBtn = document.getElementById("btn");
    
        oBtn.onclick = function () {
            alert("666");
        }
        oBtn.onclick = function () {
            alert("777");
        }
    </script>
    </body>
    </html>
    

    方法二:attachEvent

    注意点:

    1. 事件名称必须加上on
    2. 后添加的不会覆盖先添加的
    3. 只支持低版本的浏览器
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>attachEvent</title>
    </head>
    <body>
    <button id="btn">我是按钮</button>
    <script>
        // 既输出 666 也输出 777,但现代浏览器已经摒弃了这个方法
        var oBtn = document.getElementById("btn");
    
        oBtn.attachEvent("onclick", function () {
            alert("666");
        });
        oBtn.attachEvent("onclick", function () {
            alert("777");
        });
    </script>
    </body>
    </html>
    

    方法三:addEventListen

    注意点:

    1. 事件名称不需要添加 on
    2. 后添加的不会覆盖先添加的
    3. 只支持现代浏览器(其实完全足够了)
    4. 这是三个里唯一可自定义事件是冒泡行为还是捕获行为的方法
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>addEventListener</title>
    </head>
    <body>
    <button id="btn">我是按钮</button>
    <script>
        // 既输出 666 也输出 777,现代浏览器通用这个方法
        var oBtn = document.getElementById("btn");
    
        oBtn.addEventListener("click", function () {
            alert("666");
        });
        oBtn.addEventListener("click", function () {
            alert("777");
        });
    
    </script>
    </body>
    </html>
    

    强行兼容

    看似考虑周全,实则没有必要

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>加个判断</title>
    </head>
    <body>
    <button id="btn">我是按钮</button>
    <script>
        var oBtn = document.getElementById("btn");
    
        function addEvent(ele, name, fn) {
            if(ele.attachEvent){
                ele.attachEvent("on"+name, fn);
            }else{
                ele.addEventListener(name, fn);
            }
        }
    </script>
    </body>
    </html>
    

    事件对象

    • 事件对象就是一个系统自动创建的一个对象
    • 当注册的事件被触发的时候, 系统就会自动创建事件对象
    • 事件对象的属性海了去了

    注意点

    1. 在高级版本的浏览器中, 会自动将事件对象传递给回到函数
    2. 在低级版本的浏览器中, 不会自动将事件对象传递给回调函数, 需要通过 window.event 来获取事件对象

    关于阻止默认行为

    1. event.preventDefault(); 只支持现代浏览器
    2. event.returnValue = false; 只支持上古浏览器(了解即可, 这年头谁还用 IE8 啊)
    3. return false; 通吃
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>事件对象</title>
    </head>
    <body>
    <button id="btn">我是按钮</button>
    <a href="http://www.baidu.com">百度首页</a>
    <script>
       var oBtn = document.getElementById("btn");
       oBtn.onclick = function (event) {
           // 兼容性的写法
           event = event || window.event;
           // alert("666");
           console.log(event);
           console.log(typeof event);
       }
    
       let oA = document.querySelector("a");
        oA.onclick = function (event) {
            // 兼容性的写法
            event = event || window.event;
    
            alert("666");
            // 阻止默认行为
            return false; // 企业开发推荐
    
            // event.preventDefault(); // 高级浏览器
            // event.returnValue = false; // IE9以下浏览器
        }
    </script>
    </body>
    </html>
    

    事件执行的三个阶段

    三个阶段

    1. 捕获阶段(从外向内的传递事件)
    2. 当前目标阶段
    3. 冒泡的阶段(从内向外的传递事件)

    注意点:

    • 三个阶段只有两个会被同时执行
    • 要么捕获和当前, 要么当前和冒泡

    冒泡还是捕获

    如何设置事件到底是捕获还是冒泡?

    通过addEventListener方法, 这个方法接收三个参数

    • 第一个参数: 事件的名称
    • 第二个参数: 回调函数
    • 第三个参数: ==false 冒泡== / ==true 捕获==

    注意点

    • onXxx的属性, 不接收任何参数, 所以默认就是冒泡
    • attachEvent方法, 只能接收两个参数, 所以默认就是冒泡
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>41-JavaScript-事件执行的三个阶段</title>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            .father{
                width: 300px;
                height: 300px;
                background: red;
            }
            .son{
                width: 150px;
                height: 150px;
                background: blue;
            }
        </style>
    </head>
    <body>
    <div class="father">
        <div class="son"></div>
    </div>
    <script>
        let oFDiv = document.querySelector(".father");
        let oSDiv = document.querySelector(".son");
        oFDiv.addEventListener("click", function () {
            console.log("father");
        }, false);
        oSDiv.addEventListener("click", function () {
            console.log("son");
        }, false);
    </script>
    </body>
    </html>
    
    <!--
    默认就是 false,也就是冒泡
    设置为 true 的元素及其子元素链条都变为捕获,且仅影响自身及其子代,不影响其父元素
    -->
    

    关于冒泡的细节

    IE6.0: div -> body -> html -> document

    其他浏览器: div -> body -> html -> document -> window

    注意: 不是所有的事件都能冒泡,有些事件不冒泡,如 blur、 focus、 load、 unload 等

    阻止事件冒泡 (强行兼容)

    首先要明确:阻止的前提是有事件,阻止事件冒泡的操作是写在实践方法的回调函数里的

    1. event.cancelBubble = true; (上古)
    2. event.stopProgagation(); (现代,知道这个才要紧)
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>43-JavaScript-阻止事件冒泡</title>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            .father{
                width: 300px;
                height: 300px;
                background: red;
            }
            .son{
                width: 150px;
                height: 150px;
                background: blue;
            }
        </style>
    </head>
    <body>
    <div class="father" id="father">
        <div class="son" id="son"></div>
    </div>
    <script>
        // 1.拿到需要操作的元素
        var oFDiv = document.getElementById("father");
        var oSDiv = document.getElementById("son");
        
        // 2.注册事件监听
        oFDiv.onclick = function () {
            console.log("father");
        }
        oSDiv.onclick = function (event) {
            event = event || window.event;
            // event.stopPropagation(); // 高级浏览器
            // event.cancelBubble = true; // 低级浏览器
            if(event.cancelBubble){
                event.cancelBubble = true;
            }else{
                event.stopPropagation();
            }
            console.log("son");
        }
    </script>
    </body>
    </html>
    

    不同移入移出事件辨析

    区别在于是否触发冒泡(或捕获)

    1. onmouseover 和 onmouseenter 的区别
      • onmouseover 移入到子元素,父元素的移入事件也会被触发
      • onmouseenter 移入到子元素,父元素的移入事件不会被触发
    2. onmouseout 和 onmouseleave 的区别
      • onmouseout 移出到子元素,父元素的移入事件也会被触发
      • onmouseleave 移出到子元素,父元素的移入事件不会被触发
    3. 简单来说, enter 和 leave 比较干净不拖泥带水
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>44-JavaScript-移入移出事件区别</title>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            .father{
                width: 300px;
                height: 300px;
                background: red;
            }
            .son{
                width: 150px;
                height: 150px;
                background: blue;
            }
        </style>
    </head>
    <body>
    <div class="father">
        <div class="son"></div>
    </div>
    <script>
        let oFDiv = document.querySelector(".father");
        let oSDiv = document.querySelector(".son");
        /*
        oFDiv.onmouseover = function () {
            console.log("father");
        }
        oSDiv.onmouseover = function () {
            console.log("son");
        }
         */
        /*
        oFDiv.onmouseenter = function () {
            console.log("father");
        }
        oSDiv.onmouseenter = function () {
            console.log("son");
        }
         */
        oFDiv.onmouseleave = function () {
            console.log("father");
        }
        oSDiv.onmouseleave = function () {
            console.log("son");
        }
    </script>
    </body>
    </html>
    

    通过事件获取元素位置

    • offsetX/offsetY: 事件触发点相对于当前元素自身以左上为原点的位置
    • clientX/clientY: 事件触发相对于浏览器可视区域的位置(上古浏览器不支持)
    • 注意点:
      • 显示器区域不包括滚动出去的部分(这个开发中用的少)
    • screenX/screenY: 事件触发相对于屏幕的位置
    • 整个网页包括滚动出去的部分 pageX/pageY: 事件触发相对于整个网页的位置(在页面不滚动时拿到的值和 clientX/clientY 是一样的)

    细节们

    • 调用事件方法时 return false 可以禁用默认事件, 或者用 event.preventDefault() 也行

    • 如果想获取 query 到的 input 标签对象中输入的内容, 只能通过其 value 属性

      html 可以给标签设置自定义标签属性, 可以给 JS 用,

      甚至可以通过 JS 给指定 DOM 添加自定义属性标签

    • 在 JS 中如果 HTML 标签的属性名称和取值名称一样的时候, JS 会返回 true/false 但如果是通过代码给 input 设置的数据, 那么不会触发 oninput 事件

    • 对上古浏览器的兼容只需了解即可

    移动端事件

    移动端特有事件对象

    1. Touch事件对象
      • 移动端的touch事件也是一个事件, 所以被触发的时候系统也会自动传递一个事件对象给我们
    2. 移动端touch事件对象中比较重要的三个子对象
      1. touches: 当前屏幕上所有手指的列表
      2. targetTouches: 保存了当前元素上所有的手指里列表 (这个用的多)
      3. changedTouches: 当前屏幕上刚刚接触的手指或者离开的手指

    移动端点透问题

    1. 移动端点透问题
      • 当一个元素放覆盖了另一个元素, 覆盖的元素监听 ==touch== 事件,而下面的元素监听 ==click== 事件
      • 并且touch事件触发后覆盖的元素就消失了, 那么就会出现点透问题
    2. 移动端点透问题出现的原因
      1. 当手指触摸到屏幕的时候,系统生成两个事件,一个是touch 一个是click
      2. touch 事件先执行,执行完后从文档上消失
      3. click 事件有 100~300ms 延迟, 所以后执行. (理由不对嗷, 我加了 content="scalable=no" 也还能点透)
      4. 但 click 事件执行的时候触发的元素已经消失了, 对应的位置现在是下面的元素, 所以就触发了下面元素的 click 事件
    3. 移动端点透问题解决方案 在touch事件中添加event.preverDefault(); 阻止事件扩散
    <!DOCTYPE html>
    <html lang="en">
    	<head>
    		<meta charset="UTF-8" />
    		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
    		<title>10-移动端点透问题</title>
    		<style>
    			* {
    				margin: 0;
    				padding: 0;
    			}
    			div {
    				text-align: center;
    				font-size: 40px;
    			}
    			.click {
    				width: 300px;
    				height: 300px;
    				background: red;
    				position: absolute;
    				left: 50%;
    				transform: translateX(-50%);
    				top: 100px;
    			}
    			.tap {
    				width: 200px;
    				height: 200px;
    				background: blue;
    				position: absolute;
    				left: 50%;
    				transform: translateX(-50%);
    				top: 150px;
    			}
    		</style>
    	</head>
    	<body>
    		<div class="click">click</div>
    		<div class="tap">tap</div>
            <!-- 两元素在同级, 但展现时两个块块有重叠 -->
    		<script>
    			let oClick = document.querySelector(".click");
    			let oTap = document.querySelector(".tap");
    
    			oTap.ontouchstart = function (event) {
    				this.style.display = "none";
    				event.preventDefault(); //  阻止事件扩散
    			};
    			oClick.onclick = function () {
    				console.log("click");
    			};
    		</script>
    	</body>
    </html>
    

    起源地下载网 » 事件-PC 与 mobile phone

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元