0

我正在编写自己的 jQuery 插件,其中引用了一些现有节点,并创建了一些在 DOM 树中不存在的新 jQ 节点(它们没有附加)。我正在使用该.add()方法将每个元素添加到新集合中。

发生的情况是,这个集合的顺序看起来很奇怪(我在那里找不到任何逻辑模式)。文档中的以下注释可能是原因:

从 jQuery 1.4 开始,来自 .add() 的结果将始终按文档顺序返回(而不是简单的串联)。

考虑以下示例。

HTML

<body>
    <a id="existing1"></a><a id="existing2"></a>
</body>

JS

<script type="text/javascript">

    function addToColl(selector) {
        coll = coll.add(selector);
        var n = $(selector).get(0).id.match(/\d+/)[0];
        for (var i = 0; i < 4; i++) {
            var a = $('<a>',{id:'virtual'+n+'_'+i});
            coll = coll.add(a);
        }
    }

    $(document).ready(function() {

        coll = $();

        addToColl('#existing1');
        // uncomment the following to see what's happening
        //addToColl('#existing2');

        $.each(coll,function(idx,elm) {
            console.log(elm.id);
        });

    });

</script>

输出:

现有
1 虚拟 1_0虚拟 1_1 虚拟
1_2
虚拟
1_3

当您取消注释注释函数调用它输出

现有
1 虚拟1_3 虚拟 1_2 虚拟 1_1 虚拟 1_0 现有
2 虚拟 2_0虚拟 2_1 虚拟 2_2 虚拟 2_3






应该怎么做才能避免这种混乱?

------ [编辑] ------
由于add()函数的意外行为,我最终使用原生 Javascript 数组来收集元素(即使用push()方法)。稍后,当我收集完元素后,我会将其转换为 jQuery 集合。

4

1 回答 1

1

jQuery 中的代码如下所示:

    add: function( selector, context ) {
            var set = typeof selector === "string" ?
                            jQuery( selector, context ) :
                            jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
                    all = jQuery.merge( this.get(), set );

            return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
                    all :
                    jQuery.unique( all ) );
    },

因此,如果添加的集合的第一个元素或合并的集合断开连接,它只会返回合并的集合,无论jQuery.merge()它们发生的顺序是什么。如果它们都是连接的,它会调用jQuery.unique(),这会将它们按 DOM 顺序排列。

但是,进行排序的比较函数是:

    function( a, b ) {
            if ( a === b ) {
                    hasDuplicate = true;
                    return 0;
            }

            return ( !a.compareDocumentPosition || !b.compareDocumentPosition ?
                    a.compareDocumentPosition :
                    a.compareDocumentPosition(b) & 4
            ) ? -1 : 1;
    }

然后,这取决于浏览器compareDocumentPosition()在将断开连接的元素与连接的元素或断开连接的元素相互比较时如何实现。我希望它DOCUMENT_POSITION_DISCONNECTED在两种情况下都返回 (1),但 Chrome 在后一种情况下返回 4 ( DOCUMENT_POSITION_FOLLOWING),在第一种情况下返回其他位组合。

于 2012-12-31T18:34:43.550 回答