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属性设置为空字符串也可能导致浏览器崩溃。