`

解决innerHTML包含的js代码不能被执行的问题

阅读更多
   今天我写了个js弹出模态对话框,这个模态对话框能直接显示一个html或者是url的文本内容,因为加入我需要在对话框里面显示比较复杂的布局的话直接用字符串来做是很麻烦且很难修改的。各方面都比较完善了,但是今天,在我想用这个对话框加载一个页面的时候发现了新问题。

在我的要加载的页面里面有和用户的交互过程,这是用js实现的,我把这个页面加载到我的模态对话框里面,页面显示完全正确,可是在测试交互功能的时候发现js没有响应。我用firebug插件查看,发现里面是有这段js代码的,但怎么执行不了呢。

于是我将这段js代码写在了调用模态对话框的页面,这样交互功能恢复正常了。原来使用innerHTML获得的js代码是不能被执行的,js只有在页面初次加载的时候才有效。

网上有很多种解决的方法,有用iframe实现的,有通过浏览器的特性实现的,但这些都通通不是我喜爱的方法,要我使用iframe,那还不如我把这个问题放着,每次都把被加载页面的js拷贝到调用页面算了。

不过还是找到了一个比较完美的方法,这个方法不仅没有使用限制,而且还是跨浏览器的。我需要的就是这样的代码。有时候发现要在网上找到好的代码简直比登天还难,因为大部分都是copy的,你可以看到一篇不知所云的垃圾文章被copy了好多份。同样你也可以看到好多精品文章被copy了好多份而找不到出处。不过话说回来,自己写文章确实需要很大的耐心,要写一篇别人都能看懂的文章起码需要40分钟,不然你就是在制造垃圾。所以看到好的文章注明出处是一种美德。这篇文章的出处是 http://jcodecraeer.com/a/jquery_js_ajaxjishu/2012/0625/278.html 谢谢转载,可以不带链接但别破坏了我的代码格式,不然别人没法看啊。

说正题。这个方法只需调用一个函数set_innerHTML(obj_id, html, time);

set_innerHTML('要插入innerhtml的ID名称', '要插入的代码');time参数可以忽略,我急于实现功能就没去看实现的细节了。

以下是代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/* innerhtml.js
* Version: 1.9
* LastModified: 2006-06-04
* This library is free. You can redistribute it and/or modify it.
*
*/
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);
}

有了这个方法,原来这样写

1
document.getElementById("sch_nameArea").innerHTML= text;

的地方就可以写成这样

1
set_innerHTML('sch_nameArea',text);

值得注意的是,这个代码用到了一些全局变量,

1
2
3
4
5
6
var global_html_pool = [];
var global_script_pool = [];
var global_script_src_pool = [];
var global_lock_pool = [];
var innerhtml_lock = null;
var document_buffer = "";

至少你应该尽可能的避免和这些全局变量冲突。决绝全局变量冲突的良策貌似是使用闭包,最近正在学习这些概念,如果你是一个严谨的人,我觉得有必要重写这段代码,让它更灵活和稳定。

最后向写这段代码的济南大学马秉尧老师致敬!

分享到:
评论

相关推荐

    使用ajax加载的页面中包含的javascript的解决方法

    1、【使用iframe】 在需要加载的页面中添加一个iframe,如下 代码如下: &lt;...如:xxx[removed]=XMLHttp取得的数据 这样是不会执行JS,添加eval方法就ok了:如:xxx[removed]=eval&#40;返XMLHttp取得的数据&#41;

    用AJAX返回HTML片段中的JavaScript脚本

    这是AJAX开发中很常见的问题,如果你不是一直在用JavaScript框架做开发,相信你早就发现这个问题了。本文分析了两个解决办法,其中一个是讲解jQuery框架的实现。 一、 问题描述 下面举个简单的例子,演示问题所在。...

    innerHTML在Mozilla Firefox和Opera下执行的一个特例情况。

    是在CSDN论坛看到的一个问题,平常我也没有注意,或者说没有这样用吧。看代码  改动两个文本框里的值,把这个容器的innerHTML赋值给d2 foo() [Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]不是预期的结果吧?...

    javascript函数的解释

    48.在老的浏览器中不执行此JS:&lt;!-- //--&gt; 49.引用一个文件式的JS:&lt;script type="text/javascript" src="aaa.js"&gt; 50.指定在不支持脚本的浏览器显示的HTML:&lt;noscript&gt;&lt;/noscript&gt; 51.当超链和ONCLICK事件都有时,则老...

    jQuery基础选择器练习题

    JQ 选择器大全包含:基本选择器,层级选择器,层级函数,过滤选择器,内容选择器,可见选择器,jq中显示相关的函数,属性选择器,子元素选择器,表单选择器。里面的练习题可以拿来练手

    用JavaScript实现用一个DIV来包装文本元素节点

    当你的应用需要依赖某个特定的JavaScript类库时,你无意中总会试图解决某些类库自身的问题,而不是语言的问题。就比如当我试图将文本(可能也包含HTML元素)用一个DIV元素包起来时。假设有以下HTML: This is some text ...

    jQuery详细教程

    jQuery 使用名为 noConflict() 的方法来解决该问题。 var jq=jQuery.noConflict(),帮助您使用自己的名称(比如 jq)来代替 $ 符号。 亲自试一试 结论 由于 jQuery 是为处理 HTML 事件而特别设计的,那么当您遵循...

    js使用小技巧

    Javascript小技巧一箩筐 事件源对象 event.srcElement.tagName event.srcElement.type 捕获释放 event.srcElement.setCapture(); event.srcElement.releaseCapture(); 事件按键 event.keyCode ...

    【卷一/共两卷】AJAX实战pdf高清版90M

    8.2 JavaScript的执行速度 8.2.1 测定应用时间的艰难方式 8.2.2 使用Venkman性能分析器 8.2.3 优化Ajax应用的执行速度 8.3 JavaScript的内存使用量 8.3.1 避免内存泄漏 8.3.2 Ajax的特殊考虑因素 8.4考虑性能的设计 ...

    JavaScript Table行定位效果

    第一个问题是fixed的tr在ie7中不能进行定位,而且td在定位后并不能保持在表格中的布局,这样在原表格插tr就没意义了。 ps:fixed的相关应用可参考仿LightBox效果。 最后我用的方法是新建一个table,并把源tr克隆到...

    postscribe:即使使用[removed]也异步编写javascript

    远程脚本(尤其是广告)在加载页面时阻止页面执行任何其他操作。 它们对加载时间的贡献很大,这。 异步广告不会阻止页面,可以在核心内容( 之后投放。 为什么异步投放广告如此困难? 因为它们可能包含对[removed]...

    XML轻松学习手册--XML肯定是未来的发展趋势,不论是网页设计师还是网络程序员,都应该及时学习和了解

    在XML文档中任何的差错,都会得到同一个结果:网页不能被显示。各浏览器开发商已经达成协议,对XML实行严格而挑剔的解析,任何细小的错误都会被报告。你可以将上面的myfile.xml修改一下,比如将改为,然后用IE5直接...

    基于J2EE框架的个人博客系统项目毕业设计论文(源码和论文)

    更好交流,在信息时代人们通过个人空间沟通也用来但不能在自己的博客主页面中提交评论和留言。。这样在本系统中就可以为博友提供更多的个人色彩。在管理页面中添加和删除友情连接。这样博友可以在自己空间中快速定位...

Global site tag (gtag.js) - Google Analytics