js笔记(五)文档对象模型DOM
| 一、DOM選擇器 | 1. id 選擇器:getElementById("id名"); 2. class 選擇器:getElementByClassName("class名"); 3. 標簽選擇器:getElementsByTagName("標簽名"); 4. name 選擇器:getElementById("name的屬性值"); 5. ES5新增的兩種選擇器:querySelector()、querySelectorAll(); 6. 父級選子級children、子級選父級parentNode |
| 二、DOM屬性的操作 | 1. 內置屬性; 2. 自定義屬性:通過attribute系列; 總結 |
| 三、節點的操作 | 1. 節點樹; 2. 節點的操作; 3. 過濾空白節點 |
| 四、高級選擇器 | previousSibling、previousElementSibling、nextSibling、nexElementSibling、firstChild、firstElementChild、lastChild、lastElementChild、ownerDocument |
| 五、元素的操作 | 1. 增:createElement()配和appendChild(); 2. 刪除:remove()、removeChild(具體子元素); 3. 修改(不建議改標簽): outerHTML、innerHTML |
| 六、獲取元素寬高 | 1.頁面滾動的距離; 2. 頁面可視區域的大小、整個頁面的大小; 3. 獲取圖片寬高 |
| 七、獲取樣式 | 元素.style.css樣式常用作設置,不用來獲取; |
| 八、添加、刪除、修改class |
文檔對象模型 DOM
1. 概念:DOM(document object model),文檔對象模型(document),當網頁被加載時,瀏覽器會創建頁面的DOM。
2. 作用:通過可編程的對象模型,JavaScript 獲得了足夠的能力來創建動態的 HTML,修改 HTML = 改變元素、屬性、樣式和事件。。
修改 HTML DOM意味著:
(1)改變 HTML 內容;(2)改變 CSS 樣式;(3)改變 HTML 屬性;(4)創建新的 HTML 元素;(5)刪除已有的 HTML 元素;(6)改變事件(處理程序)。
當瀏覽器載入 HTML 文檔, 它就會成為 Document 對象。Document 對象是 HTML 文檔的根節點,它使我們可以從腳本中對 HTML 頁面中的所有元素進行訪問。
console.dir(document);,查看DOM的詳細信息。
一、DOM 選擇器
我們通過 js 可以改變元素的內容(innerHTML)、屬性(value)、樣式(width、height)之前,要先選擇出這個元素。
1. id 選擇器:getElementById("id名")
(1) 通過 id 選擇指定 id 的元素,括號中的“id名”前面不需要“#”。
(2)當有多個相同 id 名時,id 選擇器選擇第一個,體現了 id 的唯一性。
<body><input type="text" name="" id="ipt"><input type="text" name="" id="ipt"><input type="text" name="" id="ipt"> </body> </html> <script>var ipts = document.getElementById("ipt");console.log(ipts) </script>2. class選擇器:getElementsByClassName("class名")
(1) 通過 class 選擇指定 class 的元素,括號中的“class名”前面不需要“.”。低版本ie(ie8+)不兼容;
(2)不管相同 class 名的元素有多少個,它返回的都是數組,這個數組是偽數組。注意要選擇具體元素時加 [0/1/2/...]。
<body><input type="text" name="" class="cont"><input type="text" name="" class="cont"><input type="text" name="" class="cont"><input type="text" name="" class="te"> </body> </html> <script>var teClass = document.getElementsByClassName("te");var conts = document.getElementsByClassName("cont");console.log("class名相同的只有自身",teClass)console.log("class名相同的有多個",conts) </script>3. 標簽選擇器:getElementsByTagName("標簽名")
- 返回的是數組,這個數組是偽數組。選擇具體元素時后面記得加 [0/1/2/...]。<body><input type="text" name="" id="ipt" class="cont"><input type="text" name="" id="ipt" class="cont"><input type="text" name="" id="ipt" class="cont"><input type="text" name="" id="ipt" class="te"><span>1</span> </body> </html> <script>var ipts = document.getElementsByTagName("input");var spans = document.getElementsByTagName("spans");console.log(ipts)console.log(spans) </script>
4. name 選擇器:getElementsByName("name屬性的值")
(1) 選擇的是具有 “name” 屬性的元素,常見的有表單元素;低版本ie(ie8+)不兼容;
(2)返回的是數組,這個數組是偽數組。
<body><input type="text" name="user"><input type="text" name="like"><input type="text" name="like"><input type="text" name="like"><span name="span">1</span> <!-- 自己添加的 name 屬性也可以被選擇 --> </body> <script>var user = document.getElementsByName("user");var likes = document.getElementsByName("like");console.log(user);console.log(likes); </script>5. ES5 新增的兩種選擇器:querySelector()、querySelectorAll()
(1)querySelector("標簽名"/ "#id名" / ".class名");;
-
返回的是單個對象,不管選擇 多個 id 還是多個 class,返回的都是第一個元素。低版本ie(ie8+)不兼容;
<body><input type="text" id="ipt" class="cont"><input type="text" id="ipt" class="cont"><input type="text" id="ipt" class="cont"><input type="text" id="ipt1" class="te"> </body> </html> <script>var ipt1 = document.querySelector("#ipt1");var cont = document.querySelector(".cont");console.log(ipt1);console.log(cont); </script> -
該選擇器還能支持簡單的 css3 選擇器。
docuemnt.querySelector("input[name = user]"); document.querySelector("div span");
(2)querySelectorAll("標簽名"/ "#id名" / ".class名");;
- 返回的是數組,不管選擇的是什么都返回數組,這是個偽數組。低版本ie(ie8+)不兼容;
6. 父級選子級children、子級選父級parentNode
ie8 及 ie8 以下不兼容。
(1)children:父選子,返回數組,這是個偽數組;
(2)parentNode:子選父,返回單個元素;
<div class="msg"><h1>1</h1><h1>2</h1><h1>3</h1> </div> var omsg= document.querySelector(".msg"); var achild = omsg.children; console.log(achild[1].parentNode); //<div class="msg">...</div>二、 DOM屬性的操作
簡單來說,html 中標簽的屬性就是 DOM 屬性。更多的屬性和方法查看菜鳥教程。
為了方便記憶,這里把js中的DOM屬性的操作分為了兩種:內置屬性和自定義屬性。
(1)內置屬性有:
- ① HTML標簽上默認(自帶)的屬性。
- ② js 上操作標簽內容的屬性;
(2)自定義屬性有:
- ① 在HTML標簽上自定義的屬性名和屬性值;
- ② 利用 js 給標簽添加的自定義的屬性名和屬性值。
| setAtrribute("屬性名", "屬性值"); | 屬性名不存在就是新增,存在就是修改屬性值。 |
| getAtrribute("屬性名"); | 獲取屬性值; |
| removeAtrribute("屬性名"); | 刪除已有的屬性名和它的屬性值,若沒有就會報錯。 |
| hasAttribute("屬性名"); | 判斷屬性是否存在,如果存在返回 true,否則返回 false。 |
1. 內置屬性:
(1)HTML標簽上默認(自帶)的屬性。
例如a標簽中的href、target、title;img中的src、title、alt屬性等就是內置屬性。
-
① 獲取:兩種方法:一、獲取 class 時要用 obox.className,用 . 獲取除 class 類名外的屬性;二、使用getAttribute(),注意獲取類名時直接getAttibute("class");
<div class="box" id="box"><a href="/aaa" target="_blank" title="title111">這是a標簽1</a> </div> <script>var obox = document.querySelector("div");var oa1 = document.querySelector("a");//console.log(obox.class); //undefinedconsole.log(obox.className); //box,獲取類名console.log(oa1.href); // /aaaconsole.log(oa1.getAttribute("title")); //title111 </script> -
② 新增/修改:兩種方法:一、通過“.”,注意新增/修改類名時是“.className”,其他正常新增/修改;二、使用setAttribute(),注意設置類名時直接setAttibute("class", "定義class名");
<a href="/aaa" target="_blank" title="title111" id="one">這是a標簽1</a> <a href="/www.xxx" id="two">這是省略title屬性的a標簽</a> <script>var oa1 = document.getElementById("one");var oa2 = document.getElementById("two");oa1.class = "a1"; //無效oa2.className = "a2";oa2.target = "_blank";oa2.setAttribute("title","title222");console.log(oa1);console.log(oa2) </script> -
③ 刪除:只能通過removeAttribute()來刪除。
<a href="/aaa" target="_blank" title="title111" id="one">這是a標簽1</a> <script>var oa1 = document.getElementById("one");delete oa1.title; //無效oa1.removeAttribute("href");console.log(oa1); </script>
(2)內置的 js 操作標簽內容的幾個屬性:innerHTML、innerText、tagName;
① innerHTML,設置或者返回元素的內容,包括標簽。innerHTML 屬性對于獲取或替換 HTML 元素的內容很有用,它可以用于獲取或改變任意 HTML 元素,包括 <html> 和 <body>;所有主流瀏覽器都支持。
② innerText,返回被選擇的元素中的所有文字內容;不支持Firefox瀏覽器;
③ tagName,以字符串形式返回某個元素的標記名(大寫),只能獲取,修改標簽名不生效。
- outHTML,返回的是標簽本身,可用來改標簽,比如把 p標簽改成 span標簽;
- innerHTML 和 innerText 都可以設置元素內容,但是innerHTML設置標簽可以被瀏覽器解析,而innerText會把標簽當成文本。
2. 自定義屬性: 通過 attibute系列
(1)獲取: getAttribute("自定義屬性名");,不能通過“.”獲取。
<body><!-- p標簽上的index就是自定義的屬性 --><p class="p" index="haha">段落1</p> </body> </html> <script>var op = document.querySelector(".p");console.log(op.index); //undefined 無效console.log(op.getAttribute("index")); //haha </script>(2)設置/修改: setAttribute("自定義屬性名","值");
- 通過“.”設置無效,但是用“.”設置的屬性的屬性值,可以被“.”獲取到,也只能被“.”獲取到。
(3)刪除: removeAttribute("自定義屬性名");
<body><p class="p" index="haha">段落1</p> </body> </html> <script>var op = document.querySelector(".p");op.removeAttribute("index")console.log(op); //成功 </script>總結
(1)不管 HTML標簽的屬性是內置的,還是自定義的,js 都可以使用 attribute 系列的方法去操作HTML標簽的屬性。此外,js 還可以使用 “.” 來操作(除刪除操作外)HTML標簽的內置屬性。
(2)js 可以通過 innerHTML、innerText、來獲取和設置標簽的文本內容,通過tagName獲取選擇的標簽名。
三、 節點的操作
| 根節點 | 整個文檔(html)是一個文檔節點; | #document | null | 數字 9 |
| 元素節點 | 每個 HTML 元素(標簽、標記)是元素節點; | 大寫的標簽名 | undefined 或 null | 數字 1 |
| 屬性節點 | 每個 HTML 屬性(標簽的屬性)是屬性節點,它也屬于元素節點; | 屬性名 | 屬性值 | 數字 2 |
| 文本節點 | HTML 元素內的文本是文本節點(包括注釋里面的文本、換行); | #text | 文本內容 | 數字 3 |
| 注釋節點 | 注釋是注釋節點; | #comment | 注釋內容 | 數字 8 |
1. 節點樹
HTML DOM 將 HTML 文檔視作樹結構,這種結構被稱為節點樹。節點樹中的節點彼此擁有層級關系,這些關系用 “父節點”、“子節點”、“同胞節點(常稱為兄弟節點)” 等術語來表示。
用一段代碼來示例:
(1)父節點:
<html> 節點沒有父節點;它是根節點;
<head> 和 <body> 的父節點是 <html> 節點
<meta>、<title>的父節點是 <head> 節點;
<h1>、<a> 的父節點是 <body> 節點;
(2)子節點:
<html> 節點擁有兩個子節點:<head> 和 <body>;
<head> 節點擁有四個子節點:3個<mate>節點、<title> 節點;
<title> 節點也擁有一個子節點:文本節點 “什么是節點”;
<body> 節點擁有兩個子節點:<h1> 和 <a>;
(3)兄弟節點:
<head> 和 <body> 節點是同胞節點;
<meta> 和 <title> 節點是同胞節點;
<h1> 和 <a> 節點是同胞節點;
2. 節點操作
| nodeName | 只讀的,規定節點的名稱; | 節點.nodeName |
| nodeValue | 規定節點的值; | 節點.nodeValue |
| nodeType | 只讀的,返回節點的類型; | 節點.nodeType |
(1) 根節點的操作
console.log(document.nodeName); //#document 獲取根節點的名稱 console.log(document.nodeValue); //null 獲取根節點的值 console.log(document.nodeType); //9 根節點的類型(2) 屬性節點的操作:元素.attributes;
屬性在元素身上,要操作一個屬性節點,首先選中元素節點。 返回一個 偽數組。
- 偽數組可以用數組的索引、length、遍歷(for),但不能用數組的方法(push()、pop()、forEach,map,filter)。
- 獲取屬性節點的nodeName、nodeValue、nodeType;console.log(atxt.attributes[0].nodeName); //type console.log(atxt.attributes[0].nodeValue); //text console.log(atxt.attributes[0].nodeType); //2
(3) 文本節點的操作: childNodes、parentNode;
通過父選子 、子選父;
| children | 獲取到的是一個偽數組,是所有子元素/標簽(不包括空白節點)的集合。 |
| childNodes | 獲取到的是一個偽數組,是所有節點(元素節點、文本節點(空白節點也是文本節點)、注釋節點等)的集合。ie8不包含空文本節點。 |
| parentNode | 獲取父元素節點。 |
- 節點.childNodes[i],獲取到的是節點本身,是個對象,而不是字符串;console.log(obox.childNodes[0]); //返回節點本身 console.log(obox.childNodes[0].nodeName); //#text console.log(obox.childNodes[0].nodeValue); //文字 節點的值 console.log(obox.childNodes[0].nodeType); //3
3. 過濾空白節點
var list = obox.childNodes; for(var i=0; i<list.length; i++){ //遍歷所有節點if(list[i].nodeType == 1){ //元素節點的nodeType=1console.log(list[i]);} }四、高級選擇器
previousSibling、previousElementSibling、nextSibling、nexElementSibling、firstChild、firstElementChild、lastChild、lastElementChild、ownerDocument
關系(兄弟、父子)選擇器(ie8不支持)
1. 兄弟之間:
(1)相鄰的前一個節點: previousSibling;
(2)相鄰的前一個元素節點: previousElementSibling;
(3)相鄰的下一個節點: nextSibling;
(4)相鄰的下一個元素節點: nexElementSibling;
2. 父子之間:
(1)第一個子節點: firstChild;
(2)第一個子元素節點: firstElementChild,ie7/8 不支持;
(3)最后一個子節點: lastChild;
(4)最后一個子元素節點: lastElementChild;
3. 獲取根節點: ownerDocument 相當于 document;
<body><span>第一個文本</span><ul id="list"><li>1</li><li>2</li><li>3</li><li>4</li></ul><p>我是p</p> </body> <script> var olist = document.getElementById("list");console.log(olist.previousSibling); //#textconsole.log(olist.previousElementSibling); //<span>第一個文本</span>console.log(olist.nextSibling); //#textconsole.log(olist.nextElementSibling); //<p>我是p</p>console.log(olist.firstChild); //#textconsole.log(olist.firstElementChild); //<li>1</li>console.log(olist.lastChild); //#textconsole.log(olist.lastElementChild); //<li>4</li>console.log(olist.ownerDocument); //#document </script>五、 元素的操作
1. 增:createElement()配和appendChild()
先創建元素(元素節點),然后把它追加到已有的元素上。
(1)先創建: document.createElement("標簽名");
創建文本節點用createTextNode("文本節點名稱"),使用方式同 createElement();
(2)插入(通常先給標簽設置一些樣式、內容,最后再插入):
- ① 作為父元素的最后一個子元素插入: document.appendChild("創建的標簽");<body><div id="box"></div> </body> </html> <script>var obox = document.getElementById("box");var addSpan = document.createElement("span"); //創建一個span元素span.innerHTML = "你好"; //給 span 元素設置內容,最后一步再插入obox.appendChild(addSpan); //把創建好的 span 元素插入到 obox 中 </script>
- 插入到之前: insertBefore(newNode,existNode);
2. 刪除:remove()、removeChild(具體子元素)
刪除元素有兩種方式:直接刪除remove(),根據父刪除子 removeChild(具體子元素)。
(1)直接刪除(建議使用): remove();
(2)根據父刪除子: removeChild(具體子元素);
3. 修改(不建議改標簽): outerHTML、innerHTML
<body><div id="box"><p class="msg"><b>標題</b> <span>文字</span></p></div> </body> <script>var obox = document.getElementById("box");console.log(obox.outerHTML);console.log(obox.innerHTML)obox.outerHTML = "<main>"+obox.innerHTML+"</main>"; //outerHTML 是用來改邊標簽的var op = document.querySelector(".msg");op.innerHTML = "<em>hello</em>"; //innerHTML 修改的是元素的內容 </script>六、獲取元素寬高 - 各種尺寸
| offsetParent | 返回元素的偏移容器,即離自身最近的上一級寫了定位的元素,沒有就返回 <body>。 |
| offsetWidth、offsetHeight | 返回元素的 寬度/高度,包括邊框(border)和填充(padding),但不是邊距(margin)。content的width + border + padding |
| offsetTop、offsetLeft | 返回當前元素的相對 垂直/水平 偏移位置(垂直方向是 top+margin值,水平方向是 left+margin值)的偏移容器 |
| clientWidth、clientHeight | 在頁面上返回內容的 可視寬度/高度(不包括邊框,邊距或滾動條)content的width + padding |
| clientTop、clientLeft | 當前元素的 上/左邊框 的大小。 |
| scrollWidth、scrollHeight | 返回元素的整個 寬度/高度(包括帶滾動條的隱蔽的地方)。 |
| scrollTop、scrollLeft | 返回當前視圖中的實際元素的 頂部邊緣和頂部邊緣/左邊緣和左邊緣 之間的距離。 |
1. 頁面滾動的距離
onscroll = function(){var yTop = document.documentElement.scrollTop; //縱向滾動 滾動條距離頁面頂部的距離var xLeft = document.documentElement.scrollLeft; //橫向滾動 滾動條距離頁面左邊的距離console.log(yTop);console.log(xLeft); }兼容寫法(兼容低版本瀏覽器):
onscroll = function(){var yTop = document.body.scrollTop;var xLeft = document.body.scrollLeft;console.log(yTop);console.log(xLeft); }2. 頁面可視區域的大小、整個頁面的大小
onresize = function(){//頁面可視區域的大小var dWidth = document.documentElement.clientWidth;var dHeight = document.documentElement.clientHeight;console.log(dWidth); console.log(dHeight);//頁面整體的大小,即body/html(除了margin值)的大小var bWidth = document.body.clientWidth;var bHeight = document.body.clientHeight;console.log(bWidth); //3000console.log(bHeight); //2000}3. 獲取圖片寬高
因為圖片要獲取資源路徑,所以用到 onload。 onload用于頁面(window)和圖片 (圖片的元素)。
var oimg = document.queryselect("img");oimg.onload = function(){console.log(oimg.offsetWidth); }4. 注意: 鼠標類尺寸樣式都是X,Y,瀏覽器及元素的各項尺寸時Height,Width;(這里后面再詳細介紹)</font
七、獲取樣式
1. 設置樣式:元素.style.css樣式;
這種方法常用來設置,而不是獲取。
var obox = document.getElementById("box");console.log(obox.style.width)//obox.style.width = 600+ "px";console.log(obox.style.width)//600px2. 獲取樣式:getComputedStyle(元素,false).小駝峰樣式名;
用 getComputedStyle(元素,false).小駝峰樣式名,ie7+用 元素.currentStyle.樣式名;
function getStyle(ele, attr){if(ele.currentStyle){//return ele.currentStyle.width;//當對象身上的屬性是變量時,要用 [] 來訪問,而不用 .return ele.currentStyle[attr];} else {return getComputedStyle(ele,false)[attr]; } console.log( getStyle(obox,"height") )八、添加、刪除、修改class
(1)在已經有 class 的 DOM 上添加新的 class:元素.classList.add("class名稱");
(2)在已經有 class 的 DOM 上刪除新的 class:元素.classList.remove("class名稱");
(3)將當前的 class 名改成另外一個名稱:元素.className("class名稱");
總結
以上是生活随笔為你收集整理的js笔记(五)文档对象模型DOM的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: js笔记(四)内置对象Math和Date
- 下一篇: js笔记(八)ES6