Note that there are some explanatory texts on larger screens.

plurals
  1. POLayering intersecting elements with jQuery
    text
    copied!<p>I have a page with draggable/droppable elements that once dropped need to calculate their left position and width in regards to other draggables that they may be touching.</p> <p>This isn't too hard in and of itself, but where I'm really having trouble is getting them to fill in empty space. How do I get the draggables to fill in the empty space without doubling on top of each other?</p> <pre><code>// $t is the element being added/dropped. // nd refers to New Dimensions, IE, the new dimensions for $t // existingDivs gets any DIV's that have already been added to the dom var $t = $(this), nd = {t:$t.position().top, h:$t.height(), l: 0, w: 95}, existingDivs = $('#container .subContainer .draggable'), intersectArr = [], nonIntersectArr = [], finalArr = []; // If there are no DIV's in the DOM you dont need to check if they intersect. if (existingDivs.length &gt; 0) { // Find the DIV's that Intersect with the one being added intersectArr = $.grep(existingDivs, function(val,num){ // xd is Existing Dimensions, for the current item being checked // verse the one being added. var $t2 = $(val), xd = {h:$t2.height(), w:parseFloat($t2.css('width')), l:parseFloat($t2.css('left')), t:$t2.position().top}; // If they intersect add it to this array return ((xd.t &lt;= nd.t &amp;&amp; xd.t+xd.h &gt; nd.t) || (nd.t &lt;= xd.t &amp;&amp; nd.t+nd.h &gt; xd.t)); }); // Find the DIV's that DO NOT Intersect with the one being added nonIntersectArr = $.grep(existingDivs, function(val,num){ // xd is Existing Dimensions, for the current item being checked // verse the one being added. var $t2 = $(val), xd = {h:$t2.height(), w:parseFloat($t2.css('width')), l:parseFloat($t2.css('left')), t:$t2.position().top}; // If they DO NOT intersect add it to this array return ((xd.t &gt; nd.t &amp;&amp; xd.t &gt; nd.t+nd.h) || (nd.t &gt; xd.t &amp;&amp; nd.t &gt; xd.t+xd.h)); }); // For every element that does not intersect, check it verse the ones that do $(nonIntersectArr).each(function(){ // nid is Non Intersecting Dimensions var $t2 = $(this), c = 0, nid = {h:$t2.height(), w:parseFloat($t2.css('width')), l:parseFloat($t2.css('left')), t:$t2.position().top}; $(intersectArr).each(function(){ // id is Intersecting Dimensions var $t3 = $(this), id = {h:$t3.height(), w:parseFloat($t3.css('width')), l:parseFloat($t3.css('left')), t:$t3.position().top}; // if the non intersecting hits one that is intersecting, then there is no space // beneath/near it, so we add it to the final intersecting array then increment c if((id.t &lt;= nid.t &amp;&amp; id.t+id.h &gt; nid.t) || (nid.t &lt;= id.t &amp;&amp; nid.t+nid.h &gt; id.t)){ finalArr.push(this); c++; } else { finalArr.push(this); } }); // if c has been incremented, we cant use this nonIntersect, so add it to the final if(c &gt; 0) { finalArr.push(this); } }); // make sure all items in the final Array are unique finalArr = $.unique(finalArr); // iterate over the final array, processing the dimensions of each element in the // array layering them so you can see each one $(finalArr).each(function(num){ // xd is Existing Dimensions, for the current item being checked // verse the one being added. var $t2 = $(this), xd = {h:$t2.height(), w:parseFloat($t2.css('width')), l:parseFloat($t2.css('left')), t:$t2.position().top}; if(((xd.t &lt;= nd.t &amp;&amp; xd.t+xd.h &gt; nd.t) || (nd.t &lt;= xd.t &amp;&amp; nd.t+nd.h &gt; xd.t))) { if(nd.l == xd.l){ nd.w = ((95/(finalArr.length+1))*1.5); xd.l = ((nd.w)*(num)); $(finalArr).each(function(ci){ $(this).css({left:((nd.w*ci)*0.58)+'%', width:((95/(finalArr.length+1))*1.5)+'%'}); nd.l = ((nd.w*ci)*0.58); }); } } }); } // Add the New Element to the container and position accordingly. nd.l = ((nd.l/finalArr.length)*(finalArr.length+1))+'%'; nd.w = nd.w+'%'; $('#container .subContainer').append('&lt;div style="top:'+nd.t+'px;left:'+nd.l+ ';width:'+nd.w+';height:'+nd.h+'px;" class="dragId_'+$t.attr('id')+ ' draggable"&gt;&lt;div class="title"&gt;'+$t.attr('title')+'&lt;/div&gt;&lt;/div&gt;'); </code></pre> <p>Any suggestions/help would be much appreciated. Thanks.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload