innerhtml 动态添加 html 代码和脚本,给某个元素的 innerHTML 赋值, 并使得值中的 js 代码有效且兼容多个浏览器,很棒的一个方法
Javascript 是一种由 Netscape 的 LiveScript 发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如 Perl,遗留的速度问题,为客户提供更流畅的浏览效果。
症状:给某个元素的 innerHTML 设置值时,如果提供的 HTML 代码中包含 js 脚本,很多时候这些脚本无效,或者在某种浏览器上有效,但在其它浏览器上无效。
原因:不同浏览器对插入 innerHTML 中的脚本有不同的处理方法。经过实践,归纳如下:
对于 IE,首先, script 标签必须带 defer 属性,其次, 在插入时刻,innerHTML 的所属节点必须在 DOM 树中.
对于 Firefox 和 Opera,在插入时刻,innerHTML 的所属节点不可以在 DOM 树中。
根据上面结论,给出通用的设置 innerHTML 方法:
- /*
- * 描述:跨浏览器的设置 innerHTML 方法
- * 允许插入的 HTML 代码中包含 script 和 style
- * 参数:
- * el: DOM 树中的节点,设置它的 innerHTML
- * htmlCode: 插入的 HTML 代码
- * 经测试的浏览器:ie5+, firefox1.5+, opera8.5+
- */
- var set_innerHTML = function (el, htmlCode)
- {var ua = navigator.userAgent.toLowerCase();
- if (ua.indexOf('msie') >= 0 && ua.indexOf('opera') < 0)
- {htmlCode = 'for IE' + htmlCode;
- htmlCode = htmlCode.replace(/]*)>/gi,'');
- el.innerHTML = htmlCode;
- el.removeChild(el.firstChild);
- }
- else
- {var el_next = el.nextSibling;
- var 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);
- }
- }
上面的代码还有一个问题:如果插入的 HTML 代码中包含 document.write 语句,那么就会破坏整个页面。对于这种情况,可以通过重新定义 document.write 来避免。代码如下:
- /*
- 描述:重定义 document.write 函数.
- 避免在使用 set_innerHTML 时,插入的 HTML 代码中包含 document.write 语句,导致原页面受到破坏。
- */
- document.write = function(){
- var body = document.getElementsByTagName('body')[0];
- for (var i = 0; i < arguments.length; i++) {
- argument = arguments[i];
- if (typeof argument == 'string') {
- var el = body.appendChild(document.createElement('div'));
- set_innerHTML(el, argument)
- }
- }
- }
来源: