Only Internet Explorer seems to have the element property: canHaveHtml
(MSDN, Dottoro). I can't seem to find anything in other browsers to emulate it, other than using a regex with a list of tagnames. Is there a way to determine this in Chrome, Firefox etc?
For example is there a way of checking for the innerHTML
property and is this 100% equivalent?
Definition and UsageThe childNodes property returns a collection (list) of an elements's child nodes. The childNodes property returns a NodeList object. The childNodes property is read-only. childNodes[0] is the same as firstChild .
To get the children of an element, you use the childNodes property of the element. How it works: First, select the element whose id is container using the querySelector() method. Then, use the childNodes property to get the children of the container elements.
The children property returns a collection of an element's child elements.
I believe there is no specifications about that:
http://www.w3.org/TR/domcore/#concept-node-append
For instance, in Firefox, Chrome and Safari, you can actually add nodes to elements like <input>
for example:
var input = document.createElement("input");
var div = document.createElement("div");
div.textContent = 'hello';
console.log(input.outerHTML, input.childNodes.length);
input.appendChild(div);
console.log(input.outerHTML, input.childNodes.length);
They're just not rendered. But they're considered children of the input
node in both case. In case of Firefox the outerHTML
is not changed, only the childNodes
length reports 1, in case of Chrome and Safari the outerHTML
changes from <input>
to <input></input>
.
In Firefox, as opposite of Safari and Chrome, innerHTML
returns actually the children's HTML, even if it's not rendered and is not returned in outerHTML
.
Update:
As @Bergi pointed out in @MårtenWikström answer, approaches like the previous I made doesn't really works well on element that can have content, like textarea
, or even title
, but not HTML content. Therefore, a better canHaveHTML
could be something like that:
// Improving the `canHaveHTML` using `canHaveChildren`,
// using the approach shown by Mårten Wikström
function canHaveChildren(node) {
// Uses the native implementation, if any.
// I can't test on IE, so maybe it could be worthy to never use
// the native implementation to have a consistent and controlled
// behaviors across browsers. In case, just remove those two lines
if (node && node.canHaveChildren)
return node.canHaveChildren();
// Returns false if it's not an element type node; or if it has a end tag.
// Use the `ownerDocument` of the `node` given in order to create
// the node in the same document NS / type, rather than the current one,
// useful if we works across different windows / documents.
return node.nodeType === 1 && node.ownerDocument
.createElement(node.tagName).outerHTML.indexOf("></") > 0;
}
function canHaveHTML(node) {
// See comment in `canHaveChildren` about native impl.
if (node && node.canHaveHTML)
return node.canHaveHTML();
// We don't bother to create a new node in memory if it
// can't have children at all
if (!canHaveChildren(node))
return false;
// Can have children, then we'll check if it can have
// HTML children.
node = node.ownerDocument.createElement(node.tagName);
node.innerHTML = "<b></b>";
// if `node` can have HTML children, then the `nodeType`
// of the node just inserted with `innerHTML` has to be `1`
// (otherwise will be likely `3`, a textnode).
return node.firstChild.nodeType === 1;
}
Tested in Firefox, Chrome and Safari; that should cover all the nodes and all the scenarios.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With