前端點滴(JS基礎)(六)---- HTML Dom 對象操作

HTML DOM 操作

1. 屬性節點的操作

(1)查詢元素的屬性

屬性不能單獨存在,一定屬於一個標籤。所有,操作屬性,前提必須找到標籤。

語法 描述 特點 支持
元素節點.attributes 獲取元素的所有屬性 - 所有瀏覽器
元素節點.getAttribute(屬性名) 獲取指定屬性的值 標準的獲取已經存在的屬性值的方法 所有瀏覽器
元素節點.屬性名 獲取指定屬性的值 獲取不存在的屬性值時比較好用,能夠獲取類似於readOnly、checked等屬性 所有瀏覽器

實例:

<script>
  var input = document.getElementById('input');
  /* 元素節點.attributes */
  console.log(input.attributes);
  // NamedNodeMap {0: type, 1: id, 2: readonly, type: type, id: id, readonly: readonly, length: 3}
  console.log(input.attributes.length);  // 3
  
  /* 元素節點.getAttribute(屬性名) */
  console.log(input.getAttribute('type'));  //=> text
  console.log(input.getAttribute('readOnly'));  //=> null

  /* 元素節點.屬性名 */
  console.log(input.type);  //=> text
  console.log(input.readOnly);  //=> true
</script>

(2)添加/修改元素的屬性

語法 描述 特點 支持
元素節點.setAttribute(屬性名,屬性值) 設置(添加/修改)元素的所有屬性 屬性不存在表示添加,屬性存在表示修改 所有瀏覽器
元素節點.屬性名 = 值 設置(添加/修改)元素的所有屬性 屬性不存在表示添加,屬性存在表示修改 所有瀏覽器

實例:

/* 設置元素屬性 */
  input.setAttribute("value","yaodao");
  input.value = "yaodao"
  
/* 修改元素屬性 */
  input.setAttribute("name","text2");
  input.name = "text2"

效果:
(設置前):
在這裏插入圖片描述
(設置後):
在這裏插入圖片描述

(3)刪除元素的屬性

/* 刪除元素屬性 */
  input.removeAttribute("value")

在這裏插入圖片描述

(4)判斷元素是否有哪個屬性

語法:標籤節點.hasAttribute("屬性名")

注意: 返回Boolean類型的值。

/* 判斷是否存在元素屬性 */
  console.log(input.hasAttribute("value"));  //=> false
  console.log(input.hasAttribute("name"));  //=> true

總結

元素節點的增刪改查:

  • 增:document.creatElement(“標籤名”); document.creatTextNode(“文本”); 父節點.appendChild(子節點); 父節點.insertBefore(新節點,參照節點)
  • 刪:父節點.removeChild(子節點);
  • 改:父節點.replaceChild(新節點,參照節點)
  • 查:document.getElementById(“元素id”); document.getElementsByTagName(“標籤名”); document.getElementsByClassName(“類名”);document.getElementsByName(“元素的name屬性”);document.querySelector(“css選擇器”);document.querySelectorAll(“css選擇器”)

屬性節點的增刪改查:

  • 增:元素節點.setAttribute(“屬性名”,“屬性值”); 元素節點.屬性名 = “屬性值”;
  • 刪:元素節點.removeAttribute(“屬性名”);
  • 改:元素節點.setAttribute(“屬性名”,“屬性值”); 元素節點.屬性名 = “屬性值”;
  • 查:元素節點.attributes; 元素節點.getAttribute(“屬性名”); 元素節點.屬性名;

2. DOM 對象的通用屬性

innerHTML

  • 獲取/設置元素裏的html內容

innerText

  • 獲取/設置元素裏面的文本內容

nodeName

  • nodeName 是隻讀的

    元素節點的 nodeName 與標籤名相同
    ​屬性節點的 nodeName 與屬性名相同
    ​文本節點的 nodeName 始終是 #text
    ​文檔節點的 nodeName 始終是 #document

nodeValue

  • 元素節點的 nodeValue 是 undefined 或 null
  • 文本節點的 nodeValue 是文本本身
  • 屬性節點的 nodeValue 是屬性值

