简体   繁体   English

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

[英]Writing an .add*() plug-in function using jQuery

Okay, so I have discovered how to write jQuery plug-ins and I think this will tidy up my code a lot. 好的,所以我发现了如何编写jQuery插件,我认为这会很多地整理我的代码。 I've been looking at a lot of tutorials which just adds style to the set of matched elements passed on the plug-in function. 我一直在看很多教程,它们只是为插件函数传递的匹配元素集添加了样式。

...but I want to add new elements to the when using my function. ...但我想在使用我的函数时添加新元素。 Say that I want to do this: 说我想这样做:

$children
    .addCousins()
        .addClass("x")
    .end()
    .addClass("y");

So I've written this function, .addCousins() . 所以我写了这个函数, .addCousins() What it does, nobody knows, but know that it works in theory. 它的作用,没人知道,但知道它在理论上有效。 I only need to wrap my head around how to add more elements (if there are any) when .addCousins() is called. 我只需要在.addCousins()时如何添加更多元素(如果有的.addCousins() For each element in $children there can be zero or more "cousins", which should be added when doing the .each() in the plug-in function. 对于$children每个元素,可以有零个或多个“堂兄弟”,这应该在插件函数中执行.each()时添加。

Here's what I have so far: 这是我到目前为止所拥有的:

(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);

I've been trying various solutions all day, but no progress yet. 我整天都在尝试各种解决方案,但还没有进展。 The selection of the cousin (the implementation of the selection you need not worry about) is done in the inner anonymous function, but, yeah, I don't really know how to go from here. 表兄弟的选择(你不必担心的选择的实现)是在内部匿名函数中完成的,但是,是的,我真的不知道如何从这里开始。

I hope I've been more or less clear about what I want. 我希望我或多或少地清楚自己想要什么。

Edit #1. 编辑#1。 Here is some testable HTML (I think)... 这是一些可测试的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>

...and my updated plug-in function. ...和我更新的插件功能。

(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);

If table cell 2 is selected an passed on to .cousins() , table cell 4 should be returned. 如果选择表格单元格2并传递给.cousins() ,则应返回表格单元格4。 Vice versa for table cell 4... 反之亦然,表格4 ...

Edit #2. 编辑#2。 My (not yet working) update: 我的(还没有工作)更新:

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

As I understand it, you want to add elements to the set, and have .end get you back the previous set. 据我所知,你想要在集合中添加元素,并让.end让你回到前一集。

You can use .add for this: http://jsfiddle.net/AjkRb/1/ . 您可以使用.addhttp//jsfiddle.net/AjkRb/1/

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

                toAdd.push($(this)
                    .parent()
                    .next()
                    .children("td.radio")
                    .get(index));  // add native element (get instead of eq)
            });
            return this.add(toAdd);
        }
    });
})(jQuery);

Usage can then be as follows: 用法可以如下:

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

Viktor, assuming your code to correctly select the elements of interest (cousins), then there's a number of ways to approach adding them to the original selection. Viktor,假设您的代码正确选择了感兴趣的元素(堂兄弟),那么有很多方法可以将它们添加到原始选择中。

A consideration is that the elements in the returned jq object should be in DOM order and fortunately, "as of jQuery 1.4 the results from .add() will always be returned in document order (rather than a simple concatenation) .add() ". 需要考虑的是返回的jq对象中的元素应该是DOM顺序,幸运的是,“从jQuery 1.4开始, .add()的结果将始终按文档顺序返回(而不是简单的连接) .add() ” 。 pimvdb's code correctly addresses this. pimvdb的代码正确解决了这个问题。

On another tack, I would prefer the additional flexibility offerd by a .cousins() plugin rather than .addCousins() , where : 另一方面,我更喜欢.cousins()插件而非.addCousins()提供的额外灵活性,其中:

  • .cousins() would select just the cousins .cousins()会选择表兄弟
  • .cousins().andSelf() would be equivalent to .addCousins() .cousins().andSelf()相当于.addCousins()

Here's the code for .cousins() : 这是.cousins()的代码:

(function($) {
    $.fn.extend({
        cousins: function(options) {
            var settings = {
                sibling_selector: '*',
                uncle_selector: '*',
                cousin_selector: '*'
            };
            if (options) {
                $.extend(settings, options);
            }
            var c = [];//cousins
            this.each(function() {
                var $this = $(this);
                var index = $this.parent().children(settings.sibling_selector).index($this);
                $this.parent().siblings(settings.uncle_selector).each(function() {
                    c.push($(this).children(settings.cousin_selector).get(index));
                });
            });
            return this.pushStack(c);
        }
    });
})(jQuery);

DEMO DEMO

Notes: 笔记:

  • to generalize the plugin, this version accepts an options map (see demo). 为了概括插件,这个版本接受一个选项图(见演示)。
  • .pushStack() allows the method chain .cousins(...).andSelf() and .cousins(...).end() to behave as expected. .pushStack()允许方法链.cousins(...).andSelf().cousins(...).end()按预期运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM