前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >前端day16-JS(WebApi)学习笔记(事件补充、事件冒泡与捕获)

前端day16-JS(WebApi)学习笔记(事件补充、事件冒泡与捕获)

原创
作者头像
帅的一麻皮
修改2020-05-06 17:58:14
1.7K0
修改2020-05-06 17:58:14
举报
文章被收录于专栏:前端与Java学习前端与Java学习

01-拖拽事件

1.1-h5新增拖拽

注意点:

  • 设置draggable="true"即可实现元素拖拽
  • img标签的draggable默认值就是true,无需设置
代码语言:javascript
复制
<div id="box" draggable="true"></div>
<!-- img标签默认的draggable就是true,可以不用设置 -->
<img src="./images/mn.jpg" alt="" >

1.2-拖拽事件

  • 1.ondragstart :拖拽开始​
  • 2.ondrag :拖拽中(不断触发)​
  • 3.ondragend :拖拽结束
代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        #box {
            width: 100px;
            height: 100px;
            background-color: #f00;
            position: absolute;
        }
    </style>
</head>

<body>
    <!--注意点:一定要给元素加上draggable=true,拖拽事件才能生效-->
    <div id="box" draggable="true"></div>

    <script>
        var box = document.getElementById('box');
        //1.拖拽开始
        box.ondragstart = function () {
            console.log('鼠标按下并第一次移动,开始拖拽');

        };
        //鼠标按下:求出蓝线距离 = 红线 - 绿线
        var x = 0;
        var y = 0;
        box.onmousedown = function (e) {
            x = e.pageX - box.offsetLeft;
            y = e.pageY - box.offsetTop;
        }
        //2.正在拖拽
        box.ondrag = function (e) {
            console.log(e.pageX, e.pageY);
            console.log('拖拽中');
        };
        //3.拖拽结束
        box.ondragend = function (e) {
            console.log('鼠标松开,拖拽结束');
            box.style.left = e.pageX - x + "px";
            box.style.top = e.pageY - y + "px";
        }
    </script>
</body>
</html>

1.3-容器盒子事件

跟容器相关的拖拽事件

  • ondragenter:有元素被 拖拽到 元素范围内就触发
  • ondragleave:有元素被 拖离 元素范围内就触发
  • ondragover:鼠标移动时,元素在我的范围内就会触发(非常频繁)
  • ondrop: 鼠标松开时,元素还在我的范围内就会触发

* 注意点:这个事件默认不会触发,需要配合ondragover使用

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>

    <style>
        .box{
            width: 100px;
            height: 100px;
            background-color: #f00;
        }
        .container{
            width: 400px;
            height: 550px;
            border: 1px solid #000;
            position: absolute;
            right:20px;
            top:20px;
        }
    </style>
</head>
<body>
    <div class="box" draggable="true"></div>
    <div class="container"></div>

    <script>
        //找到box
        var box = document.querySelector('.box');
        //找container
        var container = document.querySelector('.container');
        //1.ondragenter
        container.ondragenter = function(){
            console.log('有元素被拖拽进来了');
        };
        //2.ondragleave
        container.ondragleave = function(){
            console.log('元素离开了');
        };
        //3.ondragover
        //由于这个事件触发非常的频繁,影响性能。所以需要阻止默认事件
        container.ondragover = function(e){
            e.preventDefault();
            // console.log('鼠标移动时,元素在我的范围内');
        };
        //4.ondrop
        //这个事件默认不会触发,需要配合ondragover使用
        // 给容器盒子注册ondragover事件,然后阻止这个事件的默认行为 e.preventDefault()
        container.ondrop = function(){
            console.log('鼠标松开时,元素还在我的范围内');
        };
    </script>
</body>
</html>

1.4-键盘事件及获取键盘按键

1.键盘事件

onkeydown:键盘按下触发

onkeyup:键盘弹起触发

onkeypress:键盘按下并弹起会触发

onkeydown和onkeypress的区别:了解即可

  • 1.onkeypress可以过滤掉特殊的功能键例如删除、F1-F12,shift,alt键等等,onkeydown不会过滤
  • 2.onkeypress可以区分大小写,但是onkeydown永远都是大写(不管大小写状态)
  1. 如何获取你到底按的是哪个键?

* 通过事件对象获取 语法: 事件对象.keyCode

* 获取到的是键盘对应字符的ascii码

* ascii码转字符:String.fromCharCode(code)

3.有三个属性都可以获取到按下的键

keyCode(IE8及之前),charCode,which

所以为了保证一定能获取到,就做兼容

var code = e.keyCode || e.charCode || e.which;

02-注册/移除多个同名事件

