js学习笔记8(事件高级和案例)

<!-- 事件高级 -->

    <!-- 注册事件   : 有两种注册事件的方式(传统方式和方法监听注册方式) -->

    <!-- 传统注册方式:引用on开头的事件 比如onclick  ;  特点:注册事件的唯一性  同一个元素同一个事件只能设置一个函数,最后注册的 处理函数会覆盖前面注册的处理函数-->

    <!-- 方法监听注册方式(移动端使用较多): w3c标准 推荐方式  ;  addEventListener()他是一个方法  ;  ie9之前的ie不支持此方法,可以使用attahEvent()代替    ;   特点:同一个元素同一个事件可以注册多个监听器(监听处理函数)  按注册顺序依次执行-->

    <!-- <button>传统注册事件</button>

    <button>方法监听注册事件</button>

    <button>ie9之前的ie</button>

    <script>

        //传统注册事件  无兼容问题

        var btn = document.querySelectorAll('button');

        btn[0].onclick = function(){

            alert(11);

        }

        //事件监听注册事件

        btn[1].addEventListener('click',function(){   //里面的事件类型是字符串,必须加引号,且没有on

            alert(22);

        })

        btn[1].addEventListener('click',function(){   //同一个事件可以添加多个侦听器,顺序执行

            alert(33);

        })

        //attachEvent 事件监听方式(一般不使用)  ie9之前的ie才能支持

        btn[2].attachEvent('onclick',function(){

            alert(44);

        })

        //所有兼容:注册事件兼容性解决方案(了解)

    </script> -->

    <!-- 删除事件(解绑事件) -->

    <!-- <div>1</div>

    <div>2</div>

    <div>3</div>

    <script>    

        var divs = document.querySelectorAll('div');

        divs[0].onclick = function(){

            alert(11);

            divs[0].onclick = null;   //传统方式   :  eventTarget.onclick = null

        }

        divs[1].addEventListener('click',fn);    //如果要考虑后面会删除函数的话,就要把处理函数写在外面  fn在这里不需要加小括号

        function fn(){

            alert(22);

            divs[1].removeEventListener('click',fn);   //方法监听注册方式  :  eventTarget.removeEventListener(type,listener[,useCapture]);

        }

        divs[2].attachEvent('onclick',fn1);

        function fn1(){

            alert(33);

            divs[2].detachEvent('onclick',fn1);   //detachEvent('',)方法

        }

        //删除事件也有兼容性方案

       

    </script> -->


 

    <!-- DOM事件流 -->

    <!-- 事件流:从页面接受事件的顺序 -->

    <!-- DOM事件流:事件发生时会在元素节点之间按照一定的顺序传播,这个传播过程就叫DOM事件流 -->

    <!-- DOM事件流分为3个阶段 : 1.捕获阶段(最顶层传到当前事件 上往下)  2.当前目标阶段   3.冒泡阶段(从当前传到最顶层 从下往上) -->

     <!-- <div class="father">

        <div class="son">son盒子</div>

    </div>

    <script>

        //dom事件流三个阶段

        //1.JS代码中只能执行捕获或者冒泡的其中一个阶段

        //2.onclick 和 attachEvent(ie) 只能得到冒泡阶段

        var son = document.querySelector('.son');

        son.addEventListener('click',function(){  

            alert('son');

        },true);   //如果 addEventListener 的第三个参数为 true 则表示处于捕获阶段

        var father = document.querySelector('.father');

        father.addEventListener('click',function(){  

            alert('father');

        },true);   //捕获阶段 document -> html  -> body -> father -> son    由于处于捕获阶段,所以此处虽然father的事件写在后面,但是执行的时候是先执行father

        //冒泡阶段(实际开发中常关注)  有些事件没有冒泡,比如 onblur,onfocus,onmouseenter,onmouseleave   事件冒泡有时会带来麻烦,但有时也会帮助很巧妙的某些事件,后面再了解

        var father = document.querySelector('.father');

        father.addEventListener('click',function(){  

            alert('father');     //如果 addEventListener 的第三个参数为 false 或者 省略 则表示处于冒泡阶段

        });

        var son = document.querySelector('.son');

        son.addEventListener('click',function(){  

            alert('son');

        },false);      //冒泡阶段  son -> father  -> body -> html ->document    由于处于冒泡阶段,所以此处先执行son

        document.addEventListener('click',function(){

            alert('document');

        });  //最后弹出document

    </script>   -->


 

    <!-- 重点!!⭐事件对象 -->

    <!-- <div>123</div>

