目标是生成流体布局,如下所示。
到目前为止,我有一个工作函数moveBox(lastBox, "east")
,可以跟踪行索引和列索引。
function moveBox(box, where) {
switch (where) {
case "north":
lastTopOffset -= BOX_HEIGHT + BOX_MARGIN;
box.style.top = lastTopOffset + 'px';
box.style.left = lastLeftOffset + 'px';
rowIndex -= 1;
break;
// ...
}
我的current code,
(function () {
var i, lastBox,
MAX_DIVS = 72,
BOX_HEIGHT = 50,
BOX_WIDTH = 100,
BOX_MARGIN = 5,
field = document.getElementById('fieldPerimeter'),
fieldHeight = field.offsetHeight,
maxRows = Math.floor(fieldHeight / (BOX_HEIGHT + BOX_MARGIN)),
rowIndex = 0,
colIndex = 0,
lastLeftOffset = 0,
lastTopOffset = 0;
function moveBox(box, where) {
switch (where) {
case "north":
lastTopOffset -= BOX_HEIGHT + BOX_MARGIN;
box.style.top = lastTopOffset + 'px';
box.style.left = lastLeftOffset + 'px';
rowIndex -= 1;
break;
case "east":
lastLeftOffset += BOX_WIDTH + BOX_MARGIN;
box.style.top = lastTopOffset + 'px';
box.style.left = lastLeftOffset + 'px';
colIndex += 1;
break;
case "south":
lastTopOffset += BOX_HEIGHT + BOX_MARGIN;
box.style.top = lastTopOffset + 'px';
box.style.left = lastLeftOffset + 'px';
rowIndex += 1;
break;
default:
break;
}
}
for (i = 0; i < MAX_DIVS; i += 1) {
lastBox = document.createElement('div');
lastBox.className = 'box';
lastBox.innerHTML = i;
field.appendChild(lastBox);
//delete me
if( (i + 1) % 2 === 0 || (i + 1)% 3 === 0){
moveBox(lastBox, "east");
} else {
moveBox(lastBox, "south");
}
//delete me
// if(rowIndex < maxRows && rowIndex > 0){
// if (colIndex % 4 === 0){
// moveBox(lastBox, "south");
// } else if (colIndex % 2 === 0){
// moveBox(lastBox, "north");
// } else {
// moveBox(lastBox, "east");
// }
// }
}
})();
将div附加到容器然后移动它。下面的代码显示了我指定何时移动北或南的部分尝试。但我正在努力实现理想的布局。
if (colIndex % 4 === 0) { moveBox(lastBox, "south"); }
else if (colIndex % 2 === 0) { moveBox(lastBox, "north"); }
else { moveBox(lastBox, "east"); }
答案 0 :(得分:5)
这是工作小提琴,http://jsfiddle.net/efortis/zuY74/
注意我为了处理小提琴而对offsetHeight
进行了硬编码,并在顶部添加了lastMove
变量。
for (i = 0; i < MAX_DIVS; i += 1) {
lastBox = document.createElement('div');
lastBox.className = 'box';
lastBox.innerHTML = i;
field.appendChild(lastBox);
if (i === 0) {
rowIndex += 1;
} else {
if (colIndex % 4 === 0 && rowIndex < maxRows) {
moveBox(lastBox, "south");
lastMove = "south";
} else if (colIndex % 2 === 0 && rowIndex !== 1 && lastMove !== "south") {
moveBox(lastBox, "north");
lastMove = "north";
} else {
moveBox(lastBox, "east");
lastMove = "east";
}
}
}
答案 1 :(得分:2)
以下适用于网格位置而不是像素,我们的想法是您可以毫无困难地将网格位置转换为像素。
我的网格非常简单。左上角是(0, 0)
。因此,您的方框0位于(0, 0)
,方框7位于(1, 6)
等,
如果您有maxrows
行,则第一个maxrows-1
项会进入(0, 0)
,(0, 1)
等。项maxrows
进入{{1} }}。下一个(1, maxrows-1)
项目会显示maxrows-1
,(maxrows-1,2)
等,而(maxrows-2, 2)
的项目会显示在2*maxrows
。
您应该能够从数字中计算项目在网格中的位置。在这里假设整数数学。
(0, 3)
此时,您将拥有框应该移动的网格位置。现在通过将// xblock treats each two columns as a single entity.
xblock = itemNo / (maxrows + 1);
xpos = 2 * xblock;
ypos = itemNo % (maxrows + 1);
if (ypos == maxrows)
{
// this is the last item, so we need to shift it.
xpos += 1;
ypos = maxrows - 1;
}
// Now, turn things upside down if xblock is odd
if ((xblock % 2) == 1 && ypos != maxrows)
{
ypos = maxrows - ypos - 1;
}
乘以xpos
并添加偏移量将网格位置转换为像素应该是一件简单的事情。对BOX_WIDTH
和ypos
执行相同的操作。
答案 2 :(得分:0)
我注意到这是布局中反复出现的模式: 从0开始
-
var MOVES_DONE = 0;
var MOVES_LIMIT = 72;
/*
* First define the three movement functions that we will use
* (right, down and left)
*/
function up(box) {
console.log("up");
}
function down(box) {
console.log("down");
}
function right(box) {
console.log("right");
}
/*
* Solution 1:
* Starting from the top-left corner do the necessary moves to complete the
* layout:
---------------------------------
| |
box, up, right, right,
down, up, start_over
down, up,
down, up,
down, up,
down, up,
down, right, right,
*/
var moves = [down, down, down, down, down, down, right, right,
up, up, up, up, up, up, right, right];
var len_moves = moves.length;
while(MOVES_DONE < MOVES_LIMIT) {
moves[MOVES_DONE % len_moves](box);
MOVES_DONE ++;
}
解决方案2使用相同的运动功能:
/**
* Create a function that will apply a movement type to a box "times" times
* For example move(down, 6)(box) will
* move the box down 6 times if moves_done < moves_limit
*/
function move(move_type_function, times) {
return function(box) {
for (var i = 0; i < times, i + MOVES_DONE < MOVES_LIMIT; i++) {
move_type_function(box);
}
return i;
}
}
/**
* This is a complete cycle of the recurring pattern of the layout assuming that
* we are starting with the box positioned at the
*/
var moves = [move(down, 6), move(right, 2), move(up, 6), move(right, 2)];
while(MOVES_DONE < MOVES_LIMIT) {
MOVES_DONE += moves[MOVES_DONE % moves.length](box)
}
PS:我没有时间在浏览器中测试这个,所以可能会有一些错误:)