JS事件

event事件對象

在觸發(fā)DOM上某個事件時,會產(chǎn)生一個事件對象event,這個對象包含著所有事件相 關(guān)的信息,包含導致事件的元素,事件的類型以及其他的與特定事件相關(guān)的信息。
它是事件處理函數(shù)的第一個(隱藏)的參數(shù),可以通過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屬性,它是一個數(shù)字
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:鼠標相對于可視區(qū)的位置。
pageX,pageY:鼠標相對于文檔的位置
offsetX,offsetY:鼠標相對于操作元素(鼠標點擊元素)到盒子邊緣(左上)的位置.
screenX,screenY:鼠標相對于顯示屏的位置.

            document.onmousedown=function(ev){
            var ev=ev||window.event;
            console.log('可視區(qū)的位置X:'+ev.clientX);
            console.log('可視區(qū)的位置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(按下+彈起=點擊)

每一個鍵盤字母都對應(yīng)自己的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與回車 才執(zhí)行
                    alert(1)
                }
                if(ev.keyCode==13&& ev.altKey){ //摁下alt  與回車 才執(zhí)行
                    alert(2)
                }
            }

先按組合鍵測試哦

js事件流

事件流描述的是從頁面中接收事件的順序,事件可以分為冒泡事件與非冒泡事件

事件的冒泡
IE 的事件流叫做事件冒泡,即事件開始時由最具體的元素(文檔中嵌套層次最深的那個節(jié)點)接收,然后逐級向上傳播到較為不具體的節(jié)點(文檔) 。
取消冒泡:具體元素對象(冒泡元素)的事件不會冒泡到父級(外層)。
非標準(ie8及以下): ev.cancelBubble=true;
標準:ev.stopPropagation();

注意的點是,冒泡的順序,逐級向上傳播到較為不具體的節(jié)點,寫個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

如果我點擊綠圈,紅色就不觸發(fā),綠色的父級逐漸觸發(fā),這個就是事件的冒泡,平時我們點擊元素的時候相當于也點擊了body,document,只是我們沒有給父元素設(shè)置事件而已

冒泡的應(yīng)用
    <!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讓其隱藏,所以點擊按鈕無法顯示,關(guān)閉冒泡之后就可以顯示元素了,我們平時寫事件的時候需要注意一下

阻止默認事件

瀏覽器有許多默認事件,比如瀏覽器的右鍵出現(xiàn)一組選項框,比如我們表單元素中的submit的默認提交事件以及reset的重置事件,還有a標簽的跳轉(zhuǎn)事件,很多

                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是單線程語言,如果我們在不取消其默認事件的前提下,給右鍵點擊增加一個事件,彈窗來一個,會先出彈窗再顯示選項框,由此可見自定義事件優(yōu)先于默認事件,基于這個原理我們在自定義事件后方返回函數(shù)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>

可復制 瀏覽一下

其他事件也可以由此出發(fā),取消其默認行為

        <body>
            <a  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(){//多個事件就會出現(xiàn)覆蓋。
            alert(456);
        } 
        //document.onclick=null //取消事件                    
               
        </script>

上面的js很明顯,只彈出456,同元素同事件會覆蓋,很容易理解,那如果我們要點擊出現(xiàn)兩個事件怎么辦呢

DOM事件綁定:一個元素上面綁定多個事件。

        基本格式
        元素對象.addEventListener(事件類型,函數(shù),是否捕獲);標準瀏覽器
        事件類型:不能添加on,click/mouseover...
        函數(shù):普通函數(shù)名稱或者函數(shù)體。
        是否捕獲:false:冒泡(默認)   true:捕獲

第三個參數(shù),是否捕獲冒泡先不介紹,先無視

        IE事件綁定和DOM事件綁定(標準瀏覽器)的區(qū)別

        ie瀏覽器:attachEvent(事件類型,函數(shù));
        事件類型:添加on   onclick
        函數(shù):普通函數(shù)名稱或者函數(shù)體。
        1.參數(shù)不一樣  
        2.執(zhí)行順序不一樣
        3.事件類型不一樣 
        4.this指向不一樣

第三個參數(shù)默認為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() 移除事件綁定的參數(shù)和添加事件綁定是一致的。后面是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>

依舊是之前三個圓,注意上方的最后一個參數(shù)是true,之前說過DOM事件的綁定第三個參數(shù)是個布爾值,我這里封裝了一下方法,多了一個元素參數(shù),此時我們點哪個都是最后一個才彈

比如我們點最小的紅圈,先彈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

事件流的順序:捕獲---目標---冒泡,多套幾個圈 多測幾次就可以更深入理解了

事件委托的應(yīng)用
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title></title>
        </head>
        <body>
            <input type="text" id="text" /><input type="button" value="發(fā)布" 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);
                
                
                //事件委托的應(yīng)用
                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,從外面找里面找到元素,如果我們在寫邏輯的時候發(fā)現(xiàn)這個元素很難找的時候,就可以使用這種方法

拖拽效果

這個效果其實在別的文章中寫過,簡易的再寫一次,多敲一遍總是好的

    <!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  根據(jù)冒泡原理應(yīng)該很好理解了吧
                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里面,如果寫外面就執(zhí)行一次,之后將無法取消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  根據(jù)冒泡原理應(yīng)該很好理解了吧
                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>

這個邏輯應(yīng)該不難

然鵝有些元素是不允許拖拽的,比如img,其實使用return false就可以,我們試著封裝一個函數(shù)

    <!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>

這個代碼就不解釋了,看不懂多看幾遍 主要是判斷的地方

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Dom事件 事件是一種異步編程的實現(xiàn)方式,本質(zhì)上是程序各個組成部分之間的通信。DOM支持大量的事件 (一) Eve...
    woow_wu7閱讀 1,802評論 0 1
  • 事件處理客戶端js程序采用異步事件驅(qū)動編程模型。在這種情況下當文檔,瀏覽器,元素發(fā)生一些事情的時候,會產(chǎn)生事件。 ...
    小小小8021閱讀 465評論 0 0
  • ??JavaScript 與 HTML 之間的交互是通過事件實現(xiàn)的。 ??事件,就是文檔或瀏覽器窗口中發(fā)生的一些特...
    霜天曉閱讀 3,528評論 1 11
  • 事件 JavaScript和HTML的交互是通過事件實現(xiàn)的。JavaScript采用異步事件驅(qū)動編程模型,當文檔、...
    bpup閱讀 658評論 0 1
  • 今天學校舉行了陽光體育大課間活動,我好開心呀!看著一個個同學拿著跳繩在操場上排隊的樣子,我非常地興奮。 ...
    小依涵閱讀 568評論 1 1