Edited on October 7th: I realized after the original post that the code provided was not entirely correct. Specifically, it ignored CDATA values. Methods below have been updated to reflect that fix.
The logic for extracting the text values is extracted into a separate function:
function getTextNodes(node){ return $(node).contents().filter(function(){ return ( ((this.nodeName=="#text" && this.nodeType=="3") || this.nodeType=="4") // text node, or CDATA node && ($.trim(this.nodeValue.replace("\n","")) !== "") // not empty ); }); }
This method first gets the contents of the node (all children, including child nodes, text nodes, comments), and then filters it down to only what it promises to deliver. It ignores text nodes which contain only blanks, only newlines, or some combination of only those two.
Then, the set/get functions become:
function getNodeValue(node){ var $textNodes = getTextNodes(node); textValue = ($textNodes[0]) ? $.trim($textNodes[0].textContent) : ""; return textValue; }
And since we’re at it, here’s a way to set it:
function setNodeValue(node, value){ var $textNodes = getTextNodes(node); if ($textNodes.get(0)) $textNodes.get(0).nodeValue = value; else node["textContent"] = value; }
One other change to note (bolded above, in setNodeValue()) is that if a specific node has no prior text value, instead of setting it using node.textContent, we’re setting it with node[“textContent”] since Internet Explorer doesn’t like the first method (property doesn’t exist when blank). This is good practice since its generally safer.