05-DOM相關知識點講解

DOM

DOM內容主要分為四部分:

  • 什么是DOM和節點;
  • 獲取節點;
  • 節點操作(3種);
  • 屬性操作(3種)。

什么是DOM和節點

  • DOM由節點組成;
  • DOM是樹狀模型;
  • DOM操作就是節點操作;
  • 每一個HTML標簽都是一個元素節點
  • 標簽中的文字就是文字節點;
  • 標簽的屬性就是屬性節點。

獲取節點:

直接獲?。韩@取元素節點常用的方法主要有三種:通過id、標簽名、類名:
  • 通過id獲?。?code>document.getElementById("box");
  • 返回一個標簽,可以直接使用,獲得屬性值,設置屬性。
  • 通過類名獲取標簽數組:document.getElementsByClassName("a");
  • 通過標簽名獲取標簽數組:document.getElementsByTagName("div");
  • 獲得的標簽數組是一個偽數組
  • 通過標簽名和類名獲取到的標簽數組,一般都是遍歷之后再使用;特殊情況,數組中的值只有一個:
document.getElementsByTagName("div")[0];   //獲取數組中的元素
document.getElementsByClassName("a")[0];   //獲取數組中的元素
  • 通過名字獲取(較少用):document.getElementsByName();
  • 通過tagNameNS獲取(較少用):document.getElementsByTagNameNS();
<div id="box"></div>
<script>
    var div = document.getElementById("box");

    div.onclick = function () {
        alert(1);
    }
</script>
通過訪問關系獲??;
  • 有三種訪問關系:父節點、兄弟節點和子節點;
  • 節點的訪問關系是以屬性形式存在的;
  • 父節點:調用者就是節點,一個節點只有一個父節點,調用方式:調用者.parentNode;;
  • 兄弟節點:sibling
  • nextSibling:IE678中指下一個元素節點(標簽);在火狐谷歌IE9+以后都是指下一個節點(包括空文檔和換行節點);
  • nextElementSibling:在火狐谷歌IE9+都指的是下一個元素節點。
  • 總結:在IE678中用nextSibling,在火狐谷歌IE9+以后用nextElementSibling:下一個兄弟節點=節點.nextElementSibling || 節點.nextSibling;。
  • 獲取前一個兄弟節點:前一個兄弟節點=節點.previousElementSibling || 節點.previousSibling;。
  • 單個子節點:
  • 第一個子節點=父節點.firstElementChild || 父節點.firstChild;;
  • 最后一個子節點 = 父節點.lastElementChild || 父節點.lastChild;;
  • 所有子節點:
  • childNodes:它返回指定元素的子元素集合,包括HTML節點、所有屬性、文本節點(W3C親兒子,標準屬性),子節點數組=父節點.childNodes; 獲取所有節點
nodeType == 1,表示的是元素節點`記住`,元素就是標簽
nodeTyoe == 2,表示的是屬性節點,了解
nodeType == 3,表示的是文本節點,了解
  • children:非標準屬性,它返回的是指定元素的子元素的集合,只返回HTML節點,甚至不返回文本節點,雖然不是標準的DOM屬性,但是它和innerHTML方法一樣,得到了幾乎所有瀏覽器的支持。子節點數組=父節點.children; //用的最多,在IE678中,包含注釋節點,所以在IE678中,不要將注釋節點寫在里面。

  • nodeType、nodeName、nodeValue(了解)

<div id="yijiang" class="jiangjiang" value="jiang">義江</div>
<script>
        var ele = document.getElementById("yijiang");
        var attr1 = ele.getAttributeNode("id");
        var attr2 = ele.getAttributeNode("value");
        var text = ele.firstChild;

        console.log(ele);       //<div id="yijiang" class="jiangjiang" value="jiang">義江</div>
        console.log(attr1);     //id="yijiang"
        console.log(attr2);     //value="jiang"
        console.log(text);      //"義江"

        console.log(ele.nodeType);      //1
        console.log(attr1.nodeType);    //2
        console.log(attr2.nodeType);    //2
        console.log(text.nodeType);     //3

        console.log(ele.nodeValue);      //null
        console.log(attr1.nodeValue);    //yijiang
        console.log(attr2.nodeValue);    //jiang
        console.log(text.nodeValue);     //義江
