Fit colliding elements in a container dynamically

I have absolutely positioned elements with different position.top and height generated from the database.

All I'm trying to do is not run into these elements by sliding them to the right when adjusting the width so that it fits inside the <body> container.

I had a problem applying the "left" position to the colliding elements.

I use https://sourceforge.net/projects/jquerycollision/ for collision detection.

Here's what the last image should look like:

screenshot

 $('div').each(function() { var name = $(this).text(); var hits = $(this).collision('div').not(this); // Find colliding elements console.log(name + ' collides with: ' + hits.length + ' others'); if (hits.length > 0) { var widthAll = 100 / (hits.length + 1); // Shift colliding elements to the right with equal width $(hits).add(this).each(function(i) { var name = $(this).text(); $(this).css({ 'left': widthAll * i + '%', 'width': widthAll + '%' }); }); } }); 
 div { position: absolute; width: 10em; font-size: 0.75em; color: white; } .blue { top: 0; height: 80%; background-color: blue; } .red { top: 15%; height: 5%; background-color: red; } .yellow { top: 17%; height: 10%; background-color: yellow; color: black; } .green { top: 30%; height: 5%; background-color: green; } .magenta { top: 36%; height: 3%; background-color: magenta; } .cyan { top: 50%; height: 5%; background-color: cyan; color: black; } .brown { top: 81%; height: 5%; background-color: brown; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <script src="https://rawgit.com/dsbaars/jquery-collision/master/js/jquery-collision.min.js"></script> <div class='blue'>blue</div> <div class='red'>red</div> <div class='yellow'>yellow</div> <div class='green'>green</div> <div class='magenta'>magenta</div> <div class='cyan'>cyan</div> <div class='brown'>brown</div> 
+5
source share
1 answer

I think I executed your code according to your request. The idea is this:

  • The first block of code shifts the div to the right so that they do not overlap.
  • The second block makes the width of the divs evenly distributed over the size of the body.
  • The last block increases the width of the rest of the div to take up the remaining space.

 "use strict"; var divs = $('div'), mx = 0, mxs = [0], bw = $("body").outerWidth(), steps = 1; divs.each(function(i) { for (var j = i + 1; j < divs.length; j++) { if (!$(this).data("x")) $(this).data("x", 0); if (j < divs.length) { var hit = $(this).collision(divs[j]); if (hit.length) { hit = $(divs[j]); hit.css("left", "+=" + Math.ceil($(this).outerWidth())); hit.data("x", hit.position().left); if (mx < hit.data("x")) { mxs.push(mx = hit.data("x")); steps++; } } } } }); divs.each(function(i) { let iw = $(this).outerWidth(), fw = bw / steps; $(this).outerWidth(fw); for (var j = i + 1; j < divs.length; j++) { $(this).collision(divs[j]).css("left", "+=" + Math.ceil((fw - iw) * mxs.indexOf($(divs[j]).data("x")))); } }); divs.each(function() { var os = $(this).outerWidth(), ts = bw - $(this).position().left; $(this).outerWidth(ts); if ($(this).collision(divs).not(this).length) { $(this).outerWidth(os); } }); 
 body { margin: 0; } div { position: absolute; width: 10em; font-size: 0.75em; color: white; left: 0; } .blue { top: 0; height: 80%; background-color: blue; } .red { top: 15%; height: 5%; background-color: red; } .yellow { top: 17%; height: 10%; background-color: yellow; color: black; } .green { top: 20%; height: 50%; background-color: green; } .magenta { top: 36%; height: 3%; background-color: magenta; } .cyan { top: 50%; height: 5%; background-color: cyan; color: black; } .brown { top: 81%; height: 5%; background-color: brown; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://rawgit.com/dsbaars/jquery-collision/master/js/jquery-collision.min.js"></script> <div class='blue'>blue</div> <div class='red'>red</div> <div class='yellow'>yellow</div> <div class='green'>green</div> <div class='magenta'>magenta</div> <div class='cyan'>cyan</div> <div class='brown'>brown</div> 

The above fragment does not respond. If you want it to be responsive, just listen to the resize event, change the bw value and repeat the code blocks 2 and 3.

As mentioned in the comments: jquery-collision.min.js had some fatal errors, therefore, as suggested by Alex G , https://www.48design.de/de/news/2009/11/20/kollisionsabfrage-per-jquery- plugin-update-v11 / may be an alternative.

+1
source

Source: https://habr.com/ru/post/1263411/


All Articles