Skip to content

Instantly share code, notes, and snippets.

@jonathantneal
Created November 8, 2011 04:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jonathantneal/1347013 to your computer and use it in GitHub Desktop.
Save jonathantneal/1347013 to your computer and use it in GitHub Desktop.
cloneNode.js
(function (win, doc) {
// clone element with outerHTML
function cloneNodeWithHTML(node) {
var xEl = doc.createElement('x-element');
xEl.innerHTML = node.outerHTML || node.nodeValue;
return xEl.firstChild;
}
// match textnodes
function matchInnerNodes (nodeA, nodeB) {
// get childNodes Length
var nodeAChildNodesLength = nodeA.childNodes.length, nodeBChildNodesLength = nodeB.childNodes.length, i;
// match values
if (!supportsValues && 'value' in nodeA && nodeA.value !== nodeB.value) nodeB.value = nodeA.value;
// restore missing text nodes
if (!supportsTextNodes && nodeAChildNodesLength !== nodeBChildNodesLength)
for (i = 0, nodeB.innerHTML = ''; i < nodeAChildNodesLength && nodeB.appendChild(doc.createTextNode(nodeA.childNodes[i].nodeValue)); ++i);
else for (i = 0; i < nodeAChildNodesLength && arguments.callee(nodeA.childNodes[i], nodeB.childNodes[i]); ++i);
// return node
return nodeB;
}
// test clone node abilities
var testNode = doc.createElement('textarea');
testNode.appendChild(doc.createTextNode('a')); testNode.appendChild(doc.createTextNode('b'));
testNode.value += 'c';
testCloneNode = testNode.cloneNode(true);
// detect cloning support
var supportsValues = testCloneNode.value === 'abc', supportsTextNodes = testCloneNode.childNodes.length === 2;
// clone node function
win.cloneNode = supportsTextNodes ? function (node) {
return matchInnerNodes(node, node.cloneNode(true));
} : function (node) {
return ('innerHTML' in node) ? matchInnerNodes(node, cloneNodeWithHTML(node)) : node.cloneNode(true);
};
})(this, document);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment