JS事件

作者: 感觉不错哦 | 来源:发表于2018-12-13 16:12 被阅读128次

event事件对象

在触发DOM上某个事件时,会产生一个事件对象event,这个对象包含着所有事件相 关的信息,包含导致事件的元素,事件的类型以及其他的与特定事件相关的信息。
它是事件处理函数的第一个(隐藏)的参数,可以通过arguments[0]来获取。

    <!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>
    </head>
    <body> 
         <button id="btn">GET</button>
    </body>
    <script>
              btn.onclick=function(){
                  console.log(arguments[0])
              }
    </script>
    </html>

此时会打印出一系列的鼠标事件

              btn.onclick=function(event){
                  var event = event || window.event
                  console.log(event)
              }

效果等同上方,IE下取事件是在window下的,此处是个兼容

event.button

如果当前event是鼠标事件,则会有一个button属性,它是一个数字
0代表鼠标按下了左键 1代表按下了滚轮 || 2代表按下了右键(不介绍低版本IE)

    <script>
            document.onmousedown=function(ev){
            var ev=ev||window.event;
            alert(ev.button);//012 
        }
    </script>

在页面中点击即可,作为了解一下

鼠标事件中获取鼠标的位置属性介绍(clientX、pageX、offsetX、screenX)

clientX,clientY:鼠标相对于可视区的位置。
pageX,pageY:鼠标相对于文档的位置
offsetX,offsetY:鼠标相对于操作元素(鼠标点击元素)到盒子边缘(左上)的位置.
screenX,screenY:鼠标相对于显示屏的位置.

            document.onmousedown=function(ev){
            var ev=ev||window.event;
            console.log('可视区的位置X:'+ev.clientX);
            console.log('可视区的位置Y:'+ev.clientY);
            console.log('文档的位置X:'+ev.pageX);
            console.log('文档的位置Y:'+ev.pageY);
            console.log('对于操作元素的位置X:'+ev.offsetX);
            console.log('对于操作元素的位置Y:'+ev.offsetY);
            console.log('显示屏的位置X:'+ev.screenX);
            console.log('显示屏的位置Y:'+ev.screenY);
        }

这个还是得自己多测试加强记忆,写个小demo

        <!DOCTYPE html>
        <html>
            <head>
                <meta charset="UTF-8">
                <title></title>
                <style>
                    .box{
                        width: 100px;
                        height: 100px;
                        background: red;
                        position: absolute;
                        cursor: move;
                    }
                </style>
            </head>
            <body>
                <div class="box"></div>
                <script type="text/javascript">
                    var oBox=document.querySelector('.box');
                    document.onmousemove=function(ev){
                        var ev=ev||window.event;
                        oBox.style.cssText='left:'+(ev.clientX-oBox.offsetWidth/2)+'px;top:'+(ev.clientY-oBox.offsetHeight/2)+'px;';
                    }
                </script>
            </body>
        </html>

自行复制浏览一下即可

键盘事件

onkeydown + onkeyup =onpress(按下+弹起=点击)

每一个键盘字母都对应自己的keyCode码,可以测试一下

            document.onkeydown=function(ev){
              var ev=ev||window.event;
              alert(ev.keyCode);//获取键码
            }

写个小demo,控制盒子移动(w,s,a,d)

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title></title>
            <style type="text/css">
                div{
                    width: 200px;
                    height: 200px;background: red;
                    position: absolute;
                    left:400px;top:100px;
                }
            </style>
        </head>
        <body>
            <div></div>
            <script type="text/javascript">
                var oDiv=document.querySelector('div');
                document.onkeydown=function(ev){
                    var ev=ev||window.event;
                    if(ev.keyCode==87){
                        oDiv.style.top=oDiv.offsetTop-10+'px';
                    }else if(ev.keyCode==83){
                        oDiv.style.top=oDiv.offsetTop+10+'px';
                    }else if(ev.keyCode==65){
                        oDiv.style.left=oDiv.offsetLeft-10+'px';
                    }else if(ev.keyCode==68){
                        oDiv.style.left=oDiv.offsetLeft+10+'px';
                    }
                }
            </script>
        </body>
    </html>
组合键

ctrlKey、altKey、shiftKey

            document.onkeydown=function(ev){
                var ev=ev||window.event
                if(ev.keyCode==13&& ev.ctrlKey){ //摁下ctrl与回车 才执行
                    alert(1)
                }
                if(ev.keyCode==13&& ev.altKey){ //摁下alt  与回车 才执行
                    alert(2)
                }
            }

先按组合键测试哦

js事件流

事件流描述的是从页面中接收事件的顺序,事件可以分为冒泡事件与非冒泡事件

