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

2020-05-06 17:58:14 浏览数 (1)

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>

0 人点赞