这个东西让我想起了俄罗斯方块,这个实现起来很简单,容器里面所有的块元素用绝对定位排列,如果能放的下就放在这里,如果放不下了,在队列中找到能放得下的元素放置, 实在找不到,则换行排列下一行,具体思路是这样。代码里有详细的注释直接看代码吧。 下面是一个demo: http://demo.jb51.net/js/2012/sortRect/代码打包下载 sortRect.rar 复制代码 代码如下: 不规则宽高排列 <BR> <BR> <BR>.box { <BR>position: absolute; <BR>width: 100px; <BR>height: 100px; <BR>border: 1px solid #ffffff; <BR>display: none; <BR>background: url(img/1.jpg); <BR>/*margin-left: 4px; <BR>margin-top: 4px;*/ <BR>} <BR>.box2 { <BR>position: absolute; <BR>width: 100px; <BR>height: 202px; <BR>border: 1px solid #ffffff; <BR>display: none; <BR>background: url(img/2.jpg); <BR>/*margin-left: 4px; <BR>margin-top: 4px;*/ <BR>} <BR>.box3 { <BR>position: absolute; <BR>width: 202px; <BR>height: 100px; <BR>border: 1px solid #ffffff; <BR>display: none; <BR>background: url(img/3.jpg); <BR>/*margin-left: 4px; <BR>margin-top: 4px;*/ <BR>} <BR>.box4 { <BR>position: absolute; <BR>width: 202px; <BR>height: 202px; <BR>border: 1px solid red; <BR>background: url(img/4.jpg); <BR>display: none; <BR>} <BR> <BR>//初始化矩阵 <BR>var initMatrix = function(x, y){ <BR>if (!x || !y) { <BR>return; <BR>} <BR>x = ~ ~ x; <BR>y = ~ ~ y; <BR>var mt = []; <BR>var i = 0; <BR>var getX = function(xl){ <BR>var i = 0; <BR>var matrixX = []; <BR>for (; i < xl; i++) { <BR>matrixX[i] = 0; <BR>} <BR>return { <BR>mt: matrixX, <BR>isComplete: false, <BR>spaces: [{ <BR>index: 0, <BR>len: matrixX.length <BR>}] <BR>}; <BR>} <BR>for (; i < y; i++) { <BR>mt[i] = getX(x); <BR>} <BR>return mt; <BR>} <BR>//生成元素相应的队列 <BR>var getQuene = function(eleColl, base){ <BR>if (!eleColl) { <BR>return; <BR>} <BR>var quene = []; <BR>var i = 0; <BR>var len = eleColl.length; <BR>var getEleMatrix = function(ele, base){ <BR>var ht = ele.outerHeight() / base.height; <BR>var wt = ele.outerWidth() / base.width; <BR>return { <BR>ele: ele, <BR>ht: ht, <BR>wt: wt <BR>} <BR>} <BR>for (; i < len; i++) { <BR>quene[i] = getEleMatrix($(eleColl[i]), base); <BR>} <BR>return quene; <BR>} <BR>//以行为单位扫描矩阵 <BR>var sortEveryEle = function(pannelMatrix, sortQuene, unitEle, callback){ <BR>if (!pannelMatrix || !sortQuene) { <BR>return; <BR>} <BR>unitEle = unitEle || <BR>{ <BR>width: 0, <BR>height: 0 <BR>}; <BR>var checkSpace = function(line){ <BR>var i = 0; <BR>var len = line.mt.length; <BR>var tmpWt = 0; <BR>var tmpidx = 0; <BR>var tmpQuene = []; <BR>var isSetIdx = false; <BR>for (; i < len; i++) { <BR>if (line.mt[i] == 0) { <BR>if (!isSetIdx) { <BR>tmpidx = i; <BR>isSetIdx = true; <BR>} <BR>tmpWt++; <BR>} <BR>if ((line.mt[i] == 1) || (i == len - 1)) { <BR>//保存space信息到里面队列 <BR>if (tmpWt > 0) { <BR>tmpQuene.push({ <BR>index: tmpidx, <BR>len: tmpWt <BR>}); <BR>} <BR>//清空临时信息 <BR>tmpidx = 0; <BR>tmpWt = 0; <BR>} <BR>} <BR>if (tmpQuene.length <= 0) { <BR>line.isComplete = true; <BR>} <BR>line.spaces = tmpQuene; <BR>return; <BR>} <BR>var updateMartix = function(curLine, mt, ele, spidx, lineNum){ <BR>var i = j = 0; <BR>//获取当前空白信息 <BR>var sp = curLine.spaces[spidx]; <BR>//如果占用多行则更新所有占用行的空间 <BR>if (ele.ht > 1) { <BR>j = 0; <BR>for (; j < ele.ht; j++) { <BR>i = 0; <BR>for (; i < ele.wt; i++) { <BR>mt[lineNum + j].mt[sp.index + i] = 1; <BR>} <BR>//更新空白空间 <BR>checkSpace(mt[lineNum + j]); <BR>} <BR>} <BR>else {//如果是单行的话只要更新第一个本行 <BR>for (; i < ele.wt; i++) { <BR>curLine.mt[sp.index + i] = 1; <BR>} <BR>//更新模块 <BR>checkSpace(curLine); <BR>} <BR>}; <BR>//获取合适的元素 <BR>var getRightEle = function(stQu, wd){ <BR>var i = 0; <BR>var len = stQu.length; <BR>for (; i < len; i++) { <BR>if (stQu[i].wt <= wd) { <BR>return stQu.splice(i, 1); <BR>} <BR>} <BR>return; <BR>} <BR>//扫描单行 <BR>var scanLine = function(oneLine, sortQuene, mt, lineNum){ <BR>var i = 0; <BR>var len = oneLine.spaces.length; <BR>//填充 <BR>var theWt = oneLine.spaces[i].len; <BR>var mtLeft = mtTop = 0; <BR>//判断能容纳的宽是多少 <BR>var rtEle = getRightEle(sortQuene, theWt); <BR>if (rtEle) { <BR>//放置元素 <BR>//rtEle[0].ele.css("left", oneLine.spaces[i].index * 102);//base width <BR>//rtEle[0].ele.css("top", lineNum * 102);//base height; <BR>mtLeft = oneLine.spaces[i].index * (unitEle.width || 0); <BR>mtTop = lineNum * (unitEle.height || 0); <BR>if (callback) { <BR>callback({ <BR>left: mtLeft, <BR>top: mtTop, <BR>rect: rtEle[0] <BR>}); <BR>} <BR>//更新矩阵 <BR>updateMartix(oneLine, mt, rtEle[0], i, lineNum); <BR>//返回位置队列 <BR>return { <BR>left: mtLeft, <BR>top: mtTop, <BR>rect: rtEle[0] <BR>} <BR>} <BR>} <BR>var i = j = 0; <BR>var pmLen = pannelMatrix.length; <BR>var completeLine = 0; <BR>var thePosQuene = [], pos; <BR>for (; i < pmLen; i++) { <BR>while (!pannelMatrix[i].isComplete && (sortQuene.length > 0)) { <BR>pos = scanLine(pannelMatrix[i], sortQuene, pannelMatrix, i); <BR>if (pos) { <BR>thePosQuene.push(pos); <BR>} <BR>} <BR>} <BR>return thePosQuene; <BR>} <BR>var con = $("#con"); <BR>//生成相关的二维数组 <BR>var baseWidth = 102; <BR>var baseHeight = 102; <BR>var base = { <BR>width: baseWidth, <BR>height: baseHeight <BR>} <BR>var pannel = $("#pannel"); <BR>var thePannelSize = { <BR>width: pannel.width(), <BR>height: pannel.height() <BR>}; <BR>var pannelMatrix = initMatrix(thePannelSize.width / baseWidth, thePannelSize.height / baseHeight); <BR>//得到要排序的不规则宽高的方块队列 <BR>var sortQuene = getQuene(pannel.find("div"), base); <BR>//遍历matrix <BR>var theQu = sortEveryEle(pannelMatrix, sortQuene, base); <BR>var theQuOne = theQu.shift(); <BR>var selfCall = function(){ <BR>if (!theQuOne) { <BR>return; <BR>} <BR>var my = arguments.callee; <BR>theQuOne.rect.ele.show().animate({ <BR>left: "+" + theQuOne.left, <BR>top: "+" + theQuOne.top <BR>}, { <BR>duration: 1000, <BR>easing: "easeOutBounce", <BR>complete: function(){ <BR>theQuOne = theQu.shift(); <BR>my.call(); <BR>} <BR>}); <BR>} <BR>selfCall(); <br><br>