事件的冒泡
IE 的事件流叫做事件冒泡,即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档) 。
取消冒泡:具体元素对象(冒泡元素)的事件不会冒泡到父级(外层)。
非标准(ie8及以下): ev.cancelBubble=true;
标准:ev.stopPropagation();

注意的点是,冒泡的顺序,逐级向上传播到较为不具体的节点,写个demo可测试

    <!DOCTYPE html>
    <html id="html1">
        <head>
            <meta charset="UTF-8">
            <title></title>
            <style type="text/css">
                #small{
                    width: 200px;
                    height:200px;
                    border-radius: 50%;
                    background: red;
                }
                #middle{
                    width: 200px;
                    height:200px;
                    border-radius: 50%;
                    background: green;
                    padding: 100px;
                }
                
                #big{
                    width: 400px;
                    height:400px;
                    border-radius: 50%;
                    background: blue;
                    padding: 100px;
                    margin:0 auto;
                }
            </style>
            
        </head>
        <body id="body1">
            <div id="big">
                <div id="middle">
                    <div id="small"></div>
                </div>
            </div>
            <script type="text/javascript">
                //事件流:从页面中接收事件的顺序
                var small=document.querySelector('#small');
                var middle=document.querySelector('#middle');
                var big=document.querySelector('#big');
                function fn(){
                    alert(this.id);
                }
                
                small.onclick=fn;
                middle.onclick=fn;
                big.onclick=fn;
                document.body.onclick=fn;
                document.documentElement.onclick=fn;
            </script>
        </body>
    </html>

一共五个事件,如果我点击红圈,也就是先弹small,然后逐级向上释放,接着谈绿色middle,蓝色big,然后是body,最后是html

如果我点击绿圈,红色就不触发,绿色的父级逐渐触发,这个就是事件的冒泡,平时我们点击元素的时候相当于也点击了body,document,只是我们没有给父元素设置事件而已

冒泡的应用
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title></title>
        </head>
        <body>
            <button>显示</button>
            <div style="width: 150px;height: 250px;background: red;display: none;"></div>
            <script type="text/javascript">
                var oBtn=document.querySelector('button');
                var oDiv=document.querySelector('div');
                oBtn.onclick=function(ev){
                    var ev=ev||window.event;
                    oDiv.style.display='block';
                    //ev.stopPropagation();//标准浏览器取消冒泡
                }
                
                document.onclick=function(){
                    oDiv.style.display='none';
                }
            </script>
        </body>
    </html>

我这里没有取消冒泡,在点击按钮的时候,事件会冒泡到document让其隐藏,所以点击按钮无法显示,关闭冒泡之后就可以显示元素了,我们平时写事件的时候需要注意一下

阻止默认事件

浏览器有许多默认事件,比如浏览器的右键出现一组选项框,比如我们表单元素中的submit的默认提交事件以及reset的重置事件,还有a标签的跳转事件,很多

                document.oncontextmenu=function(ev){ //右键事件

                    return false
                   
                }

取消默认事件很简单,使用return false
ev.preventDefault(); 标准浏览器阻止默认事件,DOM事件使用此方法取消默认事件。
ev.returnValue = false; 非标准浏览器(IE8)阻止默认事件

                document.oncontextmenu=function(ev){ //右键事件
                    alert(1)
                    ev.preventDefault()
                   // return false
                }

因为JS是单线程语言,如果我们在不取消其默认事件的前提下,给右键点击增加一个事件,弹窗来一个,会先出弹窗再显示选项框,由此可见自定义事件优先于默认事件,基于这个原理我们在自定义事件后方返回函数false不让其往下运行即可

        <!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 type="text/css">
                .box{
                    width: 200px;
                    height: 300px;
                    background: red;
                    position: absolute;
                    display: none;
                }
            </style>
        </head>
        <body>
            <div class="box"></div>
        </body>
        <script>
                var oBox=document.querySelector('.box');
                document.oncontextmenu=function(ev){ //右键事件
                    var ev=ev||window.event;
                    oBox.style.display='block';
                    oBox.style.left=ev.clientX+'px';
                    oBox.style.top=ev.clientY+'px';
                    return false
                }
                document.onclick=function(){
                    oBox.style.display='none';
                }
        </script>
        </html>

可复制 浏览一下

其他事件也可以由此出发,取消其默认行为

        <body>
            <a href="http://www.baidu.com" onclick="return false">百度</a>
            <form action="http://www.baidu.com">
                <input type="submit" onclick="return false" />
            </form>
        </body>

