Saul
Saul

Reputation: 18041

Why do Dojo DOM functions end up with different results on IE?

In short, a script using the Dojo framework ends up with different results on IE.

Here is a sample page demonstrating the issue:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.7.3/dojo/dojo.js"></script>
<script type="text/javascript">

dojo.connect(document.body, "onload", function () {

    var d = dojo.query("div");
    var s = dojo.query("span");
    dojo.empty(d[0]);
    dojo.create("span", {innerHTML: s[0].innerHTML}, d[0]);

});

</script>
</head>
<body>
<div><span>foobar</span></div>
</body>
</html>

Don't bother trying it over at jsFiddle, this particular case does not reproduce over there.

Sample should output foobar but on IE it does not.

Why does this happen and is there a way around it?

Upvotes: 2

Views: 175

Answers (1)

Saul
Saul

Reputation: 18041

After some digging and debugging I managed to track the issue down to the internals of Dojo:

397.empty = has("ie") ? function(node) {
    node = dom.byId(node);
    for (var c; c = node.lastChild; ) {
        _397.destroy(c);
    }
} : function(node) {
    dom.byId(node).innerHTML = "";
};

_397.destroy = function destroy(node) {
    node = dom.byId(node);
    try {
        var doc = node.ownerDocument;
        if (!_3a2 || _3a3 != doc) {
            _3a2 = doc.createElement("div");
            _3a3 = doc;
        }
        _3a2.appendChild(node.parentNode ? node.parentNode.removeChild(node) : node);
        _3a2.innerHTML = "";
    } catch (e) {
    }
};

As can be seen from above code, IE gets a special case but unfortunately it is not functionally equivalent - things end up different.

Not sure if this is a bug but certainly a feature of questionable merit. A workaround is to run dojo.clone() on innerHTML before invoking dojo.empty():

var d = dojo.query("div");
var s = dojo.query("span");
var i = dojo.clone(s[0].innerHTML);
dojo.empty(d[0]);
dojo.create("span", {innerHTML: i}, d[0]);

Upvotes: 2

Related Questions