</script>
  • 補充:
  • 通過這兩個屬性parentNodechildren,可以獲取到任意元素節點:節點.parentNode.children[index];:
function siblings(elm) {
        var a = [];
        var p = elm.parentNode.children;
        for(var i =0;i<p.length;i++) {
            if(p[i] !== elm) a.push(p[i]);
        }
        return a;
}

節點操作(3種)重要:節點的訪問關系都是屬性,而節點的操作都是函數或者方法。

  • 節點的創建:
    • 新的標簽(節點)=document.createElement("標簽名");
  • 添加(插入)節點:
    • 使用方法:父節點.appendChild(新節點);,父節點的最后插入一個新節點;
    • 使用方法:父節點.insertBefore(要插入的節點,參考節點);,在參考節點之前插入,如果參考節點為null,那么他將在節點最后插入一個節點。
  • 刪除:
    • 使用方法:用父節點刪除子節點父節點.removeChild(子節點):必須指定要刪除的子節點;
    • 使用方法:節點自己刪除自己(自殺)node.parentNode.removeChild(node);,不知道父節點的情況下,可以這樣使用。
  • 復制節點:
    • 新節點=要復制的節點.cloneNode(參數);,接受一個Boolean類型參數,true表示深復制(復制節點及其所有子節點),false表示淺復制(值復制節點本身,不復制子節點)。

屬性操作(3種):

  • 獲取:

    • 節點.屬性或者節點[屬性]
    • 節點.getAttribute("屬性")
  • 設置:節點.setAttribute(屬性,值)

  • 刪除:節點.removeAttribute(屬性);

  • 注:

    • IE6、7不支持;
    • 元素節點.屬性(元素節點[屬性]):資料上說該方法綁定的屬性值不會出現在標簽上,但是經測試通過這種方法綁定的屬性如果是標簽原本就有的也會出現在標簽上,如果是用戶自定義的屬性就不會出現在標簽上;
    • get/set/removeAttribute:綁定的屬性值會出現在標簽上,推薦使用;
    • 兩種方式不能相互訪問:賦值和獲取值必須使用同一種方法。
  • 練習:

    • 切換圖片(a連接+圖片);
      • 如果<a href="www.baidu.com">跳轉</a>,點擊a,頁面會進行相應跳轉,在onclick綁定的函數最后加return false;或者如果是行內綁定就在onclick最后加return false;就可阻止相應的跳轉。
    • 顯示和隱藏盒子;
      • 顯示隱藏盒子的同時修改按鈕的文字,使用innerHTML進行按鈕文字的修改。
    • 美女相冊
//2.綁定事件(利用for循環綁定事件)
for(var aIndex in aArr){
        aArr[aIndex].onclick = function () {
            show.src = this.href;
    //warning       des.innerHTML = aArr[aIndex].title;
            des.innerHTML = this.title;
            return false;
        }
}
- 注:綁定描述時,只能通過this獲取title,不能通過aArr[aIndex]獲取,因為綁定事件時候,并沒有立刻執行事件,當用戶點擊時已經無法通過Arr[aIndex]獲取對應標簽。

排它思想

  • 通常和for循環連用,先干掉所有人,然后再單獨處理某一個特殊人。
  • 練習:
    • tab切換;

綁定事件:三種方法

  • 通過匿名函數綁定;
  • 通過函數名綁定(不能加小括號,否則就是綁定返回值了);
  • 行內綁定:<div class="content" onclick="fn()">,一定要加小括號,否則就是字符串了。(經測試發現,行內綁定的方法不能寫在window.onload里面,元素加載時找不到方法)