DOM2级事件

        <script>
            
        document.onclick=function(){//一个元素上面绑定一个事件
            alert(123);
        }
        document.onclick=function(){//多个事件就会出现覆盖。
            alert(456);
        } 
        //document.onclick=null //取消事件                    
               
        </script>

上面的js很明显,只弹出456,同元素同事件会覆盖,很容易理解,那如果我们要点击出现两个事件怎么办呢

DOM事件绑定:一个元素上面绑定多个事件。

        基本格式
        元素对象.addEventListener(事件类型,函数,是否捕获);标准浏览器
        事件类型:不能添加on,click/mouseover...
        函数:普通函数名称或者函数体。
        是否捕获:false:冒泡(默认)   true:捕获

第三个参数,是否捕获冒泡先不介绍,先无视

        IE事件绑定和DOM事件绑定(标准浏览器)的区别

        ie浏览器:attachEvent(事件类型,函数);
        事件类型:添加on   onclick
        函数:普通函数名称或者函数体。
        1.参数不一样  
        2.执行顺序不一样
        3.事件类型不一样 
        4.this指向不一样

第三个参数默认为false冒泡

        <script>
            
            function a(){
            alert('a');
            }
            function b(){
                alert('b');
            }
            function c(){
                alert('c');
            }
        document.addEventListener('click',a);  //没有on
        document.addEventListener('click',b); 
        document.addEventListener('click',c);
        /*document.attachEvent('onclick',a);  IE事件 可无视 很烦
        document.attachEvent('onclick',b);
        document.attachEvent('onclick',c);*/
        </script>

此时点击document 顺序弹出abc

removeEventListener()/detachEvent() 移除事件绑定的参数和添加事件绑定是一致的。后面是IE移除

document.removeEventListener('click',a) 此时就不弹a了

简易事件封装
        function addEvent(obj,event,fn){
            if(obj.addEventListener){//判断条件采用属性判断,如果存在属性就不是IE
                obj.addEventListener(event,fn,false);
            }else{
                obj.attachEvent('on'+event,fn);
            }
        }
        //事件移除的封装
        function removeEvent(obj,event,fn){
            if(obj.removeEventListener){
                obj.removeEventListener(event,fn,false);
            }else{
                obj.detachEvent('on'+event,fn);
            }
        }
        addEvent(document,'click',a);
        addEvent(document,'click',b);//绑定
        removeEvent(document,'click',b)//移除
        addEvent(document,'click',c);

事件流的捕获

        <!DOCTYPE html>
        <html id="html1">
            <head>
                <meta charset="UTF-8">
                <title></title>
                <style type="text/css">
                    #small{
                        width: 200px;
                        height:200px;
                        border-radius: 50%;
                        background: red;
                    }
                    #middle{
                        width: 200px;
                        height:200px;
                        border-radius: 50%;
                        background: green;
                        padding: 100px;
                    }
                    
                    #big{
                        width: 400px;
                        height:400px;
                        border-radius: 50%;
                        background: blue;
                        padding: 100px;
                        margin:0 auto;
                    }
                </style>
                
            </head>
            <body id="body1">
                <div id="big">
                    <div id="middle">
                        <div id="small"></div>
                    </div>
                </div>
                <script type="text/javascript">
                    var small=document.querySelector('#small');
                    var middle=document.querySelector('#middle');
                    var big=document.querySelector('#big');
                    function fn(){
                        alert(this.id);
                    }
                    
                    /*small.onclick=fn;
                    middle.onclick=fn;
                    big.onclick=fn;
                    document.body.onclick=fn;
                    document.documentElement.onclick=fn;*/
                    function addEvent(obj,event,fn,bool){
                        if(obj.addEventListener){
                            obj.addEventListener(event,fn,bool);
                        }else{
                            obj.attachEvent('on'+event,fn);
                        }
                    }
                    addEvent(small,'click',fn,true);
                    addEvent(middle,'click',fn,true);
                    addEvent(big,'click',fn,true);
                    addEvent(document.body,'click',fn,true);
                    addEvent(document.documentElement,'click',fn,true);
                </script>
            </body>
        </html>

依旧是之前三个圆,注意上方的最后一个参数是true,之前说过DOM事件的绑定第三个参数是个布尔值,我这里封装了一下方法,多了一个元素参数,此时我们点哪个都是最后一个才弹

比如我们点最小的红圈,先弹html 然后body 然后依次递减,但是我这个布尔值是可以更改的,如果为fasle则是冒泡,我修改其中一两个看看效果

                    addEvent(small,'click',fn,false);//冒泡
                    addEvent(middle,'click',fn,true);//捕获
                    addEvent(big,'click',fn,false);//冒泡
                    addEvent(document.body,'click',fn,true);//捕获
                    addEvent(document.documentElement,'click',fn,false);//冒泡

