8

我正在编写一个 jQuery 插件,它“指向”DOM 中的一定数量的节点。然而,如果我尝试让我的插件保存对一组节点的引用,我担心它们会“过时”。

(虽然我意识到 JavaScript 是垃圾收集并且不会崩溃,但我希望能够使我的列表保持最新,而不是保留应该被 GC 处理的东西。)

我首先想到的是可能有某种钩子。但似乎没有一个看起来值得信赖的标准:

使用 JQuery,是否可以在 DOM 元素调用 .remove() 时运行函数?

从 DOM 树中删除元素的回调?

jQuery remove() 回调?

这让我想知道通过在节点上放置类属性来维护节点列表。这样,他们在列表中的成员将与他们一起旅行。但正如人们可能担心的那样,枚举起来可能会非常缓慢,这就是为什么您应该在 classes 之前将查询表述为标签的原因。

除了潜在的性能问题之外,我想知道是否认为插件出于这种目的将类插入 DOM 节点是一种糟糕的形式,这与样式无关。(其中一个更好的事情.data()是它相对带外,除了这个列表问题之外,这就是我正在使用的。)

这似乎是一个很常见的问题,其他插件已经解决了。我很想将类解决方案用于它的“正确性”属性,即使它速度较慢。但是有没有一种更快、更规范的方法可以两全其美?

4

2 回答 2

5

我相信 jQuery UI 是如何做到的。特别是Droppables,它们在内部维护一个 jQuery 对象列表,当有东西悬停在它上面时,它们会迭代这些对象。他们以两种方式管理列表,

  1. 添加在运行 jQuery.remove() 时触发的销毁处理程序。(他们挂钩到 jQuerys 删除函数来执行此操作)尽管如此,这不会处理普通的 javascript 删除,
  2. 在做任何事情之前检查它是否存在。

我认为他们不会删除它,因为它可能会从 DOM 中删除然后放回原处。

于 2011-11-25T16:45:38.043 回答
1

很抱歉打扰您,但是“可信赖的基于 jQuery 的代码”在术语上是矛盾的。FWIW:

jQuery 与其他几个当前流行的脚本框架一样,创建一个类似Array的对象来保存查询结果,而不是实现W3C DOM Level 2+ Core(简称)NodeList接口的对象。A是的;-like 对象,它们是原生 ECMAScript 对象,而不是宿主对象,(通常)不是。NodeListNodeListArray

如果您不为此使用此类框架,则不会遇到此问题,因为所有(准)标准 DOM 方法(如getElementsByClassName())和属性(如document.forms)都返回/产生 a NodeList(有时甚至是 a HTMLCollection)。

DOM 级别 2 事件指定突变事件类型,但从DOM 级别 3 事件工作草案)开始,它们已被弃用,并且任何挂钩现在都不可靠,甚至可能无法互操作

因此,您应该为此使用(准)标准方法,而不是 jQuery 结果和突变事件。

但是,如果您仍然想采用 jQuery(-ish) 方式(以及所有其他不明显的缺点),您应该查看 aNodeparentNode属性。 Node不是Document节点但仍在文档树中的 s 具有非null parentNode属性值(而null应理解为 W3C DOM Level 2+ Core Specification 的 language-independent null,因此您应该查找类型转换为的所有值true在 ECMAScript 实现中)。因此,所有其他Nodes 的parentNode属性值为, 因此在 ECMAScript 实现null中类型转换为。false

假设它myNodes引用了一个Array元素是Nodes 的实例,并且myNode引用了一个这样的节点对象,那么以下应该可以工作:

var i = 0;

/* … */

var myNode = myNodes[i];
if (!myNode.parentNode)
{
  myNodes.splice(i, 1);
}

然后,您可以偶尔进行迭代myNodes,例如在一个名为 through 的函数中window.setInterval(),并从中删除“陈旧”节点。它当然不如NodeList使用 .

不幸的是,jQuery()不会返回对Array实例的引用。所以你必须先做一个,像这样:

var jqObj = jQuery("…");

/* or jQuery.makeArray(jqObj) */
var a = Array.prototype.slice.call(jqObj, 0);

(我们在这里使用的事实是,引用的对象jqObj确实具有length属性。)

我不能说什么是 jQuery 插件的好样式,因为现在应该很明显的原因我首先尝试避免使用 jQuery。

您还应该学习区分编程语言* s *,如 JavaScript和可与它们一起使用的(通常与语言无关的)API,如 DOM。

HTH。

于 2011-12-02T01:07:37.480 回答