innerHTML 插入 <script> 脚本正确执行的处理方式

本文介绍了解决通过innerHTML动态插入的JavaScript代码无法执行的问题。提供了两种方法:一种是利用IE浏览器特性确保脚本执行;另一种是通过创建脚本元素并管理其生命周期来实现跨浏览器兼容性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

很多时候需要通过innerHTML动态插入javascript代码到指定的div中,或者通过ajax请求回来的内容里面包含javascript代码,然后把该代码插入指定的div中,但是插入后的script却无法执行。 

原因:直接通过innerHTML动态嵌入的script,浏览器会当做普通的文本,不会当作SCRIPT节点维护到DOM里面,所以调用的时候找不到。 

搜索网络上的一些文章之后,得到一个新的方法,是利用ie本身的机制来执行的。即当节点被移除的时候,ie会重新解析节点内部的html,有脚本则会执行相关的脚本,不过这里面的脚本必须设置defer属性才可以。新方法如下:

/**  
 * 描述:跨浏览器的设置 innerHTML 方法 (允许插入的 HTML 代码中包含 script 和 style )
 * 作者:kenxu <ken@ajaxwing.com>  
 * 日期:2006-03-23  
 * 参数:  
 *    el: 合法的 DOM 树中的节点  
 *    htmlCode: 合法的 HTML 代码  
 * 经测试的浏览器:ie5+, firefox1.5+, opera8.5+  
 * 此方法充分利用了浏览器自身的特性,执行效率高,兼容性好。唯一的缺点就是脚本中不能包含 document.write。
 */
var setInnerHTML = function (el, htmlCode) {
	var ua = navigator.userAgent.toLowerCase();
	if (ua.indexOf('msie') >= 0 && ua.indexOf('opera') < 0) {
		htmlCode = '<div style="display:none">for IE</div>' + htmlCode;
		htmlCode = htmlCode.replace(/<script([^>]*)>/gi,'<script$1 defer>');
		el.innerHTML = htmlCode;
		el.removeChild(el.firstChild);
	} else {
		var el_next = el.nextSibling,
			el_parent = el.parentNode;
		el_parent.removeChild(el);
		el.innerHTML = htmlCode;
		if (el_next) {
			el_parent.insertBefore(el, el_next)
		} else {
			el_parent.appendChild(el);
		}
	}
}
此方法充分利用了浏览器自身的特性,执行效率高,兼容性好。 唯一的缺点就是脚本中不能包含 document.write。

还有另外一个方法如下:

/* innerhtml.js
 * Copyright Ma Bingyao <andot@ujn.edu.cn>
 * Version: 1.9
 * LastModified: 2006-06-04
 * This library is free.  You can redistribute it and/or modify it.
 * http://www.coolcode.cn/?p=117
 */