此时我要点最小的红圈,弹的顺序是

body--middle--small--big--html

如果我点big 篮圈,弹的顺序是

body--big--html

如果我点的是绿圈,弹的顺序是

body--middle--big--html

事件流的顺序:捕获---目标---冒泡,多套几个圈 多测几次就可以更深入理解了

事件委托的应用
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title></title>
        </head>
        <body>
            <input type="text" id="text" /><input type="button" value="发布" id="btn" />
            <ul id="ul1">
                <li>55555555</li>
                <p>pppppppppp</p>
            </ul>
            <script type="text/javascript">
                var oT=document.getElementById('text');
                var oBtn=document.getElementById('btn');
                var oUl=document.getElementById('ul1');
                    
                oBtn.addEventListener('click',function(){
                    var cLi=document.createElement('li');
                    cLi.innerHTML=oT.value;
                    oUl.appendChild(cLi);
                    oT.value='';
                },false);
                
                
                //事件委托的应用
                oUl.onclick=function(ev){
                    var ev=ev||window.event;
                    //target:获取目标元素,点击的元素对象。 
                    var ele=ev.target||ev.srcElement;//获取当前点击目标元素
                    alert(ele.nodeName);//获取当前元素的名称(大写的)
                    if(ele.nodeName=='LI'){//一定要判断当前点击的元素,就是我们需要控制的元素。
                        alert(ele.innerHTML);
                    }
                }
                
            </script>
        </body>
    </html>

注意我点的是UL,从外面找里面找到元素,如果我们在写逻辑的时候发现这个元素很难找的时候,就可以使用这种方法

拖拽效果

这个效果其实在别的文章中写过,简易的再写一次,多敲一遍总是好的

    <!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>
            *{
                margin: 0;
                padding: 0  
            }
        div{
            width: 100px;
            height: 100px;
            background: red;
            position: absolute;
            left: 0;
            top: 0
        }
        </style>
    </head>
    <body>
        <div id="div"></div>
    </body>
    <script>
        div.onmousedown=function(ev){
            var ev=ev||window.event
            //鼠标按下的时候获取短线
            var shortx=ev.offsetX; 
            var shorty=ev.offsetY;
            document.onmousemove=function(ev){  //这里为什么使用document  根据冒泡原理应该很好理解了吧
                var ev=ev||window.event;//在移动的时候重新获取,不断变化,用移动时的鼠标位置。
                div.style.left=ev.clientX-shortx+'px';
                div.style.top=ev.clientY-shorty+'px';
            }

            div.onmouseup=function(){
                    document.onmousemove=null
                    div.onmouseup=null
            }

        }
    </script>
    </html>

最简单的一个拖拽,需要注意的是onmouseup要写在onmousedown里面,如果写外面就执行一次,之后将无法取消move事件,如果我们不想让他超出浏览器,写个判断

    <!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>
            *{
                margin: 0;
                padding: 0  
            }
        div{
            width: 100px;
            height: 100px;
            background: red;
            position: absolute;
            left: 0;
            top: 0
        }
        </style>
    </head>
    <body>
        <div id="div"></div>
    </body>
    <script>
        div.onmousedown=function(ev){
            var ev=ev||window.event
            //鼠标按下的时候获取短线
           var shortx=ev.offsetX; 
           var shorty=ev.offsetY;
            document.onmousemove=function(ev){  //这里为什么使用document  根据冒泡原理应该很好理解了吧
                var ev=ev||window.event;//在移动的时候重新获取,不断变化,用移动时的鼠标位置。
                var l=ev.clientX-shortx;//水平  鼠标的x坐标减去鼠标到div左边的距离就是div的left值
                var t=ev.clientY-shorty;//垂直
                if(l<=0){   
                    l=0;
                }else if(l>=document.documentElement.clientWidth-div.offsetWidth){
                    l=document.documentElement.clientWidth-div.offsetWidth;
                }
                if(t<0){
                    t=0;
                }else if(t>=document.documentElement.clientHeight-div.offsetHeight){
                    t=document.documentElement.clientHeight-div.offsetHeight
                }
                        
                div.style.left=l+'px';
                div.style.top=t+'px';
            }

            div.onmouseup=function(){
                    document.onmousemove=null
                    div.onmouseup=null
            }

        }
    </script>
    </html>

这个逻辑应该不难