onload事件

  • 頁面加載完畢(包括文本和圖像)時候調用這個事件:window.onload;

  • 主要用途:

    • js的加載是和html的加載同步進行的。如果使用元素在定義元素之前,容易報錯;
    • 整個頁面上的所有元素加載完畢時再執行js內容;
    • window.onload:可以預防使用標簽在定義標簽之前。
  • 補充:

    • value:標簽的value屬性;
    • innerHTML:獲取雙閉合標簽里面的內容。(識別標簽)
    • innerText:獲取雙閉合標簽里面的內容。(不識別標簽)
    • 老版本的火狐不支持innerText,支持textContent。

DOM對象的屬性

  • 表單元素的屬性

    • type
    • value
    • checked
    • selected
    • disabled
  • DOM對象的屬性練習:

    • 顯示隱藏二維碼;
      • 可以替換字符串(了解):div.class.replace("old","new");;
erweima_s.onmouseover = function () {
        erweima_b.className = "erweima-big show";
    };
erweima_s.onmouseout = function () {
        erweima_b.className = erweima_b.className.replace("show","hide");
    };
  • 點擊按鈕禁用/解禁文本框;
    • inp.removeAttribute("disabled");。
<body>
    <hr>禁用/解禁文本框 <br>
    賬  號:<input value="yijiangwnag" class="account"><button>禁用</button><button>解禁</button>
    <script>
        window.onload = function () {
            var account = document.getElementsByClassName("account")[0];
            var ban = document.getElementsByTagName("button")[0];
            var banCancel = document.getElementsByTagName("button")[1];
            ban.onclick = function () {
//                account.setAttribute("disabled",true);
                account["disabled"] = true;
            };
            banCancel.onclick = function () {
//                account.removeAttribute("disabled");
                account["disabled"] = false;
            };
        }
    </script>
</body>
  • 輸入事件與事件焦點onfocus【淘寶、京東輸入框】(獲取焦點:onfocus,失去焦點:onblur);
    • 京東的input輸入框獲取到焦點時刪除內容,失去焦點時顯示內容;
    • 淘寶的input輸入框在獲取到焦點時沒有變化,輸入內容之后文字消失,當刪除內容之后文字恢復出現:oninput事件:刪除/輸入內容時候調用進入頁面時候直接獲取光標焦點:inp.focus();
<body>
        京東:<input id="jd" value="我是京東"><br>
        淘寶:<input id="tb"><label class="tbLabel">我是淘寶</label><br>
        placeholder:<input placeholder="我是placeholder">
    <script>
        //京東/淘寶輸入框
        var jd = document.getElementById("jd");
        var tb = document.getElementById("tb");
        var tbL = document.getElementsByClassName("tbLabel")[0];
        jd.onfocus = function () {
            if (jd.value == "我是京東"){
                jd.value = "";
            }
        };
        jd.onblur = function () {
            if (jd.value == ""){
                jd.value = "我是京東";
            }
        };
        tb.oninput = function () {
            if (tb.value == ""){    //但是淘寶連續輸空格label不消失的bug日后解決
                tbL.className = "tbLabel show";
            }else {
                tbL.className = "tbLabel hide";
            }
        };
    </script>
</body>
  • 檢測用戶名、密碼是否是6~12位,如果不滿足要求高亮顯示文本框;
    • html中的input標簽行內調用function的時候,是通過window去調用function的;
    • 標簽之后在函數參數里傳遞的this才是指的標簽本身。只做了解,平時使用時盡量不要在行內式中調用函數;
    • html中的input標簽行內調用function的時候,function定義不能寫在window.onload里面,標簽加載時會找不到。
<body>
    賬號:<input id="checkAcc" onblur="fn(this)"> <br>
    密碼:<input id="checkSec" onblur="fn(this)">
    <script>
    //要求用戶名3~6位,密碼在6~8位,如果不正確就高亮顯示(顯示紅色)
    function fn(aaa) {
        console.log(this);
        if (aaa.value.length > 12 || aaa.value.length < 6){
            aaa.className = "wrong";
        }else {
            aaa.className = "right";
        }
    }
    </script>