如何给一个元素添加多个相同事件?

代码语言:javascript
复制
        var btn = document.getElementById ( "btn" )
        //用这样的方式添加相同的事件,后面的会覆盖前面的
        btn.onclick = function () {
            alert("点一次200块");
        }
        btn.onclick = function () {
            alert("点我干啥?");
        }

addEventListener绑定多个同名事件

代码语言:javascript
复制
    //语法:对象.addEventListener(参数1,参数2,参数3);
    //参数1:事件名(字符串),不要加on  例如:click  、 mouseover 、mouseout
    //参数2:事件处理程序(函数名),当事件触发后哪个函数来处理
    //参数3:是一个bool类型,可以不传,默认为fasle(代表冒泡)跟冒泡和捕获有关
    //如果有同名事件不会覆盖,而是会依次执行
    //IE8及以前的版本不支持
    btn.addEventListener ( "click", function ( e ) {
        e = e || window.event
        alert ( "嘿嘿嘿" )
        console.log ( e )
    }, false )
    btn.addEventListener ( "click", function () {
        alert ( "哈哈哈" )
    } )
    //如果传入已经存在的函数,那么直接写函数名,千万不要写小括号
    btn.addEventListener ( "click", sayHi, false )
    function sayHi ( e ) {
        e = e || window.event
        alert ( "你来追我呀!" )
        console.log ( e )
    }

removeEventListener移除事件

代码语言:javascript
复制
    //1.on+事件名称的方式
    // btn.onclick = function () {
    //   alert("哈哈");
    //   btn.onclick = null; //移除事件。
    // }
    
    //2.元素名.addEventListener注册的事件,移除方式
    //元素名.removeEventListener(参数1,参数2,参数3);
    //参数1:事件名称
    //参数2:事件处理程序
    //参数3:布尔类型的值
      function test() {
        alert("哈哈");
      }
      btn.addEventListener("click", test,false);
      btn.removeEventListener("click",test,false)

03-事件冒泡

事件冒泡:如果一个元素的事件被触发,那么他的所有父级元素的同名事件也会被依次触发

  • 元素->父元素->body->html->document->window
    • 事件冒泡一直存在,只不过以前我们没有给父级元素加同名事件
代码语言:javascript
复制
<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        #box{
            width: 300px;
            height: 300px;
            background-color: hotpink;
            position: relative;
        }
        #son{
            width: 100px;
            height: 100px;
            position: absolute;

            left: 350px;
            top: 350px;

            background-color: yellowgreen;
        }
    </style>
</head>
<body>
<div id="box">
    <input type="button" value="点我" id="btn"/>
    <div id="son"></div>
</div>
</body>
</html>
<script>
    window.onclick = function () {
        alert("window被点击了");
    }
    document.onclick = function () {
        alert("文档被点击了");
    }
    document.documentElement.onclick = function () {
        alert("html被点击了");
    }
    document.body.onclick = function () {
        alert("body被点击了");
    }
    document.getElementById("box").onclick = function () {
        alert("我是骚粉的大盒子");
    };
    document.getElementById("btn").onclick = function () {
        alert("我是小按钮");
    };
    document.getElementById("son").onclick = function () {
        alert("我是又黄又绿的小盒子");
    };
</script>

如何阻止事件冒泡?

  • 阻止事件冒泡:让同名事件不要在父元素中冒泡(触发) * 说人话:点击一个元素只会触发当前元素的事件,不会触发父元素的同名事件
  • 语法: 事件对象.stopPropagation() IE8及之前不支持
  • 事件对象.cancelBubble = true IE8之前支持
  • 注意:如果想要阻止事件冒泡,一定要在触发事件的函数中接收事件对象
代码语言:javascript
复制
<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        #box{
            width: 300px;
            height: 300px;
            background-color: hotpink;
            position: relative;
        }
        #son{
            width: 100px;
            height: 100px;
            position: absolute;

            left: 350px;
            top: 350px;

            background-color: yellowgreen;
        }
    </style>
</head>
<body>
<div id="box">
    <input type="button" value="点我" id="btn"/>
    <div id="son"></div>