然鹅有些元素是不允许拖拽的,比如img,其实使用return false就可以,我们试着封装一个函数

    <!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>
            *{
                margin: 0;
                padding: 0  
            }
        img{
            position: absolute;
            left: 0;
            top: 0
        }
        </style>
    </head>
    <body>
        <img id="img" src="http://img2.imgtn.bdimg.com/it/u=2830140111,3261939339&fm=26&gp=0.jpg" />
    </body>
    <script>
         function drag(el){
            el.onmousedown=function(ev){
            var ev=ev||window.event;
                shortx=ev.offsetX;
                shorty=ev.offsetY;
            document.onmousemove=function(ev){
                    var ev=ev||window.event;//重新获取,不断变化,用移动时的鼠标位置。
                    var l=ev.clientX-shortx;//水平
                    var t=ev.clientY-shorty;//垂直
                    el.style.left=l+'px';
                    el.style.top=t+'px';
            }
            el.onmouseup=function(){
                document.onmousemove=null;
                el.onmouseup=null
            }
            return false
         }
         }

         drag(img)
    </script>
    </html>

这样我们只需要传递元素即可了

碰撞检测
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title></title>
            <style type="text/css">
                .box1{
                    width: 200px;
                    height: 200px;
                    background: red;
                    position: absolute;
                    z-index: 2;
                }
                
                .box2{
                    width: 200px;
                    height: 200px;
                    background: blue;
                    position: absolute;
                    left:800px;
                    top:200px;
                }
            </style>
        </head>
        <body>
            <div class="box1">1</div>
            <div class="box2">2</div>
            <script type="text/javascript">
                var oBox1=document.querySelector('.box1');
                var oBox2=document.querySelector('.box2');
                var shortx=0;
                var shorty=0;
                oBox1.onmousedown=function(ev){
                    //鼠标按下求短线。
                    var ev=ev||window.event;
                    shortx=ev.offsetX;
                    shorty=ev.offsetY;
                    document.onmousemove=function(ev){
                        var ev=ev||window.event;//重新获取,不断变化,用移动时的鼠标位置。
                        var l=ev.clientX-shortx;//水平
                        var t=ev.clientY-shorty;//垂直
                        oBox1.style.left=l+'px';
                        oBox1.style.top=t+'px';

                        
                        if( !((oBox1.offsetLeft+oBox1.offsetWidth)<oBox2.offsetLeft || oBox1.offsetLeft>oBox2.offsetLeft+oBox2.offsetWidth || (oBox1.offsetTop+oBox1.offsetHeight)<oBox2.offsetTop || oBox1.offsetTop>oBox2.offsetTop+oBox2.offsetHeight) ){
                            oBox2.style.background='green';
                        }else{
                            oBox2.style.background='blue';
                        }
                        
                        
                    }
                    document.onmouseup=function(){//松开鼠标,不再移动了
                        document.onmousemove=null;
                        document.onmouseup=null;
                    }
                    return false;//取消默认事件
                }
        
            </script>
        </body>
    </html>

这个代码就不解释了,看不懂多看几遍 主要是判断的地方

相关文章

  • js(事件)

    js 事件js事件.png

  • js操作页面三步骤

    js操作页面三步骤 js事件 鼠标事件 文档事件 键盘事件 表单事件 事件对象 js操作内容 js操作样式 页面转...

  • 事件

    1、鼠标的移入移除js部分 2、鼠标事件js部分 3、事件对象js部分 4、键盘事件js部分 5、输入框事件js部...

  • 20、jQuery 事件机制

    20、jQuery 事件机制 原生js事件与jQuery事件: (1)用原生的js给div注册事件 原生js注册相...

  • javascript 中的事件机制

    js之事件机制 1、事件初探 1.1 js事件的概述 JavaScript事件:JavaScript是基于事件驱动...

  • JavaScript的事件机制详解

    【js事件详解】js事件封装函数,js跨浏览器事件处理机制 一、事件流 事件流描述的是从页面中接受事件的顺序。IE...

  • JS的事件绑定和事件流模型

    一、JS事件 (一)JS事件分类 1.鼠标事件: click/dbclick/mouseover/mouseout...

  • js事件 事件冒泡

    js事件的分类 事件的类型:有鼠标事件,键盘事件,HTML事件,变化事件 注意:js中的事件前面要加on(如:on...

  • JS事件相关基础

    js事件: 键盘事件: JS中的事件冒泡和事件捕获: 1、事件冒泡。如下代码: 点击button事件,连同父元素绑...

  • 2019-01-11 input框事件,jQuery其他事件,自

    js事件的分类事件的类型:有鼠标事件,键盘事件,HTML事件,变化事件注意:js中的事件前面要加on (如:onc...

网友评论

      本文标题:JS事件

      本文链接:https://www.haomeiwen.com/subject/uxdvhqtx.html