问题
I'm attempting to use jQuery Masonry in a project and it's not working properly: there's a gap in the top-right corner of the grid. I've tried adjusting the grid width and margins, which results in either one block per row or all blocks being run together (but still with a gap topright.)
It doesn't actually look like the blocks are being rearranged at all, though Masonry is applying its class and assigning absolute positioning to the elements as expected.
I was convinced that I was doing something wrong, but now I'm not so sure. I've taken a working fiddle from a similar question on Stack (http://stackoverflow.com/questions/11695574/jquery-masonry-almost-always-empty-spaces) and carefully modified it to use the dimensions I'm working with, and it just seems to be incapable of handling this selection of elements.
Fiddle: http://jsfiddle.net/dVPA9/4/
回答1:
Well, not really a solution to your issue, so I hope you won't down vote on me.
I have been using these two other projects with great success:
- https://github.com/yconst/Freetile
- http://www.wookmark.com/jquery-plugin
There is also:
- https://github.com/xlune/jQuery-vGrid-Plugin
Sincerely,
回答2:
With Masonry and Isotope for that matter, you need to remember that it all works on a module, meaning that your column widths should adhere to a least common divisor (in pixels). Then, if you have elements spanning more than one column (one module), depending on the available screen real estate (you have huge elements) the second element (much wider than first) can't be fitted to the right of the first element (much narrower than second).
Also, you're setting a fixed width to your masonry #container (#grid) which of course defies the whole purpose of the plugin.
See for yourself: remove width: 1104px; on your #grid and zoom your browser view out to the max on your fiddle page - you will see that if there's space, the second (wide black) element will eventually fit to the right of the first (narrow grey) element.
So, it all just comes down to finding a suitable least common divisor for your column width and making sure some elements aren't too large and don't span too many columns (more than two). Then it will work.
See also https://stackoverflow.com/a/11814339/963514 and https://stackoverflow.com/a/11701171/963514 to see for more explanations of similar "problems".
回答3:
As apparently this is an indelible issue with Masonry and similar solutions, I decided I'd need to roll my own here. I also decided this would be better handled in PHP, as the default, floated DIVs will have large gaps in a lot of circumstances.
Here's the algorithm I used, with comments to explain the fine points. This could have been done in jQuery trivially as well, but on the downside it'd look nasty for users without JavaScript.
$LeftPos = 0; //Tracks where we are on the grid. Our item grid is three wide, but some items may use up to three units of space.
$j = 0; //Using a second counter to track total iterations. This is to prevent infinite loops, either because of future concerns I can't predict or because of someone setting a content block to be wider than the containing grid.
for ($i = 0; $i < sizeOf($Items); $i++){
if ($LeftPos == 3){ $LeftPos = 0; } //If we filled the third column on the last iteration, we loop back round.
if ($Items[$i]['Placed'] !== true){ //If we've already put this object into the new array, skip it.
if ($Items[$i]['SpanWidth'] + $LeftPos <= 3 || $j > (sizeOf($Items) * 3)){ //If inserting this would push us past the third column, save it for when we have more room. But if we've looped over the entire array three times, chances are we're stuck for some reason so just vomit everything out so the user can look at SOMETHING, even if it's an ugly page.
$Placed++; //Increment the counter for placed objects.
$Items[$i]['Placed'] = true; //Set this item as placed, too.
$NewProducts[$i] = $Items[$i]; //Add the current item to the new array.
$LeftPos = $LeftPos+ $Items[$i]['SpanWidth']; //And calculate our new position on the grid.
}
}
if (($i+1 == sizeOf($Items) && $Placed < sizeOf($Items))) {$i = 0;} //If we reach the end and we have placed less items than we have total, loop through again.
}
来源:https://stackoverflow.com/questions/12521687/jquery-masonry-leaving-gap