javascript之DOM技術(一)
一。樣式編程
1.頁面中的每一個元素都具有一個style對象,此對象管理元素的CSS樣式。這是在IE4.0引入的,后來作為DOM標準被接受。使用方法:
var oDiv=document.getElementById("div1");
alert(oDiv.style.backgroundColor);
style對象擁有一個cssText屬性,返回描述元素樣式的CSS字符串。
2.樣式對象style的方法(IE6并不支持這些方法):
(1)getPropertyValue(propertyName)——返回CSS特性propertName的字符串值,比如this.style.getPropertyValue("background-color");這里的propertyName必須按照CSS的樣式定義。
(2)getPropertyPriority()——返回important字符串或者為空
(3)item(index)——返回給定索引處的CSS特性名稱
(4)removeProperty(propertyName)——移除某CSS特性
(5)setProperty(propertyName,value,priorty)——按照執行優先級設定CSS特性的值
3.通過隱藏層實現自定義鼠標提示的例子:
<html>
????<head>
????????<title>Style?Example</title>
??????????<script?type="text/javascript"?src="detect.js"></script>
????????<script?type="text/javascript"?src="eventutil.js"></script>
????????<script?type="text/javascript">
????????????function?showTip()?{
????????????????var?oDiv?=?document.getElementById("divTip1");
????????????????oDiv.style.visibility?=?"visible";
????????????????var?oEvent=EventUtil.getEvent();
????????????????oDiv.style.left?=?oEvent.clientX?+?5;
????????????????oDiv.style.top?=?oEvent.clientY?+?5;
????????????}
????????????function?hideTip()?{
????????????????var?oDiv?=?document.getElementById("divTip1");
????????????????var?oEvent=EventUtil.getEvent();
????????????????oDiv.style.visibility?=?"hidden";
????????????}
????????</script>
????</head>
????<body>
????????<p>Move?your?mouse?over?the?red?square.</p>
????????<div?id="div1"?
?????????????style="background-color:?red;?height:?50px;?width:?50px"
?????????????onmouseover="showTip()"?onmouseout="hideTip()"></div>
?????????<div?id="divTip1"?
??????????????style="background-color:?yellow;?position:?absolute;?visibility:?hidden;?padding:?5px">
????????????<span?style="font-weight:?bold">Custom?Tooltip</span><br?/>
????????????More?details?can?go?here.
?????????</div>
????</body>
</html>
這里使用了我在《
javascript事件模型框架》中摘記的JS文件。實現可折疊區域的道理與此相同,很常用的功能,不再細說。
4.訪問樣式表,因為style對象只能訪問一個元素的CSS樣式,而對于<style/>定義的或者外部CSS文件定義的CSS規則沒辦法訪問,這就引出了如何訪問樣式表的問題。我們可以通過下面的方式訪問:
var?cssRules=document.styleSheets[0].cssRules||document.styleSheets[0].rules;
document.styleSheets返回頁面上所有樣式表的引用,標準DOM中規定每個樣式表的規則集合叫cssRules,而IE中叫rules,所以我們用上面的表達式來處理瀏覽器兼容問題。一個訪問的例子:
<html>
????<head>
????????<title>Accessing?Style?Sheets?Example</title>
????????<style?type="text/css">
????????????div.special?{
????????????????background-color:?red;
????????????????height:?10px;
????????????????width:?10px;
????????????????margin:?10px;
????????????}
????????</style>
????????<script?type="text/javascript">
????????????function?changeBackgroundColor()?{
????????????????var?oCSSRules?=?document.styleSheets[0].cssRules?||?document.styleSheets[0].rules;
????????????????oCSSRules[0].style.backgroundColor?=?"blue";
????????????}
????????</script>
????</head>
????<body>
????????<div?id="div1"?class="special"></div>
????????<div?id="div2"?class="special"></div>
????????<div?id="div3"?class="special"></div>
????????
????????<input?type="button"?value="Change?Background?Color"?onclick="changeBackgroundColor()"?/>
????</body>
</html>
點擊按鈕時將三個div的背景色都設置為藍色。
5.最終樣式:顧名思義,就是樣式規則(外部定義和內聯的)綜合計算之后呈現給用戶的樣式信息,用來告訴我們元素最終是如何顯示在屏幕上的。IE和標準的DOM也有區別:
(1)IE中的最終樣式稱為currentStyle對象,與style對象不同的是它是只讀的,你只能讀而不能給它賦值。
(2)DOM中的最終樣式,通過document.defaultView.getComputedStyle(元素對象,偽元素對象或者null)方法獲得
二。innerHTML和innerText
很常用的功能,特別是在AJAX應用中,經常采用的手段是從服務端返回一小段HTML代碼,通過innerHTML嵌入某個層當中來動態顯示下拉框等。一個比較常見的用法:
oDiv.innertText=oDiv.innerText;
表示從指定元素中刪除所有的HTML標簽。
三。outerText和outerHTML
與innerHTML和innerText,不過替換的是整個目標節點,僅在IE和opera中支持此特性
四。范圍
叫選區也許更為恰當,range用來選擇文檔的某個部分而不管節點的邊界。也有兩種的范圍實現:DOM和IE的
1.DOM的range
(1)在DOM中創建選區的方法:
var?supportDOMRange=document.implementation.hasFeature("Range","2.0");
if(supportDOMRange)
??var?oRange=document.createRange();
先判斷是否支持DOM,然后使用createRange()方法創建范圍
(2)簡單選區
考慮下面的代碼:
<p?id="p1"><b>hello</b>world</p>
我們通過下面的JS代碼來訪問上面這段代碼:
var?oRange1=document.createRange();
var?oRange2=document.createRange();
var?op1=document.getElementById("p1");
oRange1.selectNode(op1);
oRange2.selectNodeContents(op1);
兩個范圍,通過selectNode和selectNodeContents方法來選區,有什么不同呢?oRange1選中的范圍包括<p/>節點以及它的全部子節點,而oRange2只包含op1的子節點和文本節點(
就是"<b>hello</b>world")。
(3)范圍的特性:
<1>startContainer——范圍是從哪個節點開始的,也就是第一個節點的父節點
<2>startOffset——在startContainer的偏移位置。
<3>endContainer——最后一個節點的父節點
<4>endOffset——在endContainer中范圍結束的偏移位置
<5>commonAncestorContainer——startContainer和endContainer都處于哪個最小的節點
演示這些特性的例子:
<html>
????<head>
????????<title>DOM?Range?Example</title>
????????<script?type="text/javascript">
????????????function?useRanges()?{
????????????????var?oRange1?=?document.createRange();
????????????????var?oRange2?=?document.createRange();
????????????????var?oP1?=?document.getElementById("p1");
????????????????oRange1.selectNode(oP1);
????????????????oRange2.selectNodeContents(oP1);
????????????????
????????????????document.getElementById("txtStartContainer1").value?=?oRange1.startContainer.tagName;
????????????????document.getElementById("txtStartOffset1").value?=?oRange1.startOffset;
????????????????document.getElementById("txtEndContainer1").value?=?oRange1.endContainer.tagName;
????????????????document.getElementById("txtEndOffset1").value?=?oRange1.endOffset;
????????????????document.getElementById("txtCommonAncestor1").value?=?oRange1.commonAncestorContainer.tagName;
????????????????document.getElementById("txtStartContainer2").value?=?oRange2.startContainer.tagName;
????????????????document.getElementById("txtStartOffset2").value?=?oRange2.startOffset;
????????????????document.getElementById("txtEndContainer2").value?=?oRange2.endContainer.tagName;
????????????????document.getElementById("txtEndOffset2").value?=?oRange2.endOffset;
????????????????document.getElementById("txtCommonAncestor2").value?=?oRange2.commonAncestorContainer.tagName;
????????????}
????????</script>
????</head>
????<body><p?id="p1"><b>Hello</b>?World</p>
????????<input?type="button"?value="Use?Ranges"?onclick="useRanges()"?/>????????
????????<table?border="0">
????????<tr>
????????????<td>
????????????????<fieldset>
????????????????????<legend>oRange1</legend>
????????????????????Start?Container:?<input?type="text"?id="txtStartContainer1"?/><br?/>
????????????????????Start?Offset:?<input?type="text"?id="txtStartOffset1"?/><br?/>
????????????????????End?Container:?<input?type="text"?id="txtEndContainer1"?/><br?/>
????????????????????End?Offset:?<input?type="text"?id="txtEndOffset1"?/><br?/>
????????????????????Common?Ancestor:?<input?type="text"?id="txtCommonAncestor1"?/><br?/>????
????????????????</fieldset>
????????????</td>
????????????<td>
????????????????<fieldset>
????????????????????<legend>oRange2</legend>
????????????????????Start?Container:?<input?type="text"?id="txtStartContainer2"?/><br?/>
????????????????????Start?Offset:?<input?type="text"?id="txtStartOffset2"?/><br?/>
????????????????????End?Container:?<input?type="text"?id="txtEndContainer2"?/><br?/>
????????????????????End?Offset:?<input?type="text"?id="txtEndOffset2"?/><br?/>
????????????????????Common?Ancestor:?<input?type="text"?id="txtCommonAncestor2"?/><br?/>
????????????????</fieldset>
????????????</td>
????????</tr>
????????</table>
????????<p><strong>Note:</strong>?This?example?uses?DOM?ranges?and?will?only?work?in?browsers?that?support?DOM?ranges.?This?example?will?fail?in?Internet?Explorer.</p>
????</body>
</html>
(4)復雜選區
通過setStart和setEnd來實現復雜選區,兩個方法都接受兩個參數:節點引用和偏移量。
(5)與范圍對象的交互
<1>deleteContents(),刪除范圍內容
<2>extractContents,與deleteContents()相似,只不過返回被刪除的文檔碎片
<3>cloneContents(),創建范圍內容副本
<4>surroundContents(node),插入包圍范圍的內容
<5>insertNode(node),在選區開頭插入節點
<6>cloneRange(),復制范圍
<7>detach(),釋放系統資源
<8>compareBoundaryPoints()方法,比較范圍,兩個參數,一個比較規則(Range.START_START,Range.START_TO_END,Range.END_TO_START,Range.END_TO_END),一個是比較的范圍引用
2.IE中的范圍
IE的范圍并不標準,主要用來處理文本節點,調用<body/>,<button/>,<input/>,<textarea>節點的createTextRange方法來創建范圍,建議用document.body.createTextRange()來創建,因為其他元素創建的范圍僅能用于它們內部。
(1)簡單選區:
同樣以下面這段代碼為例子:
<p?id="p1"><b>hello</b>world</p>
要選擇hello,可以使用:
var?oRange=document.body.createTextRange();
oRange.findText("hello");
findText方法還可以接受第2個參數,如oRange.findText("hello",1);將選擇hello之后再次找到的hello文本節點。
與DOM中的selectNode方法最相似的是IE的moveToElementText()方法,比如我們要選中p1節點以及它的所有子節點:
var?oRange=document.body.createTextRange();
var?oP1=document.getElementById("p1');
oRange.moveToElementText(oP1);
alert(oP1.htmlText);
另外,oRange.parentElement()返回選區的父節點。
(2)復雜選區:
move(),moveStart(),moveEnd(),expand()方法實現復雜選區,這些方法都接受兩個參數:移動的單位("character","word","sentence","textedit")和移動的單位的個數。
(3)與范圍交互
<1>text屬性,比如oRange.text="hello";
<2>pasteHTML(),插入HTMl代碼,比如oRange.pasteHTML("<em>test</em>");
<3>duplicate(),復制范圍
<4>compareEndPoints() 方法,比較范圍,第一個參數也是比較規則("StartToStart","StartToEnd,EndToStart","EndToEnd")和比較的范圍引用。也可以通過isEqual()和isRange()方法來比較。
3.范圍的常見應用,比如搜索引擎中,搜索出來的鏈接中的關鍵字用特別的顏色包圍起來,另外就是網頁廣告比較常用。