</div>
</body>
</html>
<script>
    window.onclick = function () {
        alert("window被点击了");
    }
    document.onclick = function () {
        alert("文档被点击了");
    }
    document.documentElement.onclick = function () {
        alert("html被点击了");
    }
    document.body.onclick = function () {
        alert("body被点击了");
    }
    document.getElementById("box").onclick = function (e) {
        e = e || window.event;
        alert("我是骚粉的大盒子");
        // e.stopPropagation();
        //e.cancelBubble = true;//IE8及之前
        stopPropagation(e);//兼容性封装函数
        //阻止事件冒泡的这行代码可以写在这个事件函数的任意位置,一般习惯写在最后面
    };
    document.getElementById("btn").onclick = function () {
        alert("我是小按钮");
    };
    document.getElementById("son").onclick = function () {
        alert("我是又黄又绿的小盒子");
    };
    /**  阻止事件冒泡兼容性封装
    * @param e:事件对象
    * @return 无
    */
    function stopPropagation( e) {
        e = e || window.event;
        if(e.stopPropagation){
            e.stopPropagation();
        }else{
            e.cancelBubble = true;
        }
    }
</script>

04-事件捕获

  • 1.事件冒泡:从触发事件元素,一级一级往上找父元素触发同名事件,如果有就触发
  • 2.事件捕获:从最顶级的父元素一级一级往下找子元素触发同名事件,直到触发事件的元素为止
    • 事件捕获与事件冒泡触发事件的顺序完全相反
  • 3.事件捕获,只能通过addEventListener并且参数写true才是事件捕获
    • 其他都是冒泡(不是通过addEventListener添加、addEventListener参数为false)
  • 4.事件对象.stopPropagation() 除了可以阻止冒泡还可以阻止捕获
  • 5.IE8及以前没有捕获!

这里就省略代码了

事件三个阶段

  • 1.事件一共有三个阶段:事件的执行顺序
    • 1--捕获阶段 :
    • 2--目标阶段 :
    • 3--冒泡阶段 :
  • 2.事件对象.eventPhase 可以获得触发这个事件时,到底是哪个阶段
  • 3.先从最顶级往下一级一级捕获,然后到目标的捕获,目标的冒泡,再一级一级往上冒泡
代码语言:javascript
复制
<div class="one" id="box">
    <input type="button" value="按钮" id="btn"/>
    <div class="son" id="son"></div>
</div>
<script>
    var box = document.getElementById("box");
    var btn = document.getElementById("btn");
    var son = document.getElementById("son");
    document.addEventListener("click",function (e) {
        alert("document"+ e.eventPhase);
    },true) ;//true表示事件捕获,所以是阶段1,并且优先执行
    
    document.body.addEventListener("click", function (e) {
        alert("哈哈,我是body"+ e.eventPhase);
    },false);
    
    box.addEventListener("click",function (e) {
        alert("哈哈哈,我是粉色的盒子box..."+ e.eventPhase);
    },false);
    
    btn.addEventListener("click",function (e) {
        alert("哈哈哈,我是按钮btn..."+ e.eventPhase);
    },false);
    
    son.addEventListener("click",function (e) {
        alert("嘻嘻嘻,我是绿色的盒子son"+ e.eventPhase);

    },false);

</script>

事件类型e.type和事件源e.target

代码语言:javascript
复制
<input type="button" value="按钮" id="btn"/>
<script>
    var btn = document.getElementById('btn');
    btn.onclick = f1;
    btn.onmouseover = f1;

    function f1(e){
        //如果是点击触发的,那么就是click,如果是鼠标移入触发的就是mouseover
        console.log(e.type);
    }

</script>

事件冒泡好处:如果想给父元素的多个子元素添加事件,我们可以只需要给父元素添加事件即可,然后

通过获取事件源(e.target)就可以得知是哪一个子元素触发了这个事件

代码语言:javascript
复制
<ul id="ul1">
    <li>隔壁老王1</li>
    <li>隔壁老王2</li>
    <li>隔壁老王3</li>
    <li>隔壁老王4</li>
    <li>隔壁老王5</li>
</ul>
<script>
    var ul = document.getElementById("ul1");

    //1.如果想给ul中的每一个li标签添加点击事件,以前的做法需要遍历ul的li标签逐个添加
    //    for (var i = 0; i < ul.children.length; i++) {
    //
    //        ul.children[i].onclick = function () {
    //
    //            alert(this.innerHTML);
    //        }
    //    }
    //2.使用时间冒泡:只需要给父元素添加点击事件即可
    ul.onclick = function (e) {
        e = e || window.event;
        var target = e.target || e.srcElement;

        console.log(target.innerHTML);

        //target:事件源:触发本次事件的源头
        alert(e.target.innerHTML);
    }
</script>

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 01-拖拽事件
    • 1.1-h5新增拖拽
      • 1.2-拖拽事件
        • 1.3-容器盒子事件
          • 1.4-键盘事件及获取键盘按键
          • 02-注册/移除多个同名事件
          • 03-事件冒泡
          • 04-事件捕获
            • 事件三个阶段
              • 事件类型e.type和事件源e.target
              相关产品与服务
              容器服务
              腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档