</body>
  • 設置下拉框中的選中項(水果名稱);
    • 點擊按鈕,把下拉框中的鱷魚對應的選擇屬性設置selected,直接添加selected屬性即可,或者個selected屬性賦任何值都可以;
    • 補充:如果打印sel.value,就會打印被選中項的索引;
    • 如果要去掉選中,可以將對應的selected屬性值設為false,但是有些瀏覽器不支持,最好是remove該屬性。
    <body>
    <button id="selectFish">水產品</button><button id="rid">去除</button>
    <br>
    <select>
        <option id="banana">香蕉</option>
        <option>茄子</option>
        <option id="fish" >鱷魚</option>
        <option>西瓜</option>
    </select>
    <script>
        //挑選出下拉列表中的某一項
        var selBtn = document.getElementById("selectFish");
        var ridBtn = document.getElementById("rid");
        var eyu = document.getElementById("fish");
        var banana = document.getElementById("banana");
        selBtn.onclick = function () {
            eyu.selected = true;
        };
        ridBtn.onclick = function () {
            eyu.selected = false;
            banana.selected = true;
        };
    </script>
    </body>
  • 給文本框賦值,獲取文本框的值;
<body>
    <input type="text"> <br>
    <input type="text"> <br>
    <input type="text"> <br>
    <input type="text"> <br>
    <input type="text"> <br>
    <button>賦值</button>
    <button>取值</button>
<script>
    var inpArr = document.getElementsByTagName("input");
    var btnArr = document.getElementsByTagName("button");
    //賦值
    btnArr[0].onclick = function () {
        for(var i=0; i<inpArr.length; i++){
            inpArr[i].value = i;
        }
    };
    //取值
    btnArr[1].onclick = function () {
        var valueArr = [];
        for(var i=0; i<inpArr.length; i++){
            valueArr.push(inpArr[i].value);
        }
        console.log(valueArr.join(" "));
    };
</script>
</body>
  • 全選反選;
  • 隔行變色(使用childNodes實現)。

DOM的樣式設置(兩種方式)

className
style
  • 獲取樣式

    • DOM的style屬性只能獲取標簽中使用style設置的樣式,無法獲取嵌入或外部樣式;
    • style.cssText獲取style里面的字符串;
  • 設置樣式

    • 無論設置還是獲取只能操作行內式。
  • style屬性設置和獲取(style是一個對象,不能獲取內嵌和外鏈)

    • 樣式少的時候使用;
    • style是對象;
    • 值是字符串,沒有設置時是"";
    • 命名規則,駝峰命名,和css不一樣;
    • 設置了類樣式不能獲取(只和行內式交互,和內嵌式和外鏈無關);
    • box.style.cssText = "字符串形式的樣式"。
  • style常用屬性

    • backgroundColor;
    • backgroundImage;
    • color;
    • width;
    • height;
    • border;
    • opacity(IE8以前filter:alpha(opacity=xx));
    • 注意DOM對象style屬性和標簽中style內的值不一樣,因為在JS中-不能作為標識符;
      • backgroundColor -> DOM中;
      • background-color -> CSS中。
  • 位置:

    • position;
    • left;
    • top;
    • right;
    • bottom;
    • z-index。
  • 練習:

    • 給變div的大小和透明度;
    • 當前輸入的文本框高亮顯示;
    • 高級隔行變色、高亮顯示;
    • 百度皮膚;
      • 獲取body:
var body = document.getElementsByTagName("body");
//或者
var body = document.body;   //document內置了直接獲取body的方法
  • 顯示隱藏/關閉廣告/顯示二維碼(隱藏方法);
    • display(用的較多,可以占位置):元素隱藏之后,不占位置,頁面上的元素會重新排列;
    • visibility:元素隱藏之后占位置(hidden、visible);
    • opacity(用的較多,控制器來方便);
    • position。
  • 提高層級。

封裝

  • 練習
    • 菜單練習

