是否有内置的方法来选择最近的兄弟姐妹

时间:2014-05-02 13:31:08

标签: jquery

考虑下面的结构

Buttons http://i62.tinypic.com/2j0ceh2.jpg

我想要的是在点击按钮时选择最近的9个按钮,然后让我们改变bg颜色。这是我的自定义代码已经做到了

$(document).on("click", "#footer button", function(){
    var index = $(this).index();
    var len = $("#footer button").length;
    $("#footer button").css({
        "background-color" : "#ccc"
    });
    if (index < 5) $("#footer button:lt(9)").css({
        "background-color" : "#c99"
    });
    else if (index > (len - 6)) $("#footer button:gt(-10)").css({
        "background-color" : "#c99"
    });
    else $("#footer button").slice((index -4), (index + 5)).css({
        "background-color" : "#c99"
    });
});

现在,我发现jquery选择器使用if .. else ..块以某种方式跛足。当然,如果必须,我们必须使用它,但在这种情况下,我们呢?在jquery中是否有为此目的链接的内置方法?

HERE 是玩弄的小提琴。

2 个答案:

答案 0 :(得分:3)

没有内置方法可以做到这一点,但是在不使用if / else的情况下轻松完成:

$(document).on("click", "#footer button", function () {
    var that = $(this),
        index = that.index(),
        prev = that.prevAll('button:lt(4)'),
        next = that.nextAll('button:lt(4)');
    that.siblings().removeClass('highlight');
    that.add(prev).add(next).addClass('highlight');
});

JS Fiddle demo

顺便提一下,可以轻松创建/使用简单的插件:

(function($){
    $.fn.rangedHighlight = function(range,highlight) {
        var that = this,
            prev = that.prevAll().slice(0,range),
            next = that.nextAll().slice(0,range);
        that.siblings().addBack().removeClass(highlight);
        that.add(prev).add(next).addClass(highlight);
        return this;
    };
})(jQuery);

$('#footer').on('click', 'button', function(){
    $(this).rangedHighlight(4,'highlight');
});

JS Fiddle demo

不幸的是,在注释中指出之前,我没有注意到必须始终突出显示完整指定的元素范围,即使这会将突出显示的部分的中心偏移点击的元素。如果不使用某种类型的if / else,似乎没有办法做到这一点(尽管我正在尝试简化它)。

虽然以上情况仍然存在(没有内置方法),但我确实决定重写插件以提供选择(如果它对您有用):

(function($){
    $.fn.rangedHighlight = function(opts) {
        var that = this,
            index = that.index(),
            s = $.extend({
                'range' : 9,
                'highlight' : 'highlight',
                'highlightClicked' : false,
                'alwaysShowFull' : true,
                'returnRange' : false
            }, opts),
            eitherSide = Math.floor(s.range - 1)/2,
            all = that.parent().children(),
            leftLimited = index < eitherSide,
            rightLimited = index > all.length - eitherSide - 1,
            rangeMin, rangeMax, returnObject;

        that.addClass(s.highlightClicked, 'string' === typeof s.highlightClicked);

        if (!leftLimited && !rightLimited) {
            rangeMin = index - eitherSide;
            rangeMax = index + eitherSide + 1;
        }
        else if (s.alwaysShowFull && (leftLimited || rightLimited)) {
                rangeMin = leftLimited ? 0 : all.length - s.range;
                rangeMax = leftLimited ? s.range : all.length;
        }
        else if (!s.alwaysShowFull && (leftLimited || rightLimited)) {
                rangeMin = leftLimited ? 0 : index - eitherSide;
            rangeMax = leftLimited ? index + eitherSide + 1 : all.length;
        }

        that.siblings('.' + s.highlight).removeClass(s.highlight);
        all.slice(rangeMin, rangeMax).addClass(s.highlight);

        returnObject = s.returnRange === false ? this : all.slice(rangeMin,rangeMax);

        return returnObject;
    };
})(jQuery);

$('#footer').on('click', 'button', function(){
    $(this).rangedHighlight({
        // Number: number of elements _in total_ to be highlighted:
        'range' : 7,
        // String: the class-name to be applied to selected elements:
        'highlight' : 'highlight',
        // Boolean: shows the full range even if that range 'overlaps'
        // the start/end points:
        'alwaysShowFull' : true,
        // Boolean: return the selected range (true) or the clicked
        // element (true), for chaining purposes:
        'returnRange' : false,
        // String: specific class to add to the clicked element:
        'highlightClicked' : false,
    });
});

JS Fiddle demo

参考文献:

答案 1 :(得分:0)

你可以使用.slice(),唯一需要注意的是一个容易出错的负起始指数。

$(document).on("click", "#footer button", function(){

    var index = $(this).index(),
        range = 9, 
        startIndex = index - range, 
        endIndex = index + ( range + 1 );

    $("#footer button")
        .removeClass('selected')
        .slice(startIndex > 0 ? startIndex : 0, endIndex)
        .addClass('selected');

});

小型演示:http://jsfiddle.net/x2QJP/9/