DOM 在操作生成HTML 上,還是比較簡明的。不過,由於瀏覽器總是存在兼容和陷阱,
導致最終的操作就不是那麼簡單方便了。本章主要了解一下DOM 操作表格和樣式的一些知
識。
一.操作表格
<table>標籤是HTML 中結構最爲複雜的一個,我們可以通過DOM 來創建生成它,或
者HTML DOM 來操作它。(PS:HTML DOM 提供了更加方便快捷的方式來操作HTML,有
手冊)。
- //需要操作的table
- <table border="1" width="300">
- <caption>人員表</caption>
- <thead>
- <tr>
- <th>姓名</th>
- <th>性別</th>
- <th>年齡</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>張三</td>
- <td>男</td>
- <td>20</td>
- </tr>
- <tr>
- <td>李四</td>
- <td>女</td>
- <td>22</td>
- </tr>
- </tbody>
- <tfoot>
- <tr>
- <td colspan="3">合計:N</td>
- </tr>
- </tfoot>
- </table>
- //使用DOM 來創建這個表格
- var table = document.createElement('table');
- table.border = 1;
- table.width = 300;
- var caption = document.createElement('caption');
- table.appendChild(caption);
- caption.appendChild(document.createTextNode('人員表'));
- var thead = document.createElement('thead');
- table.appendChild(thead);
- var tr = document.createElement('tr');
- thead.appendChild(tr);
- var th1 = document.createElement('th');
- var th2 = document.createElement('th');
- var th3 = document.createElement('th');
- tr.appendChild(th1);
- th1.appendChild(document.createTextNode('姓名'));
- tr.appendChild(th2);
- th2.appendChild(document.createTextNode('年齡'));
- document.body.appendChild(table);
PS:使用DOM 來創建表格其實已經沒有什麼難度,就是有點兒小煩而已。下面我們再
使用HTML DOM 來獲取和創建這個相同的表格。
PS:因爲表格較爲繁雜,層次也多,在使用之前所學習的DOM 只是來獲取某個元素會
非常難受,所以使用HTML DOM 會清晰很多。
- //使用HTML DOM 來獲取表格元素
- var table = document.getElementsByTagName('table')[0]; //獲取table 引用
- //按照之前的DOM 節點方法獲取<caption>
- alert(table.children[0].innerHTML); //獲取caption 的內容
PS:這裏使用了children[0]本身就忽略了空白,如果使用firstChild 或者childNodes[0]
需要更多的代碼。
- //按HTML DOM 來獲取表格的<caption>
- alert(table.caption.innerHTML); //獲取caption 的內容
- //按HTML DOM 來獲取表頭表尾<thead>、<tfoot>
- alert(table.tHead); //獲取表頭
- alert(table.tFoot); //獲取表尾
- //按HTML DOM 來獲取表體<tbody>
- alert(table.tBodies); //獲取表體的集合
PS:在一個表格中<thead>和<tfoot>是唯一的,只能有一個。而<tbody>不是唯一的可以
有多個,這樣導致最後返回的<thead>和<tfoot>是元素引用,而<tbody>返回的是元素集合。
- //按HTML DOM 來獲取表格的行數
- alert(table.rows.length); //獲取行數的集合,數量
- //按HTML DOM 來獲取表格主體裏的行數
- alert(table.tBodies[0].rows.length); //獲取主體的行數的集合,數量
- //按HTML DOM 來獲取表格主體內第一行的單元格數量(tr)
- alert(table.tBodies[0].rows[0].cells.length); //獲取第一行單元格的數量
- //按HTML DOM 來獲取表格主體內第一行第一個單元格的內容(td)
- alert(table.tBodies[0].rows[0].cells[0].innerHTML); //獲取第一行第一個單元格的內容
- //按HTML DOM 來刪除標題、表頭、表尾、行、單元格
- table.deleteCaption(); //刪除標題
- table.deleteTHead(); //刪除<thead>
- table.tBodies[0].deleteRow(0); //刪除<tr>一行
- table.tBodies[0].rows[0].deleteCell(0); //刪除<td>一個單元格
- //按HTML DOM 創建一個表格
- var table = document.createElement('table');
- table.border = 1;
- table.width = 300;
- table.createCaption().innerHTML = '人員表';
- //table.createTHead();
- //table.tHead.insertRow(0);
- var thead = table.createTHead();
- var tr = thead.insertRow(0);
- var td = tr.insertCell(0);
- td.appendChild(document.createTextNode('數據'));
- var td2 = tr.insertCell(1);
- td2.appendChild(document.createTextNode('數據2'));
- document.body.appendChild(table);
PS:在創建表格的時候<table>、<tbody>、<th>沒有特定的方法,需要使用document
來創建。也可以模擬已有的方法編寫特定的函數即可,例如:insertTH()之類的。
二.操作樣式
CSS 作爲(X)HTML 的輔助,可以增強頁面的顯示效果。但不是每個瀏覽器都能支持最
新的CSS 能力。CSS 的能力和DOM 級別密切相關,所以我們有必要檢測當前瀏覽器支持
CSS 能力的級別。
DOM1 級實現了最基本的文檔處理,DOM2 和DOM3 在這個基礎上增加了更多的交互
能力,這裏我們主要探討CSS,DOM2 增加了CSS 編程訪問方式和改變CSS 樣式信息。
- //檢測瀏覽器是否支持DOM1 級CSS 能力或DOM2 級CSS 能力
- alert('DOM1 級CSS 能力:' + document.implementation.hasFeature('CSS', '2.0'));
- alert('DOM2 級CSS 能力:' + document.implementation.hasFeature('CSS2', '2.0'));
PS:這種檢測方案在IE 瀏覽器上不精確,IE6 中,hasFeature()方法只爲HTML 和版本
1.0 返回true,其他所有功能均返回false。但IE 瀏覽器還是支持最常用的CSS2 模塊。
1.訪問元素的樣式
任何HTML 元素標籤都會有一個通用的屬性:style。它會返回CSSStypeDeclaration 對
象。下面我們看幾個最常見的行內style 樣式的訪問方式。
- var box = document.getElementById('box'); //獲取box
- box.style.cssFloat.style; //CSSStyleDeclaration
- box.style.cssFloat.style.color; //red
- box.style.cssFloat.style.fontSize; //20px
- box.style.cssFloat || box.style.styleFloat; //left,非IE 用cssFloat,IE 用styleFloat
PS:以上取值方式也可以賦值,最後一種賦值可以如下:
- typeof box.style.cssFloat != 'undefined' ? box.style.cssFloat = 'right' : box.style.styleFloat = 'right';
- box.style.cssText; //獲取CSS 代碼
- //box.style.length; //3,IE 不支持
- //box.style.removeProperty('color'); //移除某個CSS 屬性,IE 不支持
- //box.style.setProperty('color','blue'); //設置某個CSS 屬性,IE 不支持
PS:Firefox、Safari、Opera9+、Chrome 支持這些屬性和方法。IE 只支持cssText,而
getPropertyCSSValue()方法只有Safari3+和Chrome 支持。
PS:style 屬性僅僅只能獲取行內的CSS 樣式,對於另外兩種形式內聯<style>和鏈接
<link>方式則無法獲取到。
雖然可以通過style 來獲取單一值的CSS 樣式,但對於複合值的樣式信息,就需要通過
計算樣式來獲取。DOM2 級樣式,window 對象下提供了getComputedStyle()方法。接受兩個
參數,需要計算的樣式元素,第二個僞類(:hover),如果沒有沒有僞類,就填null。
PS:IE 不支持這個DOM2 級的方法,但有個類似的屬性可以使用currentStyle 屬性。
- var box = document.getElementById('box');
- var style = window.getComputedStyle ?
- window.getComputedStyle(box, null) : null || box.currentStyle;
- alert(style .color); //顏色在不同的瀏覽器會有rgb()格式
- alert(style .border); //不同瀏覽器不同的結果
- alert(style .fontFamily); //計算顯示覆合的樣式值
- alert(box.style.fontFamily); //空
PS:border 屬性是一個綜合屬性,所以他在Chrome 顯示了,Firefox 爲空,IE 爲undefined。
所謂綜合性屬性,就是XHTML 課程裏所的簡寫形式,所以,DOM 在獲取CSS 的時候,最
好採用完整寫法兼容性最好,比如:border-top-color 之類的。
2.操作樣式表
使用style 屬性可以設置行內的CSS 樣式,而通過id 和class 調用是最常用的方法。
- box.id = 'pox'; //把ID 改變會帶來災難性的問題
- box.className = 'red'; //通過className 關鍵字來設置樣式
在添加className 的時候,我們想給一個元素添加多個class 是沒有辦法的,後面一個
必將覆蓋掉前面一個,所以必須來寫個函數:
- //判斷是否存在這個class
- function hasClass(element, className) {
- return element.className.match(new RegExp('(\\s|^)'+className+'(\\s|$)'));
- }
- //添加一個class,如果不存在的話
- function addClass(element, className) {
- if (!hasClass(element, className)) {
- element.className += " "+className;
- }
- }
- //刪除一個class,如果存在的話
- function removeClass(element, className) {
- if (hasClass(element, className)) {
- element.className = element.className.replace(
- new RegExp('(\\s|^)'+className+'(\\s|$)'),' ');
- }
- }
之前我們使用style 屬性,僅僅只能獲取和設置行內的樣式,如果是通過內聯<style>或
鏈接<link>提供的樣式規則就無可奈何了,然後我們又學習了getComputedStyle 和
currentStyle,這隻能獲取卻無法設置。
CSSStyleSheet 類型表示通過<link>元素和<style>元素包含的樣式表。
- document.implementation.hasFeature('StyleSheets', '2.0') //是否支持DOM2 級樣式表
- document.getElementsByTagName('link')[0]; //HTMLLinkElement
- document.getElementsByTagName('style')[0]; //HTMLStyleElement
這兩個元素本身返回的是HTMLLinkElement 和HTMLStyleElement 類型,但
CSSStyleSheet 類型更加通用一些。得到這個類型非IE 使用sheet 屬性,IE 使用styleSheet;
- var link = document.getElementsByTagName('link')[0];
- var sheet = link.sheet || link.styleSheet; //得到CSSStyleSheet
- sheet.disabled; //false,可設置爲true
- sheet.href; //css 的URL
- sheet.media; //MediaList,集合
- sheet.media[0]; //第一個media 的值
- sheet.title; //得到title 屬性的值
- sheet.c***ules //C***uleList,樣式表規則集合
- sheet.deleteRule(0); //刪除第一個樣式規則
- sheet.insertRule("body {background-color:red}", 0); //在第一個位置添加一個樣式規則
PS:除了幾個不用和IE 不支持的我們忽略了,還有三個有IE 對應的另一種方式:
- sheet.rules; //代替c***ules 的IE 版本
- sheet.removeRule(0); //代替deleteRule 的IE 版本
- sheet.addRule("body", "background-color:red", 0);//代替insertRule 的IE 版本
除了剛纔的方法可以得到CSSStyleSheet 類型,還有一種方法是通過document 的
styleSheets 屬性來獲取。
- document.styleSheets; //StyleSheetList,集合
- var sheet = document.styleSheets[0]; //CSSStyleSheet,第一個樣式表對象
爲了添加CSS 規則,並且兼容所有瀏覽器,我們必須寫一個函數:
- var sheet = document.styleSheets[0];
- insertRule(sheet, "body", "background-color:red;", 0);
- function insertRule(sheet, selectorText, cssText, position) {
- //如果是非IE
- if (sheet.insertRule) {
- sheet.insertRule(selectorText + "{" + cssText + "}", position);
- //如果是IE
- } else if (sheet.addRule) {
- sheet.addRule(selectorText, cssText, position);
- }
- }
爲了刪除CSS 規則,並且兼容所有瀏覽器,我們必須寫一個函數:
- var sheet = document.styleSheets[0];
- deleteRule(sheet, 0);
- function deleteRule(sheet, index) {
- //如果是非IE
- if (sheet.deleteRule) {
- sheet.deleteRule(index);
- //如果是IE
- } else if (sheet.removeRule) {
- sheet.removeRule(index);
- }
- }
通過C***ules 屬性(非IE)和rules 屬性(IE),我們可以獲得樣式表的規則集合列表。這
樣我們就可以對每個樣式進行具體的操作了。
- var sheet = document.styleSheets[0]; //CSSStyleSheet
- var rules = sheet.c***ules || sheet.rules; //C***uleList,樣式表的規則集合列表
- var rule = rules[0]; //CSSStyleRule,樣式表第一個規則
- rule.cssText; //當前規則的樣式文本
- rule.selectorText; //#box,樣式的選擇符
- rule.style.color; //red,得到具體樣式值
PS:Chrome 瀏覽器在本地運行時會出現問題,rules 會變成null,只要把它放到服務器
上允許即可正常。
總結:三種操作CSS 的方法,第一種style 行內,可讀可寫;第二種行內、內聯和鏈接,
使用getComputedStyle 或currentStyle,可讀不可寫;第三種c***ules 或rules,內聯和鏈接
可讀可寫。