<script>

    var div=document.querySelector('div');

    div.onclick = function(event){

        console.log(event);     //event就是一个事件对象,它写在函数小括号里 ,可以当形参来看,只是它是系统自动创建,不需要我们自己传参,  它包含了事件的一系列相关信息,比如此处的event包含了鼠标点击的坐标等  且只有事件存在时才会有事件对象存在

    }

    div.addEventListener('click',function(e){}); //事件对象可以自己命名,一般取名为 e 、evt   事件对象也有兼容性问题 在ie678里 只认识window.event这个事件对象写法  

    //但有兼容性写法 e = e || window.event 意思是事件对象可能是e,也可能是window.event

    div.onclick = function(e){

        e=e ||window.event;

        console.log(e);   //这样每个浏览器就都可以识别了

    }

</script>


 

 常见事件对象的属性和方法

<div>123</div>

<ul>

    <li>12</li>

    <li>12</li>

    <li>12</li>

</ul>

<a href="http://www.baidu.com">百度</a>

<input type="submit" value="提交">

<script>

    //1.e.target(标准) 返回触发事件的元素   ie678不支持,只支持e.srcElement(非标准)

    /* var div = document.querySelector('div');

    div.addEventListener('click',function(e){

        console.log(e.target);  //返回div

    })

    //2.e.target 与 this 的区别

    var ul =document.querySelector('ul');

    ul.addEventListener('click',function(e){

        console.log(this);   //返回ul (返回绑定事件的元素 , 此处为 ul)

        console.log(e.target);  //返回li (返回触发事件的元素,此处为 li ,因为鼠标点击的是 li )

    })

    //了解(currentTarget 与 this 属性相似 ie678不支持) */


 

    //返回事件类型 type

   /*  var div = document.querySelector('div');

    div.addEventListener('click',function(e){

    console.log(e.type);    //返回click

    })

    div.addEventListener('mouseover',function(e){

        console.log(e.type);  //mouseover

    })

 */

    //阻止默认行为(事件)  阻止链接跳转 或者不让按钮提交(比如想在它跳转之前做一些事或者满足某些条件才跳转)

   /*  var a=document.querySelector('a');

    a.addEventListener('click',function(e){

        e.preventDefault();   //DOM标准写法

    })

    a.onclick = function(e){

        e.preventDefault();  //普通浏览器写法

        e.returnValue;  //低版本写法 这是一个属性 ie678

        //我们也可以利用 return false 这个没有兼容性问题

        return false;   //特点:遇到 return 后,之后的代码就不执行了  

        alert(11);   //这个就不会执行了

    } */


 

    //阻止冒泡  !!重点!面试常考 ⭐

    //标准写法: stopPropagation();   停止传播   也有兼容性问题    // ie678 :e.cancleBubble=true;(非标准)

    var son = document.querySelector('.son');

        son.addEventListener('click',function(e){  

            alert('son');

            e.stopPropagation();     //不再弹出 father了

        },false);

        var father = document.querySelector('.father');

        father.addEventListener('click',function(){  

            alert('father');   //father没有设置阻止冒泡,点击它之后document依然会弹出来

        },false);

        document.addEventListener('click',function(){

            alert('document');

        });

</script> -->

<!-- 事件委托(代理、委派) -->

