解决innerHTML包含的js代码不能被执行的问题
在我的要加载的页面里面有和用户的交互过程,这是用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 = "" ; |
至少你应该尽可能的避免和这些全局变量冲突。决绝全局变量冲突的良策貌似是使用闭包,最近正在学习这些概念,如果你是一个严谨的人,我觉得有必要重写这段代码,让它更灵活和稳定。
最后向写这段代码的济南大学马秉尧老师致敬!