DOM操作技術
很多時候,DOM操作都是比較簡明的,因此用JavaScript生成那些通常原本用HTML代碼生成的內容並不麻煩。不過,也有一些時候,操作DOM並不像表面上看起來那麽簡單,由於瀏覽器中充斥著隱藏的陷阱和不兼容,用JavaScript代碼處理DOM的某些部分要比處理其他部分更復雜一些。
動態腳本
使用<script>元素可以向頁面插入JavaScript代碼,一種是通過雙人床特性包含外部文件,另一種就是用這個元素本身來包含代碼,接下來要說的動態腳本,只的是在頁面加載時不存在,但將來的某一時刻通過修改DOM動態添加的腳本。
var script = document.createElement("script"); script.type = "text/javascript"; script.src = ‘aaa.js‘; document.body.appendChild(script); // 等同於<script text="text/javascript" src =‘aaa.js‘></script>
整個過程可以使用下面的函數來封裝:
function addScript(url){
var script = document.createElement("script");
script.type = "text/javascript";
script.src = url;
document.body.appendChild(script);
}
另一種指定JavaScript代碼的方式是行內方式:
<script text="text/javascript" > function sayHi(){ console.log(‘Hi‘); }
</script>
從邏輯上來講,下面的代碼是有效的:
var script = document.createElement("script"); script.type = "text/javascript"; script.appendChild(document.createTextNode("function sayHi(){console.log(‘Hi‘);}")); document.body.appendChild(script);
上面的DOM代碼在其他瀏覽器中可正常運行,但在IE中,則會報錯,因為IE將<script>視為一個特殊的元素,不允許DOM訪問其子節點,不過可以使用<script>元素的text屬性來指定JavaScript代碼:
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "function sayHi(){console.log(‘Hi‘);}";
document.body.appendChild(script);
這樣修改之後的代碼可以在IE及其他瀏覽器中運行,但Safari3.0之前的版本不能正確的支持text屬性,因此,如果需要兼容早期的Safari,可以這樣修改:
var script = document.createElement("script");
script.type = "text/javascript";
var code = "function sayHi(){console.log(‘Hi‘);}";
try{
script.appendChild(document.createTextNode(code));
}catch(ex){
script.text = code;
}
document.body.appendChild(script);
整個過程可以使用下面的函數來封裝:
function addScriptCode(code){
var script = document.createElement("script");
script.type = "text/javascript";
try{
script.appendChild(document.createTextNode(code));
}catch(ex){
script.text = code;
}
document.body.appendChild(script);
}
動態樣式
能夠把CSS樣式包含到HTML頁面中元素有兩個,其中,<link>元素用於包含來自外部的文件,而<style>元素用於指定嵌入的樣式。與動態腳本類似,動態樣式是值在頁面剛加載時不存在的樣式,動態樣式是在頁面加載完成後動態添加到頁面中的。
var link = document.createElement(‘link‘); link.rel = "stylesheet"; link.type = "text/css"; link.href = "style/css";
var head = document.getElementsByTagName("head")[0]; head.appendChild(link); // 等同於 <link rel="stylesheet" href="style.css">
和script不同的是,必須將<link>元素添加到<head>而不是<body>元素中,才能保證在所有瀏覽器中的行為一致,整個過程可以用以下的函數來表示:
function addStyle(url){
var link = document.createElement("link");
link.rel = "stylesheet";
link.type = "text/css";
link.href = url;
var head = document.getElementsByTagName("head")[0];
head.appendChild(link);
}
另一種定義樣式的方式是使用<style>元素包含嵌入式CSS。
<style type="text/css"> body{ color:red; } </style>
按照相同的邏輯,下列DOM代碼應該是有效的:
var style = document.createElement("style");
style.type = "text/css";
style.appendChild(document.createTextNode("body{color:red}"));
var head = document.getElementsByTagName("head")[0];
head.appendChild(style);
事實上,上面的代碼在其他的瀏覽器中可以正常運行,但在IE中會報錯,同<style>一樣,IE將<style>視為一個特殊的節點,不允許訪問其子節點,解決這個問題的辦法就是訪問元素的styleSheet屬性,該屬性有一個CSSText屬性,可以接受CSS代碼。
var style = document.createElement("style");
style.type = "text/css";
try{
style.appendChild(document.createTextNode("body{color:red}"));
}catch(ex){
style.styleSheet.cssText = "body{color:red}";
}
var head = document.getElementsByTagName("head")[0];
head.appendChild(style);
同理,上面的整個過程可以使用下面的函數來封裝:
function addStyleCss(css){
var style = document.createElement("style");
style.type = "text/css";
try{
style.appendChild(document.createTextNode(css));
}catch(ex){
style.styleSheet.cssText = css;
}
var head = document.getElementsByTagName("head")[0];
head.appendChild(style);
}
需要註意的是,如果專門針對IE編寫代碼,需小心使用styleSheet.cssText 屬性,在重用同一個<style>元素並再次設置這個屬性時,有可能會導致瀏覽器崩潰,同樣,將CSSText屬性設置為空字符串也可能導致瀏覽器崩潰。
DOM操作技術