JavaScript高级程序设计之DOM之DOM 操作技术之动态脚本第10.2.1讲

10.2 DOM
操作技术
很多时候,DOM 操作都比较简明,因此用JavaScript 生成那些通常原本是用HTML 代码生成的内
容并不麻烦。不过,也有一些时候,操作DOM 并不像表面上看起来那么简单。由于浏览器中充斥着隐

藏的陷阱和不兼容问题,用JavaScript 代码处理DOM 的某些部分要比处理其他部分更复杂一些。

10.2.1
动态脚本
使用<script>元素可以向页面中插入JavaScript 代码,一种方式是通过其src 特性包含外部文件,
另一种方式就是用这个元素本身来包含代码。而这一节要讨论的动态脚本,指的是在页面加载时不存在,
但将来的某一时刻通过修改DOM 动态添加的脚本。跟操作HTML 元素一样,创建动态脚本也有两种方
式:插入外部文件和直接插入JavaScript 代码。
动态加载的外部JavaScript 文件能够立即运行,比如下面的<script>元素:

<script type="text/javascript" src="client.js"></script>

这个<script>元素包含了第9 章的客户端检测脚本。而创建这个节点的DOM 代码如下所示:

var script = document.createElement("script");
script.type = "text/javascript";
script.src = "client.js";
document.body.appendChild(script);

显然,这里的DOM 代码如实反映了相应的HTML 代码。不过,在执行最后一行代码把<script>
元素添加到页面中之前,是不会下载外部文件的。也可以把这个元素添加到<head>元素中,效果相同。
整个过程可以使用下面的函数来封装:

function loadScript(url){
var script = document.createElement("script");
script.type = "text/javascript";
script.src = url;
document.body.appendChild(script);
}
然后,就可以通过调用这个函数来加载外部的JavaScript 文件了:

loadScript("client.js");
加载完成后,就可以在页面中的其他地方使用这个脚本了。问题只有一个:怎么知道脚本加载完成
呢?遗憾的是,并没有什么标准方式来探知这一点。不过,与此相关的一些事件倒是可以派上用场,但
要取决于所用的浏览器,详细讨论请见第13 章。
另一种指定JavaScript 代码的方式是行内方式,如下面的例子所示:

<script type="text/javascript">
function sayHi(){
alert("hi");
}
</script>
从逻辑上讲,下面的DOM 代码是有效的:

var script = document.createElement("script");
script.type = "text/javascript";
script.appendChild(document.createTextNode("function sayHi(){alert('hi');}"));
document.body.appendChild(script);

在Firefox、Safari、Chrome 和Opera 中,这些DOM 代码可以正常运行。但在IE 中,则会导致错误。
IE 将<script>视为一个特殊的元素,不允许DOM 访问其子节点。不过,可以使用<script>元素的
text 属性来指定JavaScript 代码,像下面的例子这样:

var script = document.createElement("script");
script.type = "text/javascript";
script.text = "function sayHi(){alert('hi');}";
document.body.appendChild(script);

经过这样修改之后的代码可以在IE、Firefox、Opera 和Safari 3 及之后版本中运行。Safari 3.0 之前
的版本虽然不能正确地支持text 属性,但却允许使用文本节点技术来指定代码。如果需要兼容早期版
本的Safari,可以使用下列代码:

var script = document.createElement("script");
script.type = "text/javascript";
var code = "function sayHi(){alert('hi');}";
try {
script.appendChild(document.createTextNode("code"));
} catch (ex){
script.text = "code";
}
document.body.appendChild(script);
这里,首先尝试标准的DOM 文本节点方法,因为除了IE(在IE 中会导致抛出错误),所有浏览器
都支持这种方式。如果这行代码抛出了错误,那么说明是IE,于是就必须使用text 属性了。整个过程
可以用以下函数来表示:

function loadScriptString(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);
}

下面是调用这个函数的示例:

loadScriptString("function sayHi(){alert('hi');}");
以这种方式加载的代码会在全局作用域中执行,而且当脚本执行后将立即可用。实际上,这样执行
代码与在全局作用域中把相同的字符串传递给eval()是一样的。


你可能感兴趣的:(JavaScript高级程序设计之DOM之DOM 操作技术之动态脚本第10.2.1讲)