動態創建元素(操作元素)三種方式

  • 方式一:document.wtrite(),document.write()能夠識別標簽;,不常用,因為容易覆蓋之前的標簽;

  • 方式二:innerHTML,直接寫會覆蓋之前的,一般這樣使用div.innerHTML += "<li>xxx</li>;",用的比較多,綁定屬性和內容比較方便;

  • 方式三:利用DOM的API創建,document.createElement("li"),用的也比較多,指定數量的時候一般用這種方法。

  • 操作元素:

    • 父元素.appendChild(子元素);:在父元素的最后面添加子元素;
    • 父元素.insertBefore(newEle,aaa);:在指定位置添加;
    • 父元素.removeChild(子元素);
    • 父元素.replaceChild(newEle,oldEle);,用的較少;
    • 需要克隆的節點.cloneNode(true);,參數為true時,是深拷貝,一般都是用深拷貝。
  • 練習:

    • 動態創建列表,高亮顯示(四大美女);
    • 祝愿墻;
    • 左右切換城市或者水果;
      • div.onclick = function(){//code};,如果函數不帶參數,我們可以直接綁定一個函數名;但是如果函數帶參數,我們需要在匿名函數中去調用這個帶參數的函數。
    • 動態創建祝愿墻;
    • 在線會員列表;
    • 模擬百度搜索文本框;
      • a.indexOf(b);返回b在a中的位置,如果`b="ccc;",那么返回a中ccc的第一個c的位置,如果a中沒有ccc,那么就返回-1;

動態創建表格(了解)

  • 方式一:createElement();;
  • 方式二:
  • rows (只讀,table和textarea能用);
  • insertRow() (只有table能用);指定索引值之前插入
  • deleteRow() (只有table能用);
  • cells (只讀,table和textarea能用);
  • insertCell() (只有tr能調用)
  • deleteCell() (只有tr能調用)

內置對象

  • 內置對象就是指這個語言自帶的一些對象,供開發者使用,這些對象提供了一些常用的或者最基本而又必要的功能。
對象名稱 對象說明
Arguments 函數實參集合
Array 數組
Boolean 布爾對象
Date 日期時間對象
Error 異常對象
Function 函數構造器
Math 數學對象
Number 數值對象
Object 基礎對象
RegExp 正則表達式對象
String 字符串對象
Date
  • 日期對象四種聲明/定義方式

    • 直接定義:var date1 = new Date();獲取當前時間;
    • 設定指定時間(兼容最強):var date2 = new Date("2017/1/1 20:12:12");;
    • 不常用:var date3 = new Date("Wed Jan 27 2016 12:00:00 GMT+0800(中國標準時間)");
    • var date4 = new Date(2016,1,27);
    • 后兩種兼容性不好,不建議使用。
  • Date對象的方法:

    • getDate() //獲取日:1-31;
    • getDay() //獲取星期:0-6(0代表周日)
    • getMonth() //獲取月:0-11(1月從0開始)
    • getFullYear() //獲取完整年份(瀏覽器都支持)
    • getHours() //獲取小時:0-23
    • getMinutes() //獲取分鐘:0-59
    • getSeconds() //獲取秒:0-59
    • getMilliseconds() //獲取毫秒
    • getTime() //返回累計毫秒數(從1970/1/1午夜)
  • 返回距離1970/1/1毫秒數

    • var date = Date.now();
    • var date = +new Date();
    • var date = new Date().getTime();
    • var date = new Date().valueOf();
    • 返回1970/1/1午夜與當前日期和時間之間的毫秒數。
  • 案例:

    • 日歷:顯示當前年月日和星期
    • 倒計時:蘋果發布會:倒計時包括天時分秒;
      • 當任一階段的時間小于10時,要在前面補0,否則會有閃動;
      • 解決方案:hour = hour<10?"0"+hour:hour;
String(Boolean/Number)
  • 給索引查字符(charAt/charCodeAt)
    1. charAt,獲取相應位置字符(參數:字符位置)
      • 字符串中第一個字符的下標是0。如果參數index不在0與string.length之間,該方法將返回一個空字符串;
    2. charCodeAt,獲取相應位置字符編碼(參數:字符位置)
      • charAt()方法和charCodeAt()方法用于選取字符串中某一位置上的單個字符;
      • 區別:charCodeAt()方法,它并不返回指定位置上的字符本身,而是返回該字符在Unicode字符集中的編碼值。如果該位置沒有字符,返回值為NaN。
字符/字符編碼 = Str.charAt/charCodeAt(索引值);
  • 簡單數據類型也有屬性,因為底層會進行數據類型轉換,但是簡單數據類型``不能綁定``屬性和方法。

  • 給字符查索引(indexOf/lastIndexOf)

    • indexOf,從前向后索引字符串的位置(參數:索引字符串);
      • 從前向后尋找并返回第一個符合元素的位置。
    • lastIndexOf,從后向前索引字符串的位置(參數:索引字符串);
      • 從后向前尋找并返回第一個找到的符合元素的位置。
    • 練習:求一個字符串占多少字符位。(一個漢字占兩個字符位,英文的所有字符在0-127之間)。長度只看字符個數,不分中英文。
  • url編碼和解碼(了解)

    • uri(uniform resource identifiers),通過資源標識符進行編碼,以便發送給瀏覽器。有效的uri中不能包含某些字符,例如空格。而這uri編碼方法就可以對uri編碼,它們用特殊的utf-8編碼替換所有無效的字符,從而讓瀏覽器能夠接受和理解;
    • encodeURIComponent()函數可以把字符串作為URI組件進行編碼;
    • decodeURIComponent()函數可以把字符串作為URI組件進行解碼。
  • 字符串的連接:

新字符串 = str1.concat(str2);
  • 字符串的截取
    • slice(參數1,參數2);,截取字符串,參數1代表截取的起始位置,參數2代表終點位置,兩個參數都是索引值。

      • (2,5):正常包左不包右;
      • (2):從指定的索引位置截取到最后;
      • (-3):從倒數第幾個截到最后;
      • (5,2):前面的數大于后面的數,返回空。
    • substr(參數1,參數2),截取字符串,參數1是截取起始位置,參數2是截取的長度,參數1是索引值,參數2是數值。

      • (2,4):從索引值為2的位置開始,截取4個字符;
      • (1):一個值,從指定位置截取到最后;
      • (-3):從倒數第幾個截取到最后;
      • 不包括前大后小的情況。
    • substring(參數1,參數2)同slice

      • 不同點:參數能智能調換位置;
      • 參數為負值時,將獲取全部字符串。
      • (2,5),正常包左不包右;
      • (2),從指定的索引位置截到最后;
      • (-3),截取全部字符;
      • (5,2),前面大后面小會智能調換位置(2,5);
      • 兩個參數都是索引。
  • 特殊方法簡介

    • trim() //只能去除字符串前后的空格,中間的去不了;
    • replace(參數1,參數2) //替換,將字符串中的參數1(假定為"aaa")替換成參數2,從前往后查找"aaa",只能替換一次;如果要全部替換就將"aaa"改為/aaa/g;現在只能替換全部是小寫的"aaa",如果要不區分大小寫,就寫成/aaa/gistr.replace(/aaa/gi,"bbb");
    • split("&") //字符串變數組:如果沒有參數,將把整個字符串作為一個元素添加到數組中;如果參數是空字符串"",將會把字符串的每一個字符當成一個元素添加到數組中;如果參數是指定分隔符"&",將會把字符串用&分割成元素然后分別添加到數組中。
    • 大小寫轉換:
      • to(Locale)UpperCase() //全部轉換成大寫;
      • to(Locale)LowerCase() //全部轉換成小寫。
  • 基本包裝類型:

    • 為了方便操作基本數據類型,JavaScript還提供了三個特殊的引用類型:String/Number/Boolean;
    • 例如:
var s1 = "zhangsan";
var s2 = s1.substring(5);
  • 解析:s1是基本數據類型,基本數據類型是沒有屬性和方法的;當調用s1.substring(5)時,先把s1包裝成String類型的臨時對象,再調用substring方法,最后銷毀臨時對象;實現過程如下:
var s1 = "zhangsan";
//當調用s1.substring(5)時,具體過程解析如下:
var s1Temp = new String(s1);
var s2 = s1Ttemp.substring(5);
s1Temp = null;
  • 字符串練習

    • 截取字符串“我愛你中國,我親愛的母親”中的“中國,我親愛”;
    • "abcoefoxyozzopp"查找字符串中所有"o"出現的位置;
    • 把字符串中所有的"o"替換成"!";
    • 判斷一個字符串中出現次數最多的字符,統計這個次數。
    • 給定一個字符串:"abaasdffggghhjjkkgfddsssss3444343"問題如下:
      • 字符串的長度;
      • 取出指定位置的字符,如:0、3、5、9等;
      • 查找指定字符是否在以上字符串中存在,如i、c、b等;
      • 替換指定的字符,如g換成22,ss替換成b等操作方法;
      • 截取指定開始位置到結束位置的字符串,如取得1-5的字符串;
      • 找出以上字符串中出現次數最多的字符和出現的次數。
  • 獲取節點元素的封裝(重點

HTML方法(了解)
  • anchor(); //創建a鏈接
  • big();
  • sub();
  • sup();
  • link();
  • bold();
  • str.link(); //返回值是字符串
Math
  • Math.abs();:取絕對值;
  • Math.floor();:向下取整;
  • Math.ceil();:向上取整;
  • Math.round();:四舍五入取整;
  • Math.random();:獲得0~1之間的隨機數。
addEventListenner(事件監聽器,原事件被執行的時候,后面綁定的事件照樣會被執行,不會發生層疊現象,更適合團隊開發。如果同一個按鈕綁定多個onclick事件,后面的會層疊前面的,只會執行最后一個onclick綁定事件。)
  • 使用方法
    • btn.addEventListener("click",fn);;
    • 調用者是事件源,參數1是事件名(不帶on不帶小括號),參數2是執行的函數,參數3是捕獲或者冒泡(以后再講)。
  • 實現原理(事件監聽原理)(了解,自己封裝一個)
    • 不能直接執行函數,要先進行判斷;
    • 如果以前綁定過事件,那么把以前的事件執行完畢再執行現在的函數;
    • 如果沒有被定義過事件,該事件源的該事件對應的屬性應該是null,對應的Boolean值應該為false;如果已經定義過該事件源的該事件,該事件源的該事件屬性應該是function本身,對應的Boolean值類型為true;
    • 可以通過綁定屬性的方式綁定方法,可以通過獲取屬性的方式來獲取方法
<body>
    <button>按鈕一</button>
    <button>按鈕二</button>

    <script>
        var btn1 = document.getElementsByTagName("button")[0];
        var btn2 = document.getElementsByTagName("button")[1];

        btn1.onclick = function () {
            console.log("我是王老大");
        };

        fn("click",fn1,btn1);
        fn("click",fn2,btn1);
        fn("click",fn3,btn1);
        fn("mouseover",fn2,btn2);

        function fn1() {
            console.log("黃河入海流;關公耍大刀");
        }
        function fn2() {
            console.log("我自橫刀向天笑,去留肝膽兩昆侖");
        }
        function fn3() {
            console.log("床前明月光,一片白茫茫");
        }

        function fn(str, func, ele) {
            var oldFunc = ele["on"+str];
            ele["on"+str] = function () {
                if (oldFunc){
                    oldFunc();
                }
                func();
            }
        }
    </script>
</body>
  • 兼容性(addEventListener和attachEvent)
    • 事件名稱的區別:
      • addEventListener中第一個參數type是click、load,不帶on;ele.addEventListener("click",fn);
var btn3 = document.getElementsByTagName("button")[2];
btn3.addEventListener("click",fn33);
function fn33() {
        console.log("你點了addEventListener");
}
  • attachEvent中第一個參數type是onclick、onload。ele.attachEvent("onclick",fn);
var btn4 = document.getElementsByTagName("button")[3];
btn4.attachEvent("onmouseover",fn44);
function fn44() {
        console.log("你碰到attachEvent了");
}
  • this的區別:
    • addEventListener:事件處理程序會在當前對象的作用于運行,因此,事件處理程序的this就是當前對象;
    • attachEvent:事件處理程序是在全局作用域下運行,因此this就是window。
  • 兼容性:
    • addEventListener支持火狐、谷歌、IE9+;
    • attachEvent兼容IE678。
  • 解決方案:
    • 通過判斷調用的方式來兼容IE678;
    • 判斷瀏覽器是否支持該方法,如果支持就直接調用,如果不支持就用其它方法。
//兼容性寫法,定義一個對象EventListen
        EventListen = {
            addEvent: function (ele,fn,str) {
                if (ele.addEventListener){
                    ele.addEventListener(str,fn);
                }else if (ele.attachEvent){
                    ele.attachEvent("on"+str,fn);
                }else{
                    ele["on"+str] = function () {
                        console.log("都不能綁定");
                    }
                }
            }
        };

        EventListen.addEvent(btn4,fn44,"mouseover");
  • 移除事件(解決綁定)
    • btn.onclick = null;
    • 谷歌、火狐、IE9+:btn.removeEventListener("click",fn),只能移除通過addEventListener方法添加的事件;
    • IE678:btn.detachEvent("onclick",fn),只能解綁通過attachEvent方法綁定的事件;
EventListen = {
        deleteEvent:function (ele,fn,str) {
            if (ele.removeEventListener){
                ele.removeEventListener(str, fn);
            }else if (ele.detachEvent){
                ele.detach("on"+str,fn);
            }else {
                ele["on"+str] = null;
            }
        }
};
EventListen.deleteEvent(btn4,fn,"click");
  • 封裝
//封裝
EventListen = {
    addEvent: function (ele,fn,str) {
        if (ele.addEventListener){
            ele.addEventListener(str,fn);
        }else if (ele.attachEvent){
            ele.attachEvent("on"+str,fn);
        }else{
            ele["on"+str] = function () {
                console.log("都不能綁定");
            }
        }
    },

    deleteEvent:function (ele,fn,str) {
        if (ele.removeEventListener){
            ele.removeEventListener(str, fn);
        }else if (ele.detachEvent){
            ele.detach("on"+str,fn);
        }else {
            ele["on"+str] = null;
        }
    }
};
var btn = document.getElementsByTagName("button")[4];
EventListen.addEvent(btn,fn1,"click");
EventListen.deleteEvent(btn,fn1,"click");

事件(DOM重點

什么是事件
  • JavaScript是事件驅動的;
  • 什么是事件
    • 觸發-響應;
    • 事件的概念:
      • 事件源:觸發事件的對象;
      • 事件名稱:click、mouseover等;
      • 事件處理程序:onclick、onmouseover等。
注冊事件的兩種方式
  • onclick:

    • DOM0;
    • 幾乎所有的瀏覽器都支持;
  • addEventListener

    • DOM2;
    • 現代瀏覽器支持,IE9+;
    • 可以給同一個事件注冊多個事件處理程序;
    • 可以選擇捕獲或者冒泡;
    • IE9以前使用atachEvent。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,428評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,024評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 175,285評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,548評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,328評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,878評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,971評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,098評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,616評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,554評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,725評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,243評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,971評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,361評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,613評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,339評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,695評論 2 370

推薦閱讀更多精彩內容

  • 一、JS前言 (1)認識JS 也許你已經了解HTML標記(也稱為結構),知道了CSS樣式(也稱為表示),會使用HT...
    凜0_0閱讀 2,784評論 0 8
  • 第1章 認識JS JavaScript能做什么?1.增強頁面動態效果(如:下拉菜單、圖片輪播、信息滾動等)2.實現...
    mo默22閱讀 1,313評論 0 5
  • 國家電網公司企業標準(Q/GDW)- 面向對象的用電信息數據交換協議 - 報批稿:20170802 前言: 排版 ...
    庭說閱讀 11,043評論 6 13
  • 《ijs》速成開發手冊3.0 官方用戶交流:iApp開發交流(1) 239547050iApp開發交流(2) 10...
    葉染柒丶閱讀 5,240評論 0 7
  • 時間: 17:10地點: 學校門口綠化帶一角任務: 接老弟放學 16:30,老媽和表姐在附近買菜,我就光榮的被派來...
    轉不出的時光閱讀 213評論 0 0