DOM 之外的节点选择和操作(jQuery 的技巧是什么?)

发布于 2024-08-13 01:23:24 字数 267 浏览 5 评论 0原文

你好,我想在 dom 之外进行 dom 选择和操作。

目标是在 dom 之外构建我的小部件,并仅在准备好后将其插入到 dom 中。

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

我正在尝试用普通的 js 来做到这一点。我习惯使用 jQuery 来完成此操作,它可以很好地处理它。我试图在 jQuery 源代码中找到窍门,但到目前为止没有成功......

Olivier

Hi I would like to do dom selection and manipulation out of the dom.

The goal is to build my widget out of the dom and to insert it in the dom only once it is ready.

My issue is that getElementById is not supported on a document fragment. I also tried createElement and cloneNode, but it does not work either.

I am trying to do that in plain js. I am used to do this with jQuery which handles it nicely. I tried to find the trick in jQuery source, but no success so far...

Olivier

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

欢你一世 2024-08-20 01:23:24

我做过类似的事情,但不确定是否能满足您的需求。
创建一个“等待区域”,例如普通的 。然后你可以在 JS 函数中执行类似的操作:

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

I have done something similar, but not sure if it will meet your needs.
Create a "holding area" such as a plain <span id="spanReserve"></span> or <td id="cellReserve"></td>. Then you can do something like this in JS function:

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

[旋木] 2024-08-20 01:23:24

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 功能。假设您有能力安装另一个库。

希望这有帮助!

jQuery will try to use getElementById first, and if that doesn't work, it'll then search all the DOM elements using getAttribute("id") until it finds the one you need.

For instance, if you built the following DOM structure that isn't attached to the document and it was assigned to the javascript var widget:

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

You could then do the following:

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";

If you need more than just searching by ID, I'd suggest installing Sizzle rather than duplicating the Sizzle functionality. Assuming you have the ability to install another library.

Hope this helps!

时光与爱终年不遇 2024-08-20 01:23:24

编辑:

沿着这些思路做一些简单的事情怎么样:

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

    return null;
  }

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

如果您想跳过像 jQ/Prototype/Dojo/etc 这样的更大的库,那么您可以使用 Sizzle - 它是为 jQ 和 Dojo 提供支持的选择器引擎,并且作为独立的版本提供。如果这也是不可能的,那么我想您可以深入研究 Sizzle 源代码,看看发生了什么。总而言之,为了避免 100k 的运行时间似乎需要付出很大的努力,而且您编写的代码运行时的速度可能会比放入 Sizzle 或其他开源库中的所有工作要慢。

http://sizzlejs.com/

哦还有...我认为(猜测)jQ 的技巧是元素不是脱离 DOM。我可能是错的,但我认为当你做类似的事情时:

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

它实际上在 DOM 文档中,它只是不是主体/头节点的一部分。不过,这可能是完全错误的,这只是一个猜测。

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

但是正如下面评论中所述,Sizzle 似乎不适用于 DocumentFragments...所以回来到第一个:-)

EDIT:

what about something simple along these lines:

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

    return null;
  }

Why not just use jQuery or the selection API in whatever other lib youre using? AFAIK all the major libs support selection on fragments.

If you wan tto skip a larger lib like jQ/Prototype/Dojo/etc.. then you could jsut use Sizzle - its the selector engine that powers jQ and Dojo and its offered as a standalone. If thats out of the question as well then i suppose you could dive in to the Sizzle source and see whats going on. All in all though it seems like alot of effort to avoid a few 100k with the added probaility that the code you come up with is going to be slower runtime wise than all the work pulled into Sizzle or another open source library.

http://sizzlejs.com/

Oh also... i think (guessing) jQ's trick is that elements are not out of the DOM. I could be wrong but i think when you do something like:

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

Its actually in the DOM document its just not part of the body/head nodes. Could be totally wrong about that though, its just a guess.

So you got me curious haha. I took a look at sizzle.. than answer is - its not using DOM methods. It seems using an algorithm that compares the various DOMNode properties mapped to types of selectors - unless im missing something... which is entirely possible :-)

However as noted below in comments it seems Sizzle DOES NOT work on DocumentFragments... So back to square one :-)

北方的巷 2024-08-20 01:23:24

现代浏览器(不是 IE)在 Element API 中有 querySelector 方法。您可以使用它在 DocumentFragment 中按 id 获取元素。

jQuery 使用 sizzle.js

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

如果您正在寻找跨浏览器兼容性(您可能就是这样),您将需要编写自己的方法,或者检查 querySelector 方法。

Modern browsers ( read: not IE ) have the querySelector method in Element API. You can use that to get and element by id within a DocumentFragment.

jQuery uses sizzle.js

What it does on DocumentFragments is: deeply loop through all the elements in the fragment checking if an element's attribute( in your case 'id' ) is the one you're looking for. To my knowledge, sizzle.js uses querySelector too, if available, to speed things up.

If you're looking for cross browser compatibility, which you probably are, you will need to write your own method, or check for the querySelector method.

赢得她心 2024-08-20 01:23:24

听起来你正在做正确的事情。不知道为什么它不起作用。



// 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)



It sounds like you are doing to right things. Not sure why it is not working out.



// 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)



一紙繁鸢 2024-08-20 01:23:24

您实际上有两个工具可以使用: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() 方法。

You really have two tools to work with, html() and using the normal jQuery manipulation operators on an XML document and then insert it in the DOM.

To create a widget, you can use html():

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

I assume that's not what you want. Therefore, look at the additional behaviors of the jQuery selector: when passed a second parameter, it can be its own XML fragment, and manipulation can happen on those documents. eg.

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

All the operators like append, appendTo, wrap, etc. can work on fragments like this, and then they can be inserted into the DOM.

A word of caution, though: jQuery uses the browser's native functions to manipulate this (as far as I can tell), so you do get different behaviors on different browsers. Make sure to well formed XML. I've even had it reject improperly formed HTML fragments. Worst case, though, go back and use string concatenation and the html() method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文