1. 程式人生 > 實用技巧 >WebAPI程式設計DOM學習

WebAPI程式設計DOM學習

1.事件高階


1.1 給元素新增事件,稱為註冊事件或者繫結事件
註冊事件有兩種方式:傳統方式方法監聽註冊方式

方法監聽註冊方式

· w3c標準 推薦方式
· addEventListener()它是一個方法
· IE9之前的IE不支援此方法,可使用attachEvent()代替(非標準 不建議使用)
· 特點:同一個元素同一個事件可以註冊多個監聽器

//1.裡面的事件型別是字串 必定加引號 而且不帶on
            //2.同一個元素 同一個事件可以新增多個偵聽器(事件處理程式)
            btn.addEventListener('click',function
(){ alert('HELLO!') })

2.刪除事件

divs[0].onclick = function(){
                alert(11);
                //1.傳統方式刪除事件
                divs[0].onclick = null;
            }
            //2.removeEventListener 刪除事件
            //裡面的fn不需要呼叫加小括號
            divs[1].addEventListener('click',fn);
            
function fn(){ alert(22); divs[1].removeEventListener('click',fn); }

3.DOM事件流

事件流描述的是從頁面中接收事件的順序。
事件發生時會在元素節點之間按照特定的順序傳播,這個傳播過程即DOM事件流。

DOM事件流分為3個階段

1.捕獲階段
2.當前目標階段
3.冒泡階段

注意
① JS程式碼中只能執行捕獲或者冒泡其中的一個階段
②onclick和attachEvent 智慧得到冒泡階段
③addEventListener(type,listener[,useCapture])第三個引數如果是true,表示事件

捕獲階段呼叫事件處理程式;如果是false(不寫預設就是false),表示在事件冒泡階段
呼叫事件處理程式。

捕獲階段

<script type="text/javascript">
            //dom 事件流 三個階段
            //1.JS程式碼中只能執行捕獲或者冒泡其中的一個階段。
            //2.onclick和attachEvent(ie)只能得到冒泡階段。
            //3.捕獲階段 如果addEventListener第三個引數是true那麼則處於捕獲階段 document->html->body->father->son
            var son = document.querySelector('.son');
            son.addEventListener('click',function(){
                alert('son');
            },true);
            var father = document.querySelector('.father');
            father.addEventListener('click',function(){
                alert('father');
            },true);
</script>

冒泡階段

<script type="text/javascript">
            //dom 事件流 三個階段
            //1.JS程式碼中只能執行捕獲或者冒泡其中的一個階段。
            //2.onclick和attachEvent(ie)只能得到冒泡階段。
//4.冒泡階段 如果addEventListener 第三個引數是false或者省略 則處於冒泡階段 son->father->body->html->document
            var son = document.querySelector('.son');
            son.addEventListener('click',function(){
                alert('son');
            },false);
            var father = document.querySelector('.father');
            father.addEventListener('click',function(){
                alert('father');
            },false);
        </script>

事件物件

<script type="text/javascript">
            var div = document.querySelector('div');
            //ie678用傳統方法
            div.onclick = function(e){
                console.log(window.event);
            }
            //不考慮相容用以下
            div.addEventListener('click',function(e){
                console.log(e);
            })
            //1.event 就是一個事件物件 寫到我們偵聽函式的小括號裡面 當形參來看
            //2.事件物件只有有了事件才會存在,它是系統自動建立的,不需要我們傳遞引數
            //3.事件物件是我們事件的一系列相關資料的集合 跟事件相關的 比如滑鼠點選裡面就包含了滑鼠的相關資訊,滑鼠座標等,如果是鍵盤事件裡面就包含鍵盤事件的資訊,比如 判斷使用者按下了哪個鍵
            //4.這個事件物件可以自己命名 比如event、evt、e
            //5.事件物件也有相容性問題 ie678 通過window.event
        </script>

常見事件物件屬性和方法

<script type="text/javascript">
            //常見事件物件的屬性和方法
            //1.e.target 返回的是觸發事件的物件(元素)this返回的是繫結事件的物件(元素)
            //區別:e.target 點選了哪個元素 就返回哪個元素。this哪個元素綁定了這個點選事件,就返回誰
            var div = document.querySelector('div');
            div.addEventListener('click',function(e){
                console.log(e.target);
                console.log(this);
            })
            var ul = document.querySelector('ul');
            ul.addEventListener('click',function(e){
                //給ul綁定了事件 this就指向ul
                console.log(this);
                //e.target 指向我們點選的那個物件 誰觸發了這個事件。點選的是li,e.target指向的就是li
                console.log(e.target);
            })
        </script>

阻止預設行為

<script type="text/javascript">
            //阻止預設行為(事件)讓連結不跳轉 或者讓提交按鈕不提交
            var a = document.querySelector('a');
            a.addEventListener('click',function(e){
                e.preventDefault();//dom 標準寫法
            });
            //傳統方式
            a.onclick = function(e){
                //普通瀏覽器 e.preventDefault()方法
                e.preventDefault();
                //ie678 低版本瀏覽器 returnValue 屬性
                e.returnValue;
                //我們可以利用return false 也能阻止預設行為 沒有相容性問題 特點:return後面的程式碼不執行了 而且只限於傳統的註冊方式
                return false;
            }
        </script>

5.阻止事件冒泡

5.1 阻止事件冒泡的兩種方式
事件冒泡:開始時由最具體的元素接收,然後逐級向上傳播到DOM最頂層節點。

阻止事件冒泡

· 標準寫法:利用事件物件裡面的stopPropagation()方法

e.stopPropagation();

· 非標準寫法:IE6-8利用事件物件cancelBubble屬性.

if(e&&e.stopPropagation()){
    e.stopPropagation();
}else{
    window.event.cancelBubble = true;
}

6. 事件委託(代理、委派)

事件委託的原理
不要每個子節點單獨設定事件監聽器,而是事件監聽器設定在其父節點上,然後利用冒泡 原理影響設定每個子節點。

<ul>
            <li>知否知否應是綠肥紅瘦</li>
            <li>知否知否應是綠肥紅瘦</li>
            <li>知否知否應是綠肥紅瘦</li>
            <li>知否知否應是綠肥紅瘦</li>
            <li>知否知否應是綠肥紅瘦</li>
        </ul>
        <script type="text/javascript">
            //事件委託的核心原理:給父節點新增偵聽器,利用事件冒泡影響每一個子節點
            var ul = document.querySelector('ul');
            ul.addEventListener('click',function(e){
                for(var i = 0; i<ul.children.length;i++){
                ul.children[i].style.backgroundColor = '';
                }
                e.target.style.backgroundColor = 'pink';
                
            })
        </script>

7.常用的滑鼠事件

7.1禁止滑鼠右鍵選單

contextmenu 主要控制應該何時顯示上下文選單,主要用於程式設計師取消預設的上下文選單

document.addEventListener('contextmenu',function(e){
                e.preventDefault();
            })


7.2禁止滑鼠選中(selectstart 開始選中)

document.addEventListener('selectstart',function(e){
                e.preventDefault();
            })

7.3滑鼠事件物件

跟隨滑鼠移動的小天使 案例

<body>
        <img src="img/angel.jpg"/>
        <script type="text/javascript">
            var img = document.querySelector('img');
            document.addEventListener('mousemove',function(e){
                var x = e.pageX;
                var y = e.pageY;
                img.style.top = y-50+'px';
                img.style.left = x - 40 + 'px';
            })
        </script>
    </body>

8.常用鍵盤事件

keyup 和 keydown事件不區分字母大小寫 a 和A 得到的都是65
keypress事件區分字母大小寫 a 97和A得到的是65

document.addEventListener('keyup',function(e){
                console.log('up:'+e.keyCode);
            })
            document.addEventListener('keypress',function(e){
                console.log('press:'+e.keyCode);
            })

模擬京東按鍵S輸入內容

var search = document.querySelector('input');
            document.addEventListener('keyup',function(e){
                if(e.keyCode == 83){
                    search.focus();
                }
            })

京東快遞單號查詢

<head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            .search{
                position: relative;
                margin: 200px;
            }
            .con{
                position: absolute;
                display: none;
                border: 1px solid #ccc;
                box-shadow: 0 2px 4px rgba(0,0,0,.3);
                width: 200px;
                height: 35px;
                line-height: 35px;
                top: -45px;
                left: 0;
            }
            .con::before{
                content: '';
                position: absolute;
                top: 35px;
                left: 20px;
                width: 0;
                height: 0;
                border-top: 8px solid #fff;
                border-left: 8px solid transparent;
                border-right: 8px solid transparent;
                border-bottom: 8px solid transparent;
                
            }
        </style>
    </head>
    <body>
        <div class="search">
            <div class="con">
                123
            </div>
            <input type="text" placeholder="請輸入您的快遞單號" class="jd"/>
        </div>
        <script type="text/javascript">
            var con = document.querySelector('.con');
            var jd = document.querySelector('.jd');
            jd.addEventListener('keyup',function(e){
                if(this.value==''){
                    con.style.display='none';
                }else{
                con.style.display ='block';
                con.innerHTML = this.value;    
                }
            })
        </script>
        
    </body>