innerHTML 插入 script 脚本正确执行的处理方式
为什么80%的码农都做不了架构师?>>>
很多时候需要通过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
innerHTML 插入 script 脚本正确执行的处理方式相关推荐
- coos.$script 动态插入脚本并执行的方法
/** * 动态插入脚本并执行 * @param scriptStr * @param el dom元素对象或ID 可以不传入 * @exsample coos.$script(&qu ...
- 动态引入js只能生效一次_干货丨动态插入的script脚本执行时间
在一些场景我们会动态插入script标签加载js. 譬如某个js文件不是很重要,并不是整个页面需要的脚本,可能只是某个功能需要的,这个功能可能是用户点击了某个按钮才触发,入口比较深.且和你页面本身的结 ...
- 动态引入js只能生效一次_动态插入的script脚本执行时间
在一些场景我们会动态插入script标签加载js. 譬如某个js文件不是很重要,并不是整个页面需要的脚本,可能只是某个功能需要的,这个功能可能是用户点击了某个按钮才触发,入口比较深.且和你页面本身的结 ...
- 运维经验分享(六)-- 深究crontab不能正确执行Shell脚本的问题(二)
运维经验分享作为一个专题,目前共7篇文章 <运维经验分享(一)-- Linux Shell之ChatterServer服务控制脚本> <运维经验分享(二)-- Linux Shell ...
- 运维经验分享(三)-- 解决Ubuntu下crontab不能正确执行脚本的问题
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://dgd2010.blog.51cto.com/1539422/1676490 运维 ...
- 让SH/BAT脚本定位到运行目录的相对位置,实现其脚本可在任意运行目录下被正确执行...
让SH/BAT脚本定位到运行目录的相对位置 实现其脚本可在任意运行目录下被正确执行 在Linux下的bash脚本 #!/bin/bash cd `dirname $0` 在Windows下的BAT脚本 ...
- 如何在 Shell 脚本中执行语法检查调试模式
我们开启了 Shell 脚本调试系列文章,先是解释了不同的调试选项,下面介绍如何启用shell调试模式. 写完脚本后,建议在运行脚本之前先检查脚本中的语法,而不是查看它们的输出以确认它们是否正常工作. ...
- 在 Shell 脚本中执行语法检查调试模式
文章目录 shell 脚本调试系列 概述 启用 verbose 调试模式 在 Shell 脚本中启用语法检查调试模式 通过修改脚本的首行来启用脚本检查 内置的 set 命令来在脚本中启用调试模式 sh ...
- 如何使用Elasticsearch groovy script脚本更新数据
2019独角兽企业重金招聘Python工程师标准>>> 如何使用Elasticsearch groovy script脚本更新数据 博客分类: 搜索引擎,爬虫 今天细说一下elast ...
- 【Android】iOS开发中xconfig和script脚本的使用
利用Xcode进行开发时需要进行很多build setting的设置以便能让项目按照设置的进行编译,同时有时候需要在编译时利用script脚本进行一些设置,本文主要介绍xconfig文件和script ...
最新文章
- xdoj 1144 K叉哈弗曼树
- oauth过滤login_OAuth2AuthenticationProcessingFilter资源认证服务器过滤器
- goland 调试运行路径
- LINQ TO SQL中还是用传统的连接串方式建立DbContext更好些
- Java数组和Arrays类
- Expression Blend实例动画-大坝水位升高演示
- OSS.Common获取枚举字典列表标准库支持
- JSP隐含变量和Spring中Model在EL表达式中的读取顺序
- 杭电1.3.6考试排名
- 大学生使用计算机的情况英语作文,关于网络的大学生英语作文(精选10篇)
- 《Android游戏开发详解》——导读
- 拓端tecdat|python爬虫进行Web抓取LDA主题语义数据分析报告
- 一元钱一瓶汽水,喝完后两个空瓶能换一瓶汽水,问:你有20元钱,可以喝到几瓶汽水?
- 博后招募 | 浙江大学陈华钧教授招聘知识图谱等方向博后及算法工程师
- Vue的一些知识汇总---希望对你有用
- 2018年11月TIOBE编程语言排行榜,Java稳居第一
- 怎样计算两个时间之间的间隔
- 计算机无法准确计算浮点数,浮点数计算异常原因(转)
- JAVA incept_(jsp+servlet)ERP管理系统 - WEB源码|JSP源码/Java|源代码 - 源码中国
- OVS 内核CT实现