Dojo Query by ID defaulting to getElementById

Dojo Query by ID defaulting to getElementById

本文关键字:to getElementById defaulting ID Query by Dojo      更新时间:2023-09-26

查看 Dojo 库中的 dojo/query 代码,如果传入的选择器是 ID 选择器,则看起来它们默认使用 document.getElementById

例如,如果我这样做:

query("#myId")

这将在幕后运行:

document.getElementById("myId")

这对于查询窗口文档中的节点很好,但是如果您要构建尚未放入文档中的节点怎么办? 如果我在内存中构造一个节点以稍后放入 DOM,并且我需要按 ID 查询该节点,则我无法做到这一点。 因为此节点尚未在文档中。

我知道这也是jQuery的做法,但是jQuery是不同的,因为无论如何,通过ID或不同的选择器(类,属性等)进行查询的方法都是相同的。 例如:

$("#myId")
$(".myClass")
$("div[align=center]")

方法是一样的。 因此,在这种情况下默认为document.getElementById对我来说很好。

对于Dojo,

鉴于Dojo提供了一个单独的功能作为getElementById (dom.byId)的别名,因此它具有很大的误导性。 如果我想对实际文档进行 ID 查询,我会使用它。 如果我通过选择器使用 dojo/query,那么我希望能够查询文档或上下文节点。

Dojo 在可行的本机选择器引擎可用的情况下使用 lite.js 选择器引擎。 文件的开头有一个"快速路径"块,实际上默认为 dom.byId 。 如果我注释掉这个块,引擎将恢复为使用 querySelectorAll ,这反过来又解决了这个问题。

谁能解释道场这样做的原因? 或者,如果有一个可行的解决方法不需要我注释掉 Dojo 的代码? 我见过的一种有效的方法是使用数据属性代替 ID,这伪造了引擎,但这似乎很蹩脚。

编辑

注意:您可以在查询时将上下文节点传递给 dojo/query,但在 Dojo 中,即使您使用 dom-construct在 DOM 外部创建了一个节点,该节点的 ownerDocument 仍然是 window.document。 换句话说:

var node = domConstruct.toDom('<div><p><span id="myId">Content</span></p></div>');
var doc = node.ownerDocument;

将导致"doc"成为窗口文档。 因此,执行以下操作:

doc.getElementById("myId")将失败。 就像这样:

var results = query("#myId", node);

因为 Dojo 的代码会查找 'node' 的 ownerDocument,它又是 window.document

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

如果节点尚未在 DOM 中,则无法使用 Dojo 的query选择器访问它。但是,如果节点位于 dijit 注册表中,则可以使用 dijit.registry.byId(<id>) .

这可能是一个黑客,但也许它可以帮助你,

function foo(){
    this.bar = bar();
    bar.[access the properties of the div here]
}
function bar(){
   this.somenode = document.createElement("div");
   return this.somenode;
}

您可以访问div 的属性,在本例中为 bar,而无需将其添加到页面中,bar() 中的"somenode"可以是任何有效的 HTML 元素。

是的,似乎如果您为 query('#myid', nodeInMemory) 指定上下文,它不应该使用 document.etElementById()

解决方法是使用

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