var global_html_pool = [];
var global_script_pool = [];
var global_script_src_pool = [];
var global_lock_pool = [];
var innerhtml_lock = null;
var document_buffer = "";
function set_innerHTML(obj_id, html, time) {
	if (innerhtml_lock == null) {
		innerhtml_lock = obj_id;
	} else if (typeof(time) == "undefined") {
		global_lock_pool[obj_id + "_html"] = html;
		window.setTimeout("set_innerHTML('" + obj_id + "', global_lock_pool['" + obj_id + "_html']);", 10);
		return;
	} else if (innerhtml_lock != obj_id) {
		global_lock_pool[obj_id + "_html"] = html;
		window.setTimeout("set_innerHTML('" + obj_id + "', global_lock_pool['" + obj_id + "_html'], " + time + ");", 10);
		return;
	}
	function get_script_id() {
		return "script_" + (new Date()).getTime().toString(36)
		 + Math.floor(Math.random() * 100000000).toString(36);
	}
	document_buffer = "";
	document.write = function (str) {
		document_buffer += str;
	}
	document.writeln = function (str) {
		document_buffer += str + "\n";
	}
	global_html_pool = [];
	var scripts = [];
	html = html.split(/<\/script>/i);
	for (var i = 0; i < html.length; i++) {
		global_html_pool[i] = html[i].replace(/<script[\s\S]*$/ig, "");
		scripts[i] = {
			text : '',
			src : ''
		};
		scripts[i].text = html[i].substr(global_html_pool[i].length);
		scripts[i].src = scripts[i].text.substr(0, scripts[i].text.indexOf('>') + 1);
		scripts[i].src = scripts[i].src.match(/src\s*=\s*(\"([^\"]*)\"|\'([^\']*)\'|([^\s]*)[\s>])/i);
		if (scripts[i].src) {
			if (scripts[i].src[2]) {
				scripts[i].src = scripts[i].src[2];
			} else if (scripts[i].src[3]) {
				scripts[i].src = scripts[i].src[3];
			} else if (scripts[i].src[4]) {
				scripts[i].src = scripts[i].src[4];
			} else {
				scripts[i].src = "";
			}
			scripts[i].text = "";
		} else {
			scripts[i].src = "";
			scripts[i].text = scripts[i].text.substr(scripts[i].text.indexOf('>') + 1);
			scripts[i].text = scripts[i].text.replace(/^\s*<\!--\s*/g, "");
		}
	}
	var s;
	if (typeof(time) == "undefined") {
		s = 0;
	} else {
		s = time;
	}
	var script,add_script, remove_script;
	for (var i = 0; i < scripts.length; i++) {
		var add_html = "document_buffer += global_html_pool[" + i + "];\n";
		add_html += "document.getElementById('" + obj_id + "').innerHTML = document_buffer;\n";
		script = document.createElement("script");
		if (scripts[i].src) {
			script.src = scripts[i].src;
			if (typeof(global_script_src_pool[script.src]) == "undefined") {
				global_script_src_pool[script.src] = true;
				s += 2000;
			} else {
				s += 10;
			}
		} else {
			script.text = scripts[i].text;
			s += 10;
		}
		script.defer = true;
		script.type = "text/javascript";
		script.id = get_script_id();
		global_script_pool[script.id] = script;
		add_script = add_html;
		add_script += "document.getElementsByTagName('head').item(0)";
		add_script += ".appendChild(global_script_pool['" + script.id + "']);\n";
		window.setTimeout(add_script, s);
		remove_script = "document.getElementsByTagName('head').item(0)";
		remove_script += ".removeChild(document.getElementById('" + script.id + "'));\n";
		remove_script += "delete global_script_pool['" + script.id + "'];\n";
		window.setTimeout(remove_script, s + 10000);
	}
	var end_script = "if (document_buffer.match(/<\\/script>/i)) {\n";
	end_script += "set_innerHTML('" + obj_id + "', document_buffer, " + s + ");\n";
	end_script += "}\n";
	end_script += "else {\n";
	end_script += "document.getElementById('" + obj_id + "').innerHTML = document_buffer;\n";
	end_script += "innerhtml_lock = null;\n";
	end_script += "}";
	window.setTimeout(end_script, s);
}

转载于:https://my.oschina.net/jsan/blog/168621

### 如何使用 JavaScript 的 `document.write` 方法在网页中输出包含标题和列表的 HTML 结构 `document.write` 是 JavaScript 中的一个方法,用于向 HTML 输出流写入内容。通过该方法,可以动态生成并插入 HTML 标记到页面中[^2]。下面是一个示例代码,展示如何使用 `document.write` 方法在网页中输出一个包含标题和列表的结构: ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Document Write 示例</title> <script> document.write("<h1>这是标题</h1>"); // 输出标题标签 <h1> document.write("<ul>"); // 开始无序列表 document.write("<li>列表项 1</li>"); // 列表项 1 document.write("<li>列表项 2</li>"); // 列表项 2 document.write("<li>列表项 3</li>"); // 列表项 3 document.write("</ul>"); // 结束无序列表 </script> </head> <body> </body> </html> ``` 上述代码将生成一个包含标题和列表的 HTML 页面。`document.write` 方法会直接将指定的字符串作为 HTML 内容写入到文档中[^4]。 需要注意的是,当页面加载完成后再次调用 `document.write` 方法时,可能会覆盖整个文档的内容[^1]。因此,在实际开发中需要谨慎使用此方法,尤其是在用户交互后动态生成内容时,推荐使用 DOM 操作(如 `innerHTML` 或 `appendChild`)来替代 `document.write`。 此外,如果需要换行显示内容,不能直接使用 `\n`,而应使用 HTML 的 `<br>` 标签来实现换行效果[^3]。 ### 注意事项 - `document.write` 方法仅适用于同步脚本执行环境。如果在异步脚本中使用,可能会导致页面内容被清空。 - 在现代 Web 开发中,建议避免使用 `document.write`,因为它可能导致性能问题以及维护困难。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值