Reputation: 1563
I'm trying to figure out the best way to create groups of elements based on common properties. I can obviously compare them one by one and end up with the correct result but I'm sure there is a better way to go.
So, I basically assign 4 types of attributes to my divs: position top, position left, width and position bottom. I have 4 divs to which I assign them (but 4 may be bigger in the future).
zones = 4;
for (x = 1; x<=zones ; x++)
{
$('#zone'+x).attr('data-top',Math.floor($('#zone'+x).position().top));
$('#zone'+x).attr('data-bottom',Math.floor($('#zone'+x).position().top) + $('#zone'+x).height());
$('#zone'+x).attr('data-left',Math.floor($('#zone'+x).position().left));
$('#zone'+x).attr('data-width',$('#zone'+x).width());
}
With this I end up with something like this:
<div id="zone2" data-top="976" data-bottom="2579" data-left="131" data-width="660">...</div>
Now the challenge I'm facing is to create groups of elements based on all divs that have a common data-top value. The simple solution was to compare all data-top to each other, while with only 4 divs to compare it's manageable but if the number of divs grow, it will soon become a mess.
QUESTION 1: how to assign a group for a common attribute value?
What I'm trying to get in the end is:
<div id="zone2" data-top="976" data-bottom="2579" data-left="131" data-width="660" data-group="1">...</div>
And data-group would be equal to 1 for all divs that have the same data-top value. If there are multiple groups sharing common data-top values, then I would need data-group to be incremented. I could end up with something like this:
<div id="zone1" data-top="976" data-bottom="2379" data-left="131" data-width="660" data-group="1">...</div>
<div id="zone2" data-top="976" data-bottom="2579" data-left="131" data-width="660" data-group="1">...</div>
<div id="zone3" data-top="1500" data-bottom="2479" data-left="131" data-width="660" data-group="2">...</div>
<div id="zone3" data-top="1500" data-bottom="3579" data-left="131" data-width="660" data-group="2">...</div>
QUESTION 2: how to find a maximum value within a group ?
With the groups correctly set, how should I proceed to find the maximum data-bottom value? In the example above, the maximum data-bottom value for data-group=1 is 2579 and 3579 for data-group=2
I thought of using .each and within the .each compare values, it works in the end but code is awfully long.
Upvotes: 3
Views: 2020
Reputation: 11750
I would propose this approach (FIDDLE)
First, set a data attribute (data-zone
) for each element. Then iterate over the elements and call getTopGroup()
function to check if this group exists and assign the data-group-top
attribute.
HTML
<div class="zone1" data-zone="1">Zone 1</div>
<div class="zone2" data-zone="2">Zone 2</div>
<div class="zone3" data-zone="3">Zone 3</div>
<div class="zone4" data-zone="4">Zone 4</div>
<div class="zone1" data-zone="1">Zone 1</div>
<div class="zone2" data-zone="2">Zone 2</div>
<div class="zone3" data-zone="3">Zone 3</div>
<div class="zone4" data-zone="4">Zone 4</div>
jQuery
// Create a blank array of groups
var groupsTop = [];
var getTopGroup = function(top) {
var group = 1;
var groupIndex = $.inArray(parseInt(top), groupsTop);
if (groupIndex == -1) {
groupsTop.push(top);
return groupsTop.length;
} else {
return groupIndex + 1;
}
};
$('[class^=zone]').each(function() {
var elem = $(this);
var x = elem.attr('data-zone');
var top = 10* x;
var topGroup = getTopGroup(top);
// This is an example calculation of offsets
elem.attr({
'data-top': top,
'data-bottom': 5 * x,
'data-left': 3 * x,
'data-width': 6 * x,
'data-group-top': topGroup
});
});
You can use the same logic to implement a check for other data attributes too.
Upvotes: 1