节点选择和操作从dom(什么是jQuery的技巧?)

时间:2009-12-02 14:04:16

标签: javascript jquery dom getelementbyid documentfragment

嗨,我想做dom的选择和操作。

目标是将我的小部件从dom中构建出来,并在它准备就绪后将其插入dom中。

我的问题是文档片段不支持getElementById。我也尝试过createElement和cloneNode,但它也不起作用。

我试图在普通的js中这样做。我习惯用jQuery来处理它。我试图在jQuery源代码中找到这个技巧,但到目前为止还没有成功......

奥利弗

6 个答案:

答案 0 :(得分:1)

我做过类似的事情,但不确定它是否能满足您的需求。 创建一个“保留区域”,例如普通<span id="spanReserve"></span><td id="cellReserve"></td>。然后你可以在JS函数中做这样的事情:

var holdingArea = document.getElementById('spanReserve'); holdingArea.innerHTML = widgetHTMLValue;

答案 1 :(得分:1)

jQuery将首先尝试使用getElementById,如果这不起作用,它将使用getAttribute("id")搜索所有DOM元素,直到找到您需要的那个。

例如,如果您构建了以下未附加到document的DOM结构,并且它已分配给javascript var widget

<div id="widget">
    <p><strong id="target">Hello</strong>, world!</p>
</div>

然后您可以执行以下操作:

var target;

// Flatten all child elements in the div
all_elements = widget.getElementsByTagName("*");

for(i=0; i < all_elements.length; i++){
    if(all_widget_elements[i].getAttribute("id") === "target"){
        target = all_widget_elements[i];
        break;
    }
}

target.innerHTML = "Goodbye";

如果您需要的不仅仅是按ID搜索,我建议安装Sizzle而不是复制Sizzle功能。假设您有能力安装另一个库。

希望这有帮助!

答案 2 :(得分:0)

编辑:

这些方面的简单内容如何:

  DocumentFragment.prototype.getElementById = function(id) {
    for(n in this.childNodes){
      if(id == n.id){
        return n;
      }
    }

    return null;
  }

为什么不在你使用的其他lib中使用jQuery或选择API? AFAIK所有主要的库都支持片段选择。

如果你想跳过像jQ / Prototype / Dojo /等更大的lib。那么你可以使用Sizzle - 它是为jQ和Dojo提供动力的选择器引擎,它作为独立提供。如果那不可能,那么我想你可以潜入Sizzle来源,看看有什么事情发生。总而言之,虽然似乎有很多努力可以避免几百万的额外概率,但是你提出的代码比运行Sizzle或其他开源库的所有工作都要慢。

http://sizzlejs.com/

哦也......我认为(猜测)jQ的诀窍是元素不在DOM之外。我可能错了,但我认为你做的事情如下:

$('<div></div>');

它实际上在DOM文档中它不是body / head节点的一部分。可能完全错了,但这只是猜测。

所以你让我很好奇哈哈。我看了一下sizzle ..而不是答案 - 它不使用DOM方法。它似乎使用一种算法来比较映射到选择器类型的各种DOMNode属性 - 除非我遗漏了某些东西......这完全有可能:-)

然而,如下面的评论所述,似乎Sizzle不能在DocumentFragments上工作......所以回到原点: - )

答案 3 :(得分:0)

现代浏览器(读取:非IE)在Element API中具有querySelector方法。您可以使用它来获取DocumentFragment中的id和元素。

jQuery使用sizzle.js

它对DocumentFragments的作用是:深度遍历片段中的所有元素,检查元素的属性(在您的情况下为'id')是否是您正在寻找的属性。据我所知,sizzle.js也使用querySelector(如果可用)来加快速度。

如果您正在寻找可能的跨浏览器兼容性,则需要编写自己的方法,或检查querySelector方法。

答案 4 :(得分:-1)

听起来你正在做正确的事情。不知道为什么它没有成功。



// if it is an existing element
var node = document.getElementById("footer").cloneNode(true);

// or if it is a new element use
// document.createElement("div");

// Here you would do manipulation of the element, setAttribute, add children, etc.
node.childNodes[1].childNodes[1].setAttribute("style", "color:#F00; font-size:128px");

document.documentElement.appendChild(node)



答案 5 :(得分:-1)

你真的有两个工具可以使用,html()和在XML文档上使用普通的jQuery操作运算符,然后将它插入到DOM中。

要创建窗口小部件,您可以使用html():

$('#target').html('<div><span>arbitrarily complex JS</span><input type="text" /></div>');

我认为这不是你想要的。因此,请查看jQuery选择器的其他行为:当传递第二个参数时,它可以是自己的XML片段,并且可以对这些文档进行操作。例如

$('<div />').append('<span>').find('span').text('arbitrarily complex JS'). etc.

append,appendTo,wrap等所有运算符都可以处理这样的片段,然后将它们插入到DOM中。

但请注意:jQuery使用浏览器的本机函数来操作它(据我所知),因此您可以在不同的浏览器上获得不同的行为。确保格式良好的XML。我甚至已经拒绝了不正确形成的HTML片段。但最糟糕的情况是,返回并使用字符串连接和html()方法。