nodeType
調用nodeType屬性會得到一個數字,這個數字表示節點的類型

  • 元素 1
  • 屬性 2
  • 文本 3
  • 註釋 8
  • 文檔 9

實例:

<script type="text/javascript">
  var p = document.getElementById('p');

//innerHTML,innerText
  /* 獲取元素裏的html內容 */
  console.log(p.innerHTML);   //=> 123<span>456</span>
  /* 獲取元素裏的文本內容 */
  console.log(p.innerText);   //=> 123456

  /* 設置元素中的html內容 */
  p.innerHTML = '<a href="#">按鈕</a>';
  /* 設置元素裏的文本內容 */
  p.innerText = '這是innerText後的文本';

// nodeName
  /* 獲取元素節點的nodeName */
  console.log(p.nodeName);  //=> p
  /* 獲取屬性節點的nodeName */
  console.log(p.getAttributeNode("id").nodeName);  //=> id

// nodeValue
  /* 獲取元素節點的nodeValue */
  console.log(p.nodeValue); //=> undefined
  console.log(p.getAttributeNode("id").nodeValue);  //=> p

// nodeType
  /* 獲取元素節點的nodeType */
  console.log(p.nodeType);  //=> 1
  /* 獲取屬性節點的nodeType */
  console.log(p.getAttributeNode("id").nodeType);  //=> 2
  /* 獲取文本節點的nodeType */  
  console.log(p.childNodes[0].nodeType);  //=> 3
  /* 獲取文檔的nodeType */
  console.log(document.nodeType);  //=> 9
</script>

3. 設置/獲取元素的css樣式

(1)設置樣式

語法: elementNode.style.css樣式 = 值

css樣式的寫法:
①、一個單詞的直接寫即可。比如color height …
②、樣式名稱帶中橫線的,去掉中橫線,後面單詞首字母大寫。比如fontSize lineHeight backgroundColor

實例:
在這裏插入圖片描述

(2)獲取樣式

使用 " elementNode.style.樣式名稱" 的方式只能獲取行內樣式和js已經設置過的樣式。
要想獲取全部的樣式,則必須使用下面的方法:

  • 在IE中支持 elementNode.currentStyle.樣式名稱
  • 火狐支持 getComputedStyle(elementNode).樣式

爲了兼容各個瀏覽器,所以需要自己封裝一個函數,用於獲取完整的css樣式:

function getStyle(el,style){
	// IE 支持類型
	if(el.currentStyle){
		return el.currentStyle[style]
	}else{
	// 火狐支持類型
		return getComputedStyle(el)[style]
	}
}
console.log(getStyle(p,'fontSize'))

調用 getStyle() 獲取完整的樣式。

注意: 樣式名有需要地使用駝峯命名法,並且以字符串的方式參入參數。

4. DOM獲取元素的位置

靜態元素位置屬性:

  • offsetLeft 元素在網頁中水平座標值
  • offsetTop 元素在網頁中垂直座標值
  • offsetWidth 元素在頁面中佔據的寬度
  • offsetHeight 元素在頁面中佔據的高度
    在這裏插入圖片描述
    注意: 當前offsetWidth = width+padding+border。
    注意: 當前offsetLeft = margin-left。
    注意: 當前offsetTop = margin-top。

動態元素位置屬性:

  • scrollLeft 滾動條在容器中水平滾動的距離,多用於瀏覽器的滾動條
  • scrollTop 滾動條在容器中垂直滾動的距離,多用於瀏覽器的滾動條
    在這裏插入圖片描述
    間歇滾動實現案例:
// <ul id="Dong"> 關鍵是css中設置 overflow:hidden;
	var Dong = document.getElementById("Dong");
	Dong.innerHTML += Dong.innerHTML;  
	var iLiHeight = 45;				//設置滾動行高
	Dong.scrollTop = 0;		//初始化
	var tim;																		
	function moving() {
		Dong.scrollTop++;							
		tim = setInterval(scrollUp, 30);
	}							
	function scrollUp() {
		if (Dong.scrollTop % iLiHeight ==0) {
			clearInterval(tim);										
			setTimeout(moving, 3000)
		}																		
		else {
			Dong.scrollTop++;								
			if (Dong.scrollTop >= Dong.scrollHeight/2) {
				Dong.scrollTop =0;        	
			}
		}
	}
	setTimeout(moving,3000); 		
})

5. 事件和事件對象

(1)什麼是事件

瀏覽網頁時,當我們做出點擊鼠標、按鍵盤、移動鼠標等行爲時,這些行爲會被瀏覽器內置的JavaScript引擎所捕獲,並執行對應的某些操作(函數)。那麼你的行爲(動作)+ JavaScript引擎捕獲 + 執行對應的操作 = 事件
所以,一個完整的事件應該包括:

  • 用戶行爲;
  • 瀏覽器捕獲你的行爲;
  • 執行對應的操作(函數)

常見行爲有:鼠標點擊、鼠標的移動、鼠標的移入和移出、鍵盤控制等等。
事件的作用是:通過事件,我們(瀏覽網頁的人)就可以和瀏覽器進行一些交互了。

(2)事件綁定的多種方式

聲明: 如果同時存在標籤事件,DOM方法綁定的事件。優先執行DOM方式綁定的事件。

1、on() 綁定事件

語法:elementNode.on('不帶on的常用事件名',function(){})

實例:

document.getElementById('btn').on('click', function () {
    alert(123);
});

2、事件名綁定事件

語法:elementNode.帶有on的常用事件名 = function(){}

實例:

document.getElementById('btn').onclick = function () {
    alert(123);
};

3、事件監聽綁定事件

事件監聽的方法有兩種:

  • addEventListener——兼容:firefox、chrome、IE、safari、opera;不兼容IE7、IE8
  • attachEvent——兼容:IE7、IE8;不兼容firefox、chrome、IE9、IE10、IE11、safari、opera

addEventListener() 語法: elementNode.addEventListener(event, function, useCapture)

注意: useCapture (可選)布爾值,指定事件是否在捕獲或冒泡階段執行。【true:事件句柄在捕獲階段執行; false:默認,事件句柄在冒泡階段執行】,需要了解事件發生過程:事件捕獲----處於目標----事件冒泡

attachEvent() 語法: elementNode.attachEvent(event, function)

共性與區別:

相同點:
  都是dom對象的方法,可以實現一種事件綁定多個事件處理函數。
  
不同點:

  1. attachEvent是IE有的方法,它不遵循W3C標準,而其他的主流瀏覽器如FF等遵循W3C標準的瀏覽器都使用addEventListener,所以實際開發中需分開處理。

  2. 多次綁定後執行的順序是不一樣的,attachEvent是後綁定先執行(覆蓋),addEventListener是先綁定先執行(不會覆蓋)。

  3. 存在兼容問題,綁定事件名方法不同,addEventListener() 方法的event參數不用帶on ,attachEvent() 方法中的event 參數需要帶on。

同樣爲了兼容各個瀏覽器,所以需要自己封裝一個函數,用於監聽事件:

var btn = document.getElementById('btn');
function listenFn(el,type,fn){
	if(window.addEventListener){
			return el.addEventListener(type,fn);
	}else{
			return el.attachEvent('on'+type,fn)
	}
};
function fn(){
	alert(123);
};
function fn2(){
	alert(456);
};
// ...
listenFn(btn,'click',fn);
listenFn(btn,'click',fn2);
// ... 還可以綁定多個事件

效果:
在這裏插入圖片描述
事件監聽的第三個參數說明:
addEventListener第三個參數涉及到的事件捕獲與冒泡。

 <style>
    #div1{
      width: 200px;
      height: 200px;
      background-color: red;
    }
    #div2{
      width: 100px;
      height: 100px;
      background-color: green;
    }
  </style>
  
<div id="div1" >
    <div id="div2">
      <button id="btn">按鈕</button>
    </div>
</div>
  
<script type="text/javascript">
window.onload=function(){
  document.getElementById("btn").addEventListener("click",function () {
  // body...
    alert("hello");
  });
  document.getElementById("div2").addEventListener("click",function(){
    alert("div2");
  },true);
  document.getElementById("div1").addEventListener("click",function(){
    alert("div1");
  });
}
</script>

效果:
在這裏插入圖片描述
說明:

  • 默認情況下addEventListener() 的第三個參數爲false/不填,表示元素觸發事件在冒泡階段 事件流:btn事件 -> div2事件 -> div1事件。

