JavaScript(第二十天)【DOM操作表格及樣式】
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>
</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來獲取和創建這個相同的表格。
HTML DOM中,給這些元素標簽提供了一些屬性和方法
屬性或方法 |
說明 |
caption |
保存著<caption>元素的引用 |
tBodies |
保存著<tbody>元素的HTMLCollection集合 |
tFoot |
保存著對<tfoot>元素的引用 |
tHead |
保存著對<thead>元素的引用 |
rows |
保存著對<tr> 元素的HTMLCollection集合 |
createTHead() |
創建<thead>元素,並返回引用 |
createTFoot() |
創建<tfoot>元素,並返回引用 |
createCaption() |
創建<caption>元素,並返回引用 |
deleteTHead() |
刪除<thead>元素 |
deleteTFoot() |
刪除<tfoot>元素 |
deleteCaption() |
刪除<caption>元素 |
deleteRow(pos) |
刪除指定的行 |
insertRow(pos) |
向rows集合中的指定位置插入一行 |
<tbody>元素添加的屬性和方法
屬性或方法 |
說明 |
rows |
保存著<tbody>元素中行的HTMLCollection |
deleteRow(pos) |
刪除指定位置的行 |
insertRow(pos) |
向rows集合中的指定位置插入一行,並返回引用 |
<tr>元素添加的屬性和方法
屬性或方法 |
說明 |
cells |
保存著<tr>元素中單元格的HTMLCollection |
deleteCell(pos) |
刪除指定位置的單元格 |
insertCell(pos) |
向cells集合的指定位置插入一個單元格,並返回引用 |
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樣式信息。
DOM一致性檢測
功能 |
版本號 |
說明 |
Core |
1.0、2.0、3.0 |
基本的DOM,用於表現文檔節點樹 |
XML |
1.0、2.0、3.0 |
Core的XML擴展,添加了對CDATA等支持 |
HTML |
1.0、2.0 |
XML的HTML擴展,添加了對HTML特有元素支持 |
Views |
2.0 |
基於某些樣式完成文檔的格式化 |
StyleSheets |
2.0 |
將樣式表關聯到文檔 |
CSS |
2.0 |
對層疊樣式表1級的支持 |
CSS2 |
2.0 |
對層疊樣式表2級的支持 |
Events |
2.0 |
常規的DOM事件 |
UIEvents |
2.0 |
用戶界面事件 |
MouseEvents |
2.0 |
由鼠標引發的事件(如:click) |
MutationEvents |
2.0 |
DOM樹變化時引發的事件 |
HTMLEvents |
2.0 |
HTML4.01事件 |
Range |
2.0 |
用於操作DOM樹中某個範圍的對象和方法 |
Traversal |
2.0 |
遍歷DOM樹的方法 |
LS |
3.0 |
文件與DOM樹之間的同步加載和保存 |
LS-Async |
3.0 |
文件與DOM樹之間的異步加載和保存 |
Valuidation |
3.0 |
在確保有效的前提下修改DOM樹的方法 |
//檢測瀏覽器是否支持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樣式的訪問方式。
CSS屬性及JavaScript調用
CSS屬性 |
JavaScript調用 |
color |
style.color |
font-size |
style.fontSize |
float |
非IE:style.cssFloat |
float |
IE:style.styleFloat |
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‘;
DOM2級樣式規範為style定義了一些屬性和方法
屬性或方法 |
說明 |
cssText |
訪問或設置style中的CSS代碼 |
length |
CSS屬性的數量 |
parentRule |
CSS信息的CSSRule對象 |
getPropertyCSSValue(name) |
返回包含給定屬性值的CSSValue對象 |
getPropertyPriority(name) |
如果設置了!important,則返回,否則返回空字符串 |
item(index) |
返回指定位置CSS屬性名稱 |
removeProperty(name) |
從樣式中刪除指定屬性 |
setProperty(name,v,p) |
給屬性設置為相應的值,並加上優先權 |
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
屬性或方法 |
說明 |
disabled |
獲取和設置樣式表是否被禁用 |
href |
如果是通過<link>包含的,則樣式表為URL,否則為null |
media |
樣式表支持的所有媒體類型的集合 |
ownerNode |
指向擁有當前樣式表節點的指針 |
parentStyleSheet |
@import導入的情況下,得到父CSS對象 |
title |
ownerNode中title屬性的值 |
type |
樣式表類型字符串 |
cssRules |
樣式表包含樣式規則的集合,IE不支持 |
ownerRule |
@import導入的情況下,指向表示導入的規則,IE不支持 |
deleteRule(index) |
刪除cssRules集合中指定位置的規則,IE不支持 |
insertRule(rule, index) |
向cssRules集合中指定位置插入rule字符串,IE不支持 |
sheet.disabled; //false,可設置為true
sheet.href; //css的URL
sheet.media; //MediaList,集合
sheet.media[0]; //第一個media的值
sheet.title; //得到title屬性的值
sheet.cssRules //CSSRuleList,樣式表規則集合
sheet.deleteRule(0); //刪除第一個樣式規則
sheet.insertRule("body { //在第一個位置添加一個樣式規則
PS:除了幾個不用和IE不支持的我們忽略了,還有三個有IE對應的另一種方式:
sheet.rules; //代替cssRules的IE版本
sheet.removeRule(0); //代替deleteRule的IE版本
sheet.addRule("body", "//代替insertRule的IE版本
除了剛才的方法可以得到CSSStyleSheet類型,還有一種方法是通過document的styleSheets屬性來獲取。
document.styleSheets; //StyleSheetList,集合
var sheet = document.styleSheets[0]; //CSSStyleSheet,第一個樣式表對象
為了添加CSS規則,並且兼容所有瀏覽器,我們必須寫一個函數:
var sheet = document.styleSheets[0];
insertRule(sheet, "body", "", 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);
}
}
通過CSSRules屬性(非IE)和rules屬性(IE),我們可以獲得樣式表的規則集合列表。這樣我們就可以對每個樣式進行具體的操作了。
var sheet = document.styleSheets[0]; //CSSStyleSheet
var rules = sheet.cssRules || sheet.rules; //CSSRuleList,樣式表的規則集合列表
var rule = rules[0]; //CSSStyleRule,樣式表第一個規則
CSSStyleRule可以使用的屬性
屬性 |
說明 |
cssText |
獲取當前整條規則對應的文本,IE不支持 |
parentRule |
@import導入的,返回規則或null,IE不支持 |
parentStyleSheet |
當前規則的樣式表,IE不支持 |
selectorText |
獲取當前規則的選擇符文本 |
style |
返回CSSStyleDeclaration 對象,可以獲取和設置樣式 |
type |
表示規則的常量值,對於樣式規則,值為1,IE不支持 |
rule.cssText; //當前規則的樣式文本
rule.selectorText; //#box,樣式的選擇符
rule.style.color; //red,得到具體樣式值
PS:Chrome瀏覽器在本地運行時會出現問題,rules會變成null,只要把它放到服務器上允許即可正常。
總結:三種操作CSS的方法,第一種style行內,可讀可寫;第二種行內、內聯和鏈接,使用getComputedStyle或currentStyle,可讀不可寫;第三種cssRules或rules,內聯和鏈接可讀可寫。
JavaScript(第二十天)【DOM操作表格及樣式】