Javascript 使用jQuery编写.add*()插件函数

Javascript 使用jQuery编写.add*()插件函数,javascript,jquery,jquery-plugins,Javascript,Jquery,Jquery Plugins,好的,我已经发现了如何编写jQuery插件,我认为这将大大整理我的代码。我已经看过很多教程,它们只是向传递给插件函数的匹配元素集添加样式 (function($){ $.fn.extend({ cousins: function () { this .each( function () { var index = $(this)

好的,我已经发现了如何编写jQuery插件,我认为这将大大整理我的代码。我已经看过很多教程,它们只是向传递给插件函数的匹配元素集添加样式

(function($){
    $.fn.extend({ 
        cousins: function () {
            this
                .each(
                    function () {
                        var index = $(this)
                            .prevAll("td.radio")
                                .andSelf()
                                    .length - 1;

                        $(this)
                            .prev("td[rowspan=2]")
                                .parent()
                                    .next()
                                        .children("td.radio")
                                            .eq(index)
                                                .addClass("cousin");
                                            .end()
                                        .end()
                                    .end()
                                .end()
                            .end()
                            .prev()
                                .find("td[rowspan=2]")
                                    .nextAll("td.radio")
                                        .eq(index)
                                            .addClass("cousin");
                    }
                );

            return $("td.cousin")
                .removeClass("cousin");
        }
    });
})(jQuery);
…但我想在使用我的函数时向添加新元素。说我想这样做:

$children
    .addCousins()
        .addClass("x")
    .end()
    .addClass("y");
所以我写了这个函数,.addCousins。没有人知道它的作用,但知道它在理论上是有效的。如果调用when.addCousins,我只需要考虑如何添加更多元素。对于$children中的每个元素,可以有零个或多个近亲,在执行插件函数中的.each时应添加这些近亲

(function($){
    $.fn.extend({ 
        cousins: function () {
            this
                .each(
                    function () {
                        var index = $(this)
                            .prevAll("td.radio")
                                .andSelf()
                                    .length - 1;

                        $(this)
                            .prev("td[rowspan=2]")
                                .parent()
                                    .next()
                                        .children("td.radio")
                                            .eq(index)
                                                .addClass("cousin");
                                            .end()
                                        .end()
                                    .end()
                                .end()
                            .end()
                            .prev()
                                .find("td[rowspan=2]")
                                    .nextAll("td.radio")
                                        .eq(index)
                                            .addClass("cousin");
                    }
                );

            return $("td.cousin")
                .removeClass("cousin");
        }
    });
})(jQuery);
以下是我目前掌握的情况:

(function($){
    $.fn.extend({
        addCousins: function () {
            return this.each(
                    function () {
                        var index = $(this)
                            .prevAll("td.radio")
                                .andSelf()
                                    .length - 1;

                        $(this)
                            .prev("td[rowspan=2]")
                                .parent()
                                    .next()
                                        .children("td.radio")
                                            .eq(index); // here is the "cousin" which should be added to the selection
                    }
                );
        }
    });
})(jQuery);
我一整天都在尝试各种解决方案,但还没有任何进展。表亲的选择——您不必担心的选择的实现——是在内部匿名函数中完成的,但是,是的,我真的不知道如何从这里开始

我希望我已经或多或少地清楚我想要什么

编辑1。这里有一些可测试的HTML我想

<table>
    <tr>
        <td rowspan="2">Here are cousins</td>
        <td class="radio">1</td>
        <td class="radio">2</td>
        <td class="radio">3</td>
    </tr>
    <tr>
        <td class="radio">4</td>
        <td class="radio">5</td>
        <td class="radio">6</td>
    </tr>
    <tr>
        <td rowspan="2">Here are NO cousins</td>
        <td class="radio">7</td>
        <td class="radio">8</td>
        <td class="radio">9</td>
    </tr>
</table>
如果选择了表单元格2,则应将表单元格4返回给.cousins。反之亦然,表格单元格4

编辑2。我的尚未工作更新:

cousins: function () {
    var $cousins = $();

    this
        .each(
            function () {
                var index =
                    $(this)
                        .prevAll("td.radio")
                            .andSelf()
                                .length - 1;
                var $next = null;
                var $prev = null;

                $next = 
                    $(this)
                        .prev("td[rowspan=2]")
                            .parent()
                                .next()
                                    .children("td.radio")
                                        .get(index);
                $prev =
                    $(this)
                        .parent()
                            .prev()
                                .find("td[rowspan=2]")
                                    .nextAll("td.radio")
                                        .get(index);

                if ($next == null && $prev == null) {
                    $cousins.push($(this));
                } else {
                    $cousins.push($next);
                    $cousins.push($prev);
                }
            }
        );

    return $cousins;
}

Viktor,假设您的代码正确地选择了感兴趣的元素,那么有很多方法可以将它们添加到原始选择中

需要考虑的是,返回的jq对象中的元素应该是DOM顺序,幸运的是,从jQuery 1.4开始,.add的结果将始终以文档顺序返回,而不是简单的连接.add。pimvdb的代码正确地解决了这一问题

另一方面,我更喜欢.cousins插件提供的额外灵活性,而不是.addCousins插件,其中:

.表亲们只会选择表亲们 .cousins.andSelf将等同于.addCousins 以下是。表兄妹的代码:

注:

为了推广这个插件,这个版本接受一个选项映射,请参见演示。 .pushStack允许方法链.cousins…和self以及.cousins…结束按预期运行。
据我所知,您希望向集合中添加元素,并使.end返回上一个集合

您可以为此使用。添加:

使用方法如下所示:

$("tr:first td.radio")
  .addCousins()
    .addClass("red")
    .end()
  .addClass("big");

您能否定义将元素视为近亲的规则?改编自维基百科:元素共享一个或多个共同祖先,而不是父、子、祖先、后代、兄弟姐妹、兄弟姐妹的后代/子,或祖先/父的兄弟姐妹。我认为,兄弟姐妹是一个单元格,位于我仅在下面实现的选定单元格的正上方或下方。如果给他们取个表兄妹的名字是明智的,我不知道,但这对我来说是可行的,但不要在意我的名字命名似乎很合适,但也许通过一些HTML,可以更容易地可视化您正在尝试做的事情。=]HTML本质上是。例如,如果您要选择任何不是我要获取的行跨度的行,以及它上面或下面的表亲。如果在一行中同时选择这两行,我想得到这两个表兄妹,但如果没有rowspan属性,就没有表兄妹。这里有一个演示,第一个问题有两行:这一行可以工作,但它的代码很混乱,我想用插件方法整理一下。嗯,这是一个非常有趣的解决方案,我从来没有想过,使用类作为标志。这是选择插件的标准吗?关于你关于使用.cousins而不是.addCousins的建议:我将如何从我的脚本中使用它?假设我使用$this.prevAlltd.andSelf.addCousins.nowDoSomethingWithChildrenAndCousins,当$this是单击的表格单元格时。既然我需要再次选择先前选择的元素,我将如何重写它以使用.cousins?另外,我无法注意到您的两个代码预览之间的任何差异,但谢谢!不要介意最后一个问题。正如你所说,赛尔夫似乎做了我想做的。我不能完全让它工作,但我的遍历可能有问题。嗯…@Viktor,没有适当的HTML我无法测试。你能给你原来的帖子加上点什么吗?@Viktor,我才刚刚开始研究真正的堂兄弟范例。从家谱上看,表兄弟姐妹是父母兄弟姐妹的孩子,但我不能让这个定义与你描述的相符。除非我读错了,否则范例中的但书使其非常特定于您的应用程序。我开始怀疑这个问题是否真的符合插件的条件,在任何情况下,只有在需要同时对两个或多个根元素调用cousins范式时,插件才有意义。通过创建一个常规javascript函数,您仍然可以获得可重用代码。谢谢!我以前也这么想过,但由于我对JS没有经验,结果是错的。如果我听从Beetroot的建议,在不想返回原始元素的地方使用.cousins函数,会怎么样?返回添加;不太管用。
$("tr:first td.radio")
  .addCousins()
    .addClass("red")
    .end()
  .addClass("big");