Is there a built-in method for choosing the closest n siblings

Consider the structure below

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

What I want is to select the next 9 buttons when I click on the button, and this allows me to talk about changing the colors of bg. And so my custom code is already doing this

$(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" }); }); 

Now I find using if .. else .. blocks for jquery selectors somehow. Of course, we should use it if necessary, but in this case we? Are there any built-in methods for this purpose in jquery?

HERE is a violin that you can play.

+6
source share
2 answers

There is no built-in method for this, but it is easy to do without using 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 .

By the way, a simple plugin could be easily created / used:

 (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 .

Unfortunately, I did not notice, until the comments indicated the need to always select the full specified range of elements, even if this offsets the element that clicked in the center from the selected section. There seems to be no way to do this without using if / else some kind (although I'm trying to simplify it).

While the above remains true (there is no built-in method), I decided to rewrite the plugin to offer a choice for this (if used for you):

 (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 .

Literature:

+3
source

You can just use .slice() , the only thing you need to pay attention to is the negative start index, which is easy to get around,

 $(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'); }); 

Little demo: http://jsfiddle.net/x2QJP/9/

0
source

All Articles