HTML5新添加了许多语义标签与功能标签。虽然我们可以通过document.getElementById,document.getElementsByTagName选择到它们,但在复制节点时出现问题了。本该出现的innerHTML的地方,变成空字符串……
<!DOCTYPE HTML> <html> <head> <title>cloneNode by 司徒正美</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script> window.onload = function(){ alert(document.getElementById("ee").cloneNode(true).innerHTML);//IE678弹出空字符串 } </script> </head> <body> <nav id="ee">111</nav> </body> </html>
因此我们要复制时,需要区别对待它们,这先决条件是怎么识别它们。
下面是个小测试,从各浏览器的日志的不同之处遴选方案:
window.onload = function(){ var test = document.createElement("nav"); console.log(test.outerHTML); console.log(test.tagName); console.log(Object.prototype.toString.call(test)); }
结果如下
IE9 日志: 日志: nav 日志: [object HTMLUnknownElement] IE9的IE8模式 日志: 日志: nav 日志: [object Object] IE9的IE7模式 日志: 日志: nav 日志: [object Object] IE8 日志: 日志: nav 日志: [object Object] IE7 日志: 日志: nav 日志: [object Object] FF12 NAV [object HTMLElement] chrome18 NAV [object HTMLElement] opera11 NAV [object HTMLElement] safari5 NAV [object HTMLElement]
有趣的是,如果搞了一个不是HTML5的新标签,opera,chrome, FF对元素的toString不约而同都是[object HTMLUnknownElement]。但我们这里只谈IE的情况,IE显然当作是插入一个XML元素了。因此我们只判定其有没有outerHTML(FF11才支持outerHTML),outerHTML是不是以“
下面是我框架复制节点的代码:
var div = document.createElement( "div" );//缓存parser,防止反复创建 function shimCloneNode( outerHTML, tree ) { tree.appendChild(div); div.innerHTML = outerHTML; tree.removeChild(div); return div.firstChild; } var unknownTag = "<?XML:NAMESPACE" function cloneNode( node, dataAndEvents, deepDataAndEvents ) { var bool //!undefined === true; //这个判定必须这么长:判定是否能克隆新标签,判定是否为元素节点, 判定是否为新标签 if(!support.cloneHTML5 && node.outerHTML){//延迟创建检测元素 var outerHTML = document.createElement(node.nodeName).outerHTML; bool = outerHTML.indexOf( unknownTag ) // !0 === true; } var neo = !bool? shimCloneNode( node.outerHTML, document.documentElement ): node.cloneNode(true), src, neos, i; //support.cloneHTML5: DOC.createElement("nav").cloneNode( true ).outerHTML !== "<:nav></:nav>", //…… }
有兴趣可以到我的github上转一转。