當處於目標div2 時元素觸發事件,事件就會逐層向上冒泡 div1事件 -> div2事件;當處於目標btn 時元素觸發事件,事件同樣會逐層向上冒泡div1事件 -> div2事件 -> btn事件。

  • 非默認情況下addEventListener() 的第三個參數爲true,表示元素觸發事件在捕獲階段 事件流:div1事件 -> div2事件 -> btn事件。

當處於目標div2 時元素觸發事件,事件會根據捕獲階段的事件流,先觸發div2事件,再經過冒泡階段觸發div1事件。當處於目標btn 時,由於div2 addEventListener() 的第三個參數爲true,在捕獲階段觸發。所以先觸發div2事件,再觸發btn事件,最後觸發div1事件。

  • 不過要注意一點:不要因爲捕獲而忽略冒泡。

4、標籤中綁定事件

直接在標籤中添加事件,例如:
<input type="button" value="按鈕" id="btn" onclick="fn2()">

function fn2(){
   alert(456);
}

5、實例說明

<input type="text" id="username" value="請輸入用戶名" />
<script>
//找到username,綁定獲取焦點事件
    document.getElementById('username').onfocus = function () {
        document.getElementById('username').value = '';
    };
 //優化
    document.getElementById('username').onfocus = function () {
        this.value = '';
    };
</script>

在事件處理函數中,this表示綁定事件的那個元素

HTML代碼:

<!- 要求:頁面中有很多個td,點擊td的時候,讓td的背景顏色發生變化  ->
<table>
    <tr>
        <td></td>
        <td></td>
        <td></td>
    </tr>
    <tr>
        <td></td>
        <td></td>
        <td></td>
    </tr>
</table>

css代碼:

<style>
    table,td{
        border:solid 1px #ccc;
        border-collapse: collapse; /*合併邊框*/
    }
    td{
        width:150px;
        height:50px;
    }
    table{
        margin:10px auto; /*讓表格左右居中對齊*/
    }
</style>

JS代碼:

<script>
    //點擊頁面中的td,點擊之後,讓被點擊的td背景顏色改變成隨機顏色
    //先找到所有的td
    var tds = document.getElementsByTagName('td'); // 返回數組
    //循環,爲每個td都綁定一個單擊事件
    for(var i=0; i<tds.length; i++){
        tds[i].onclick = function () {
            //this 表示綁定事件的那個td
            var r = Math.floor(Math.random()*256);
            var g = Math.floor(Math.random()*256);
            var b = Math.floor(Math.random()*256);
            this.style.backgroundColor = 'rgb('+r+', '+g+', '+b+')';
            //全變紅色
            /*if(this.style.backgroundColor != 'red'){
                this.style.backgroundColor = 'red';
            }else{
                this.style.backgroundColor = 'white';
            }*/
        };
    }
</script>

效果:
在這裏插入圖片描述

(3)常用的事件名

  1. 頁面事件:
  • onload :當頁面載入完畢(頁面中的標籤和外部資源)後觸發
  1. 焦點事件:
  • onfocus :當獲取焦點時觸發
  • onblur :當失去焦點時觸發
  1. 鼠標事件:
  • onmouseover :當鼠標懸浮時觸發
  • onmouseout :當鼠標離開時觸發
  1. 鍵盤事件:
  • onkeypress :當鍵盤按下時觸發(如果按住某個鍵不鬆開,會一直觸發press事件)
  • onkeydown :當鍵盤按下時觸發
  • onkeyup :當鍵盤彈起時觸發
  1. 其他事件:
  • onchange :內容改變時會觸發,常用於select>option。
  • onsubmit :表單提交時觸發,這個事件要給form綁定而不是給提交按鈕綁定
  • onresize : 頁面窗口改變大小時會觸發
  • onscroll :滾動條滾動時觸發

(4)什麼是事件對象

事件對象也是一個對象,它提供了一些屬性,這些屬性描述了當前事件的特點;
不同的事件中,事件對象也有所差異,比如單擊事件中,事件對象會提供pageX和pageY屬性,表示點擊的點距離頁面的距離,比如鍵盤事件中,事件對象會提供keyCode屬性,表示按的是什麼鍵。
總之,事件對象中提供了一些屬性,這些屬性可以很好的描述當前的事件的特點。

(5)獲取事件對象

IE 瀏覽器:window.event;
主流瀏覽器:傳遞給事件函數的參數。

同樣的爲了兼容各個瀏覽器,兼容各個瀏覽器的獲取事件對象的方法:

 document.getElementsByTagName('input')[0].onclick = function(a){
	if(window.event){
		e = window.event;
	}else{
		e = a;
	}
	// 簡寫
	var e = window.event||a;
}

(6)事件對象的常用屬性

下面列舉一些事件對象中的常用屬性:

  • target:返回觸發此事件的元素(事件的目標節點)。
  • currentTarget:返回其事件監聽器觸發該事件的元素。
  • keyCode:表示鍵盤上的鍵對應的數值。
  • altKey:表示是否按了alt鍵,按了結果爲true,沒按結果爲false(組合按鍵的時候,纔會有作用)
  • shiftKey:表示是否按了shift鍵,按了結果爲true,沒按結果爲false(組合按鍵的時候,纔會有作用)
  • ctrlKey:表示是否按了ctrl鍵,按了結果爲true,沒按結果爲false(組合按鍵的時候,纔會有作用)
  • pageX: 鼠標距離頁面左邊的距離
  • pageY: 鼠標距離頁面上面的距離
  • screenX: 鼠標距離屏幕左邊的距離
  • screenY: 鼠標距離屏幕上面的距離

實例:
在這裏插入圖片描述

(7)事件對象的方法

stopPropagation() 阻止冒泡事件的發生。

1. 什麼是冒泡事件?

在這裏插入圖片描述
上述小例子中,點擊元素的子元素,會透過子元素觸發元素本身的事件,這就是冒泡事件。

首先,要清楚什麼是事件流?
事件流:
當一個HTML元素產生一個事件時,該事件會在元素節點與根節點之間的路徑傳播,路徑所經過的節點都會收到該事件,這個傳播的過程叫做DOM事件流。
元素觸發事件時,事件的傳播過程稱爲事件流,過程分爲捕獲和冒泡兩種:

冒泡事件: 微軟提出的 事件由子元素傳遞到父元素的過程,叫做冒泡
捕獲事件: 網景提出的 事件由父元素到子元素傳遞的過程,叫做事件捕獲

有些時候要的就是這個效果,可以不做任何處理;有些時候不希望有冒泡事件發生,那麼可以通過事件對象的方法來阻止冒泡的發生。

2. 阻止冒泡事件的發生

阻止冒泡事件的發生有:

  • 標準瀏覽器使用 evt.stopPropagation(); //evt指的是事件對象
  • IE內核瀏覽器使用 window.event.cancelBubble = true;

可以封裝一個兼容各個瀏覽器的阻止冒泡的方法:

<script>

    /*************** 阻止冒泡函數 *************/
    function zuzhi(evt){
        if(window.event){
            window.event.cancelBubble = true;
        }else{
            evt.stopPropagation(); //evt指的是事件對象
        }
    }

    //分別給兩個div綁定單擊事件
    document.getElementById('d1').onclick = function () {
        alert(11111);
    };
    document.getElementById('d2').onclick = function (evt) {
        alert(22222);
        //阻止冒泡發生
        zuzhi(evt);  // 此處會阻止11111的彈出
    };
</script>

preventDefault() 阻止標籤的默認行爲。

默認行爲就是html標籤的一些默認行爲,比如點擊a標籤會跳轉,比如點擊了submit按鈕表單會提交。這些都屬於標籤的默認行爲。
有些時候,點擊了a標籤或者submit按鈕後不希望執行標籤的默認行爲,這時候就需要阻止默認行爲。
阻止默認行爲:
標準瀏覽器:evt.preventDefault();
IE內核瀏覽器:window.event.returnValue = false;

兼容各個瀏覽器的阻止標籤默認行爲的方法:

<body>
<a href="13冒泡事件.html">跳轉</a>
<form name="f1" action="07全選.html" method="post">
    用戶名:<input type="text" name="username"><br>
    密 碼:<input type="password" name="pwd"><br>
    <input type="submit" id="sub" value="提交">