<!-- 事件委托的原理(!重点!面试常问⭐):  不是每个子节点单独设置监听器,而是把事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点 -->

<!-- 比如:ul里有许多小li 我们给ul注册点击事件。然后利用事件对象的 target 来找到当前点击的li ,因为点击li,事件会冒泡到ul上,ul有注册事件,就会触发事件监听器 -->

<!-- 事件委托的作用  : 我们只操作了一次DOM,提高了程序的性能 -->

<ul>

    <li>知否知否,应是绿肥红瘦</li>

    <li>知否知否,应是绿肥红瘦</li>

    <li>知否知否,应是绿肥红瘦</li>

    <li>知否知否,应是绿肥红瘦</li>

    <li>知否知否,应是绿肥红瘦</li>

</ul>

我是一段不愿意分享的文字

<script>

   /*  var ul = document.querySelector('ul');

    ul.addEventListener('click',function(e){

        alert('知否!');   //只点击每个li 也可以弹出

        e.target.style.backgroundColor='pink'; //利用target可以定位当前操作对象是谁,改变当前对象的背景颜色

    })

    //常用鼠标事件

    //1.禁用鼠标右键菜单    contextmenu 主要控制应该何时显示上下文菜单,主要用于程序员取消默认的上下文菜单

    document.addEventListener('contextmenu',function(e){

        e.preventDefault();

    })

    //2.禁止鼠标选中(selectstart开始选中)  

    document.addEventListener('selectstart',function(e){  

        e.preventDefault();    //不能选中文字了

    }) */


 

    //鼠标事件对象   MouseEvent

    //1.clientX clientY 是相当于可视区域的  即使页面很长,点击的坐标依然只相对于可视化区域(也就是浏览器窗口可视区上框和左框)

    /* document.addEventListener('click',function(e){

        console.log(e.clientX);

        console.log(e.clientY);

        console.log('______');

    })

    //2.page(更常用) 鼠标在页面文档的x和y坐标  ie9以上支持  

    document.addEventListener('click',function(e){

        console.log(e.pageX);

        console.log(e.pageY);

    }) */


 

    //键盘事件

    //常用键盘事件: onkeyup 某个按键被松开时触发   ;   onkeydown 某个键盘按键被按下时触发  ;  onkeypress 某个键盘按键被按下时触发

    //1.onkeyup 某个按键被松开时触发

    /* document.onkeyup = function(){

        console.log('我弹起了');

    } */

  /*   document.addEventListener('keyup',function(){

        console.log('我弹起了');

    })

    //2.onkeydown 某个键盘按键被按下时触发

    document.addEventListener('keydown',function(){

        console.log('我按下了down');

    })

    //3.onkeypress 某个键盘按键被按下时触发   他不会识别功能键,比如 ctrl shift 左右箭头等等

    document.addEventListener('keypress',function(){

        console.log('我按下了press');

    })                                      //4.三个顺序:keydown -  keypress - keyup */


 

    //键盘事件对象

    document.addEventListener('keyup',function(e){

        console.log('up:' + e.keyCode);  //keyCode属性可以得到事件的按下的具体哪个键对应的ASCII码  可以判断用户按下哪个键

        if(e.keyCode === 65){

            alert('你按下了a键');

        }else{

            alert('你么有按下a键');

        }

    })        //注意:!keyup  和 keydown 事件是不区分大小写的  比如按下a和A返回的都是 65

    //如果要区分大小写,可以用keypress

    document.addEventListener('keypress',function(e){

        console.log('press:' + e.keyCode);  //a得到97 A得到65

    })

</script>

案例:

    <!-- 案例:天使图片跟随着鼠标的移动而移动 -->

    <!-- 分析:1.鼠标不断地移动,使用鼠标移动事件:mouseove      2.在页面中移动,给document添加移动事件      3.图片要移动距离,而且不占位置,使用绝对定位       4.核心原理:每次鼠标移动,我们都会获取最新的鼠标坐标,把这个x和y坐标作为图片的top和left值就可以移动图片 -->

       img{

            position: absolute;

            top: 2px;

        }

    </style>

