javascript - Dojo Query by ID defaulting to getElementById - Stack Overflow

Looking through the code in Dojo's library for dojoquery, it looks like they default to use docum

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 ment 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 ment 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

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 ment 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 ment 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

Share edited Sep 12, 2013 at 15:21 sma asked Sep 12, 2013 at 13:54 smasma 9,5978 gold badges53 silver badges83 bronze badges 4
  • Why are you searching for a node that does not exist yet? are you tyring to search within the contextual node? if so you can pass the node as an argument in dojo.query. dojo.query(selector,node) – tik27 Commented Sep 12, 2013 at 14:36
  • 1 I am, yeah. And yes, you can pass a node not yet in the DOM, but even in that instance, the ownerDocument of that node is still the window.document itself. If I create a node in Dojo using domConstruct and then do 'node.ownerDocument' on that node, the document returned is the window.document in the browser. And since this node is not yet there, document.getElementById fails. – sma Commented Sep 12, 2013 at 15:12
  • The problem with the context parameter is that it too must be a DOM element, so it can't be used if the node is only in memory. – Bucket Commented Sep 12, 2013 at 15:14
  • Yep, you're correct. See my above edit. – sma Commented Sep 12, 2013 at 15:22
Add a ment  | 

4 Answers 4

Reset to default 3
 var hellopuppy = dojo.query("[id='myId']",node);

If the node is not yet in the DOM, it cannot be accessed with Dojo's query selector. However, if the node is in the dijit registry, you can access it with dijit.registry.byId(<id>).

This may be a hack, but maybe it can help you,

function foo(){
    this.bar = bar();
    bar.[access the properties of the div here]
}

function bar(){
   this.somenode = document.createElement("div");
   return this.somenode;
}

you can access the properties of the div, in this case bar, without adding it to the page, 'somenode' in bar() can be anything that is a valid html element.

Yes, it seems like if you specify a context for query('#myid', nodeInMemory), it should not use document.etElementById()

The workaround is to use

dojo.query("[id='myid']", nodeInMemory);

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745044593a4608017.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信