Thursday, 12 September 2013

Dojo Query by ID defaulting to getElementById

Dojo Query by ID defaulting to getElementById

Looking through the code in Dojo's library for dojo/query, it looks like
they default to use document.getElementById if the selector passed in is
an ID selector.
For example, if I do:
query("#myId")
This will behind the scenes run:
document.getElementById("myId")
This is fine for querying nodes in the window document, but what if you
are building nodes not yet put in the document? If I am constructing a
node in memory to put in the DOM later and I need to query on that node by
ID, I can't do it. Because this node isn't in the document yet.
I understand that this is how jQuery does it, too, but jQuery is different
because the approach for querying by an ID or a different selector (class,
attribute, etc.) is the same regardless. For example:
$("#myId")
$(".myClass")
$("div[align=center]")
The approach is the same. So, defaulting to document.getElementById in
this instance is fine to me.
With Dojo, its pretty misleading in light of the fact that Dojo offers a
separate function that serves as an alias to getElementById (dom.byId). If
I wanted ID querying against the actual document, I'd use that. If I'm
using dojo/query by a selector, then I want to be able to query the
document or a contextual node.
Dojo uses the lite.js selector engine in situations where a viable native
selector engine is available. The beginning of the file has a "fast path"
block that actually does this default to dom.byId. If I comment out this
block, the engine reverts to use a querySelectorAll, which in turn fixes
this issue.
Can anyone explain the reasoning for Dojo doing this? Or if there is a
viable workaround that doesn't require me to comment out Dojo's code? One
approach I've seen that works is the use of data-attributes in place of
IDs, which fake out the engine but that just seems lame.
EDIT:
Note: You can pass a contextual node to dojo/query when querying, but in
Dojo even if you create a node outside the DOM using dom-construct, the
ownerDocument of that node is still the window.document. In other words:
var node = domConstruct.toDom('<div><p><span
id="myId">Content</span></p></div>');
var doc = node.ownerDocument;
will result in 'doc' being the window.document. So, doing something like:
doc.getElementById("myId") will fail. As will this:
var results = query("#myId", node);
Because Dojo's code looks for the ownerDocument of 'node', which again is
the window.document
In the above,

No comments:

Post a Comment