</form>
<script>
    /********* 阻止標籤的默認行爲 *********/
    //形參evt標籤標準瀏覽器的事件對象
    function zuzhi(evt){
        if(window.event){
            //IE瀏覽器
            window.event.returnValue = false;
        }else{
            //非IE瀏覽器
            evt.preventDefault();
        }
    }
    document.getElementById('sub').onclick = function (evt) {
        //檢測用戶名是否爲空
        if(document.f1.username.value == ''){
            alert('用戶名不能爲空');
            //阻止表單提交
            zuzhi(evt);
            //return false; //return false也可以阻止表單提交
        }
    };
</script>

注意: return false 同樣可以阻止默認行爲。

綜合案例----可編輯表格

HTML:

<table>
    <thead>
    <tr>
        <th>ID</th>
        <th>姓名</th>
    </tr>
    </thead>
    <tbody>
    <tr>
        <td>1</td>
        <td>唐僧</td>
    </tr>
    <tr>
        <td>2</td>
        <td>悟空</td>
    </tr>
    <tr>
        <td>3</td>
        <td>八戒</td>
    </tr>
    <tr>
        <td>4</td>
        <td>沙僧</td>
    </tr>
    <tr>
        <td>5</td>
        <td>白龍馬</td>
    </tr>
    <tr>
        <td>6</td>
        <td>金箍棒</td>
    </tr>
    </tbody>
</table>

css:

<style>
        *{
            margin:0;
            padding:0;
            border:0 none;
        }
        table,th,td{
            border:solid 1px #1b272e;
            border-collapse: collapse; /*合併邊框*/
        }
        table{
            width:400px;
            margin:10px auto; /*左右居中對齊*/
        }
        th,td{
            width:50%;
            padding:3px;
        }
</style>

js:

/* 要求:隔行換色,姓名可修改,且點擊姓名後自動變成 value爲原有值的 input 並且寬高與 td 一致,綁定回車與esc鍵盤事件 */

//兼容各個瀏覽器的獲取完整css樣式的寫法
    function getStyle(node, styleName){
        if(node.currentStyle){
            //說明是IE
            return node.currentStyle[styleName];
        }else{
            return getComputedStyle(node)[styleName];
        }
    }
// 隔行換色
// 找到所有的 tr 進行遍歷,如果遍歷的 i 能夠整除2,就改變顏色。
var trs = document.querySelectorAll('tbody tr');
for(var i = 0;i<trs.length;i++){
	if(i%2 == 0){
		trs[i].style.backgroundColor = '#d4d4d4';
	}
}
//獲取姓名td
var tds = document.querySelectorAll('tbody td:nth-child(2n)');
//循環遍歷給每個姓名td綁定單擊事件
for(var i = 0;i<tds.length;i++){
	tds[i].onclick = function(){
		//將每一個td賦值給變量td進行操作,避免改變原有數據
		var td = this;   //this表示點擊事件的對象td[i]
		var text = td.innerText;
		td.innerHTML = '';
		//創建input框
		var input = document.createElement('input');
		//設置樣式
		input.style.width = getStyle(td,"width");
		input.style.height = getStyle(td,"height");
		input.style.backgroundColor = getStyle(td,"backgroundColor");
		input.style.fontSize = getStyle(td,"fontSize");
		input.style.outline= "none";
		//將保存的td文本賦值給input.value
		input.value = text;
		//在td中加入設置好的input框 
		td.appendChild(input);
		//獲取焦點
		input.focus();

		//綁定鍵盤事件,enter成功設置,esc取消設置(恢復原形)。
          input.onkeyup = function (evt) {
                var e = window.event||evt;
                var keyCode = e.keyCode;
                if(keyCode == 13){ //表示按了回車,表示確定
                    td.innerHTML = ''; //先清空td中的input
                    td.innerHTML = this.value;
                }
                if(keyCode == 27){ //按ESC鍵表示取消
                    td.innerHTML = ''; //先清空td中的input
                    td.innerHTML = text;
                }
            };
	}
}

效果:
在這裏插入圖片描述

發佈了37 篇原創文章 · 獲贊 6 · 訪問量 2227
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章