</head>

<body>

    <img src="image/angel.gif" alt="">

    <script>

        var pic = document.querySelector('img');

        document.addEventListener('mousemove',function(e){

            //只要鼠标移动就会触发这个事件

            var x = e.pageX;

            var y = e.pageY;

            // console.log(x,y);

            //把坐标给图片

            pic.style.left=x  - 50 + 'px';  //千万别忘了加单位,否则没有效果

            pic.style.top=y  -40 + 'px';

        })

    </script>

    <!-- 案例:模拟京东按键按下内容(避免每次用鼠标去点搜索框麻烦,设置了只要输入 s 键就可以自定定位到搜索框里) -->

    <!-- 核心思路:检测用户是否按下 s 键 ,如果按下了s 键,就把光标定位到搜索框里 ;

         使用keyCode判断用户按下的键  ;  搜索框获得焦点:使用js里的 focus()方法 -->

         <input type="text">

         <script>

            var search = document.querySelector('input');

            document.addEventListener('keyup',function(e){   //在这里使用 keydown的话会把按下的内容一起输入到输入框中,为避免这种情况,这里最好使用 keyup ,这样在按键弹起时才触发,就不会把内容显示进去了

                if(e.keyCode === 83){

                    search.focus();  //这个方法就是获得焦点的意思

                }

            })

         </script>

    <!-- 案例:模拟京东快递单号查询 -->

    <!-- 要求:当我们在文本框输入内容时,文本框上面自动显示大字号的内容 -->

    <!-- 分析:1.快递单号输入内容时,上面的大号字体盒子(con)显示(这里面的字号更大)     2.表单检测用户输入:给表单添加键盘事件    3.同时把快递单号里面的值(value)获取过来赋值给con盒子(innerHTML)作为内容    4.如果快递单号里面的内容为空,则隐藏大号字体(con)盒子-->

  <style>

        *{

            padding: 0;

            margin: 0;

        }

        .search{

            width: 200px;

            height: 200px;

            margin: 100px auto;

            position: relative;

            outline: none;

        }

        .jd{

            outline: none;

        }

        .con{

            width: 170px;

            line-height: 20px;

            font-size: 18px;

            color: #333;

            border: 1px solid rgba(0, 0, 0, 0.2);

            box-shadow: 0 2px 4px rgb(0, 0, 0,0.2);

            padding: 5px 0;

            position: absolute;

            top: -40px;

            display: none;

        }

        .con::before{ /* 小三角样式 */

            content: '';

            width: 0;

            height: 0;

            position: absolute;

            top: 30px;

            left: 20px;

            border: 8px solid rgb(0, 0, 0);

            border-style: solid dashed dashed;

            border-color: #fff transparent transparent;

        }

    </style>

</head>

<body>

 

    <div class="search">

        <div class="con">123

        </div>

        <input type="text" placeholder="请输入您的快递单号" class="jd">

    </div>

    <script>

        var con = document.querySelector('.con');

        var jd = document.querySelector('.jd');

        jd.addEventListener('keyup',function(){    //在此处不用 keydown和keypress是因为,按键按下的一瞬间就触发事件了,此时文本还未输入文本框就已经执行事件了,所以结果会少一个数字的显示

            // console.log('输入内容');

            if (this.value == ''){

            con.style.display = 'none';  //当内容为空时,把上面的盒子隐藏起来

            }else{

            con.style.display = 'block';

            con.innerHTML = this.value;

            }

            jd.addEventListener('blur',function(){   // 当文本框失去焦点时con盒子隐藏起来

                con.style.display = 'none';

            })

            jd.addEventListener('focus',function(){   //当文本框获得焦点时,且有内容时,就显示 con 盒子

                if (this.value !== ''){

                    con.style.display ='block';

                }

            })

        })

    </script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值