网页瀑布流布局实现方法及功能扩展(附完整代码)
2014-05-18 11:56
721 查看
图片分享网站Pinterest(beta),在不久前获得了2700$的投资,估值已超2亿元(据说现该公司团队有8人)。该网站的一大特色就是每一张分享的图片被拟作“Pin”被钉在页面上面,每一Pin依尺寸智能排列,同时滚动页面时异步加载新Pin,极具效果。这种创新模式被在国内也被广泛copy,其中最有前途的当属Mark之,以“Mark”代“Pin”,也算有些想法。
下面简单模拟下这种布局,这种布局在国内有人称之为瀑布流,当然这个名称主要还是指Pin在异步加载时的效果,而这个在本demo并没有做。(本demo兼容所有浏览器,但还是建议你使用firefox,chrome等浏览器,效果更佳)<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<title>等宽格子堆砌</title>
<style>
*{padding:0;margin:0;}
#wrap{position:relative;zoom:1;margin:0px auto;}
#wrap li{width:250px;float:left;list-style:none;}
.boxCont{position:relative;margin:15px;border:1px solid #ccc;background:#eee;
background: -webkit-gradient(linear, 0% 20%, 0% 92%, from(#fff), to(#f3f3f3), color-stop(.1,#fff));
background: -webkit-linear-gradient(0 0 270deg, #f3f3f3, #f3f3f3 10%, #fff);
background: -moz-linear-gradient(0 0 270deg, #f3f3f3, #f3f3f3 10%, #fff);
background: -o-linear-gradient(0 0 270deg, #f3f3f3, #f3f3f3 10%, #fff);
-webkit-border-radius: 60px / 5px;
-moz-border-radius: 60px / 5px;
border-radius:60px / 5px;
-webkit-box-shadow: 0px 0px 35px rgba(0, 0, 0, 0.1) inset;
-moz-box-shadow: 0px 0px 35px rgba(0, 0, 0, 0.1) inset;
box-shadow: 0px 0px 35px rgba(0, 0, 0, 0.1) inset;
}
.boxCont:before{
content: '';
width: 50px;
height: 50px;
top:0; right:0;
position:absolute;
display: inline-block;
z-index:-1;
-webkit-box-shadow: 10px -10px 8px rgba(0, 0, 0, 0.2);
-moz-box-shadow: 10px -10px 8px rgba(0, 0, 0, 0.2);
box-shadow: 10px -10px 8px rgba(0, 0, 0, 0.2);
-webkit-transform: rotate(2deg) translate(-14px,20px) skew(-20deg);
-moz-transform: rotate(2deg) translate(-14px,20px) skew(-20deg);
-o-transform: rotate(2deg) translate(-14px,20px) skew(-20deg);
transform: rotate(2deg) translate(-14px,20px) skew(-20deg);
}
.boxCont:after{
content: '';
width: 100px;
height: 100px;
top:0; left:0;
position:absolute;
z-index:-1;
display: inline-block;
-webkit-box-shadow: -10px -10px 10px rgba(0, 0, 0, 0.2);
-moz-box-shadow: -10px -10px 10px rgba(0, 0, 0, 0.2);
box-shadow: -10px -10px 10px rgba(0, 0, 0, 0.2);
-webkit-transform: rotate(2deg) translate(20px,25px) skew(20deg);
-moz-transform: rotate(2deg) translate(20px,25px) skew(20deg);
-o-transform: rotate(2deg) translate(20px,25px) skew(20deg);
transform: rotate(2deg) translate(20px,25px) skew(20deg);
}
</style>
</head>
<body>
<ul id="wrap"></ul>
</body>
<script type="text/javascript">
var $id = function(o){ return document.getElementById(o) || o};
function sort(el){
var h = [];
var box = el.getElementsByTagName("li");
var minH = box[0].offsetHeight,
boxW = box[0].offsetWidth,
boxH,
n = document.documentElement.offsetWidth / boxW | 0; //计算页面能排下多少Pin
el.style.width = n * boxW + "px";
for(var i = 0; i < box.length; i++) {
boxh = box[i].offsetHeight; //获取每个Pin的高度
if(i < n) { //第一行Pin以浮动排列,不需绝对定位
h[i] = boxh;
box[i].style.position = '';
} else {
minH = Math.min.apply({},h); //取得各列累计高度最低的一列
minKey = getarraykey(h, minH);
h[minKey] += boxh ; //加上新高度后更新高度值
box[i].style.position = 'absolute';
box[i].style.top = minH + 'px';
box[i].style.left = (minKey * boxW) + 'px';
}
}
};
/* 返回数组中某一值的对应项数 */
function getarraykey(s, v) {
for(k in s) {
if(s[k] == v) {
return k;
}
}
};
/* 随机创建Pin */
var pin = '';
for(i = 0; i < 30; i++) {
height = Math.floor(Math.random()*200 + 200);
pin += '<li><div class="boxCont" style="height:' + height + 'px;"></div></li>';
};
$id("wrap").innerHTML = pin;
window.onload = window.onresize = function() {
sort($id("wrap"));
};
</script>
</html>
这种布局中虽然每个Pin的高度不尽相同,但是他们的宽度都是一样的。
那么假如,很邪恶的提出一个要求,宽度也不尽相同,只是说宽高都按比例成倍增加,那还怎么排列呢?呵呵,如下:
现在这种布局已经不能叫瀑布流了,我们称之为格子块,格子块通过算法智能堆砌。
到最后,说点下睛也好,说添下足也好,我们再加一个拖动交换格子的效果。
下面简单模拟下这种布局,这种布局在国内有人称之为瀑布流,当然这个名称主要还是指Pin在异步加载时的效果,而这个在本demo并没有做。(本demo兼容所有浏览器,但还是建议你使用firefox,chrome等浏览器,效果更佳)<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<title>等宽格子堆砌</title>
<style>
*{padding:0;margin:0;}
#wrap{position:relative;zoom:1;margin:0px auto;}
#wrap li{width:250px;float:left;list-style:none;}
.boxCont{position:relative;margin:15px;border:1px solid #ccc;background:#eee;
background: -webkit-gradient(linear, 0% 20%, 0% 92%, from(#fff), to(#f3f3f3), color-stop(.1,#fff));
background: -webkit-linear-gradient(0 0 270deg, #f3f3f3, #f3f3f3 10%, #fff);
background: -moz-linear-gradient(0 0 270deg, #f3f3f3, #f3f3f3 10%, #fff);
background: -o-linear-gradient(0 0 270deg, #f3f3f3, #f3f3f3 10%, #fff);
-webkit-border-radius: 60px / 5px;
-moz-border-radius: 60px / 5px;
border-radius:60px / 5px;
-webkit-box-shadow: 0px 0px 35px rgba(0, 0, 0, 0.1) inset;
-moz-box-shadow: 0px 0px 35px rgba(0, 0, 0, 0.1) inset;
box-shadow: 0px 0px 35px rgba(0, 0, 0, 0.1) inset;
}
.boxCont:before{
content: '';
width: 50px;
height: 50px;
top:0; right:0;
position:absolute;
display: inline-block;
z-index:-1;
-webkit-box-shadow: 10px -10px 8px rgba(0, 0, 0, 0.2);
-moz-box-shadow: 10px -10px 8px rgba(0, 0, 0, 0.2);
box-shadow: 10px -10px 8px rgba(0, 0, 0, 0.2);
-webkit-transform: rotate(2deg) translate(-14px,20px) skew(-20deg);
-moz-transform: rotate(2deg) translate(-14px,20px) skew(-20deg);
-o-transform: rotate(2deg) translate(-14px,20px) skew(-20deg);
transform: rotate(2deg) translate(-14px,20px) skew(-20deg);
}
.boxCont:after{
content: '';
width: 100px;
height: 100px;
top:0; left:0;
position:absolute;
z-index:-1;
display: inline-block;
-webkit-box-shadow: -10px -10px 10px rgba(0, 0, 0, 0.2);
-moz-box-shadow: -10px -10px 10px rgba(0, 0, 0, 0.2);
box-shadow: -10px -10px 10px rgba(0, 0, 0, 0.2);
-webkit-transform: rotate(2deg) translate(20px,25px) skew(20deg);
-moz-transform: rotate(2deg) translate(20px,25px) skew(20deg);
-o-transform: rotate(2deg) translate(20px,25px) skew(20deg);
transform: rotate(2deg) translate(20px,25px) skew(20deg);
}
</style>
</head>
<body>
<ul id="wrap"></ul>
</body>
<script type="text/javascript">
var $id = function(o){ return document.getElementById(o) || o};
function sort(el){
var h = [];
var box = el.getElementsByTagName("li");
var minH = box[0].offsetHeight,
boxW = box[0].offsetWidth,
boxH,
n = document.documentElement.offsetWidth / boxW | 0; //计算页面能排下多少Pin
el.style.width = n * boxW + "px";
for(var i = 0; i < box.length; i++) {
boxh = box[i].offsetHeight; //获取每个Pin的高度
if(i < n) { //第一行Pin以浮动排列,不需绝对定位
h[i] = boxh;
box[i].style.position = '';
} else {
minH = Math.min.apply({},h); //取得各列累计高度最低的一列
minKey = getarraykey(h, minH);
h[minKey] += boxh ; //加上新高度后更新高度值
box[i].style.position = 'absolute';
box[i].style.top = minH + 'px';
box[i].style.left = (minKey * boxW) + 'px';
}
}
};
/* 返回数组中某一值的对应项数 */
function getarraykey(s, v) {
for(k in s) {
if(s[k] == v) {
return k;
}
}
};
/* 随机创建Pin */
var pin = '';
for(i = 0; i < 30; i++) {
height = Math.floor(Math.random()*200 + 200);
pin += '<li><div class="boxCont" style="height:' + height + 'px;"></div></li>';
};
$id("wrap").innerHTML = pin;
window.onload = window.onresize = function() {
sort($id("wrap"));
};
</script>
</html>
这种布局中虽然每个Pin的高度不尽相同,但是他们的宽度都是一样的。
那么假如,很邪恶的提出一个要求,宽度也不尽相同,只是说宽高都按比例成倍增加,那还怎么排列呢?呵呵,如下:
<!doctype html> <html> <head> <meta charset="UTF-8" /> <title>宽高尺寸不同的格子堆砌</title> <style> body{background:#F6F7F8;} .myWidget{position:relative;overflow:hidden;zoom:1;margin:0 auto;} .MBox{float:left;} .widgetBox{position:relative;overflow:hidden;zoom:1;width:186px;height:166px;margin:6px;border:1px solid #E1E1E3; border-radius:10px; -moz-border-radius:10px; -webkit-border-radius:10px; box-shadow:2px 3px 5px #d3d3d3; -moz-box-shadow:2px 3px 5px #d3d3d3; -webkit-box-shadow:2px 3px 5px #d3d3d3; filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#fefefe, endColorstr=#e0e0e2); background: linear-gradient(top, #fefefe, #f6f6f6 ,#f3f3f3,#f2f2f2,#e0e0e2); background: -moz-linear-gradient(top, #fefefe, #f6f6f6 ,#f3f3f3,#f2f2f2,#e0e0e2); background: -webkit-gradient(linear, 0 0, 0 100% , from(#fefefe),to(#e0e0e2)); background: -webkit-linear-gradient(0 0, #fefefe, #f6f6f6 ,#f3f3f3,#f2f2f2,#e0e0e2); } </style> <script> var $id = function(o){ return document.getElementById(o) || o ;}; var getElementsByClassName = function(className,parent,tag) { parent = parent || document; if(parent.getElementsByClassName){ return parent.getElementsByClassName(className) }else{ tag = tag || '*'; var returnElements = [] var els = parent.getElementsByTagName(tag); className = className.replace(/\-/g, "\\-"); var pattern = new RegExp("(^|\\s)"+className+"(\\s|$)"); var i = 0; while(i < els.length){ if (pattern.test(els[i].className) ) { returnElements.push(els[i]); } i++; } return returnElements; } }; /* 格子排序 */ var box={}; box.gen={w:200,h:180}; box.init=function(el){ box.size=[]; //格子,[1,2]表示1X2的大格子 box.obj={}; box.oArray=[]; box.maxY=-1; box.mbox = getElementsByClassName("MBox",el,'div'); box.row = document.documentElement.offsetWidth / box.gen.w >> 0; //每行标准格数 el.style.width = box.row * box.gen.w + "px"; var i = 0 , nx, ny; while( i < this.mbox.length){ if( getElementsByClassName("bigBox",this.mbox[i],'div').length > 0 ){ nx=Math.ceil(this.mbox[i].offsetWidth / this.gen.w); nx=(nx > this.row) ? this.row : nx; //大小超出限制 ny=Math.ceil(this.mbox[i].offsetHeight / this.gen.h); this.size.push([nx,ny]); }else{ this.size.push(1); } i++; } box.sort(el); }; box.setIfr=function(el){ //大格子初始化 var ifr = getElementsByClassName("bigBox",el,'div');; if(ifr.length==0) return false; var i = 0, nx, ny, theifr; while(i < ifr.length){ theifr = getElementsByClassName("innerBox",ifr[i],'div'); nx=Math.ceil(theifr[0].offsetWidth / this.gen.w); //bigBox横向占的块数 ny=Math.ceil(theifr[0].offsetHeight / this.gen.h); ifr[i].style.width = nx*this.gen.w-14 + 'px' ; ifr[i].style.height = ny*this.gen.h-14 + 'px' ; i++; } }; box.sort=function(el){ var y=0, x=0, temp={x:Infinity, y:Infinity}, flag=Infinity, name; for(var n=0; n < this.size.length ; n++){ if(flag == 0){ x=temp.x; y=temp.y; } flag=flag-1; if(x>box.row-1){ //换行 x=0; y++; } name=x+'_'+y; //对象属性名(反映占领的格子) if(this.hasN(name)) { //判断属性名是否存在 n--; x++; if(flag<Infinity) flag=flag+1; continue; } if(!this.size .length){ //普通格子 this.obj[name]=[x,y]; //项值(反映坐标值) x++; } else{ //大格子 if(this.over(x,y,n)) { if(temp.y > y){ temp.y = y; temp.x = x; } if(temp.y < Infinity){ flag=1; } n--; x++; continue; } this.obj[name]=[x,y]; this.apply(x,y,n); x+=this.size [0]; } if(flag==-1) { flag = Infinity; temp.y = Infinity; temp.x = Infinity; } var h=this.size [1]-1 || 0; box.maxY=(box.maxY > y+h)? box.maxY : y+h; } for(var i in this.obj){ if(this.obj[i]===0 || !this.obj.hasOwnProperty(i)) continue; this.oArray.push(this.obj[i]); } box.put(el); }; box.hasN=function(n){ return n in this.obj; }; box.over=function(x,y,n){ //判断是否会重叠 var name; if(x+this.size [0] > this.row) return true; //超出显示范围 for(var k=1; k<this.size [1];k++ d290 ){ name=x+'_'+(y-0+k); if(this.hasN(name)) {return true;} //左侧一列有无重叠 } for(k=1; k<this.size [0];k++){ name=(x-0+k)+'_'+y; if(this.hasN(name)) {return true;} //上侧一行有无重叠 } return false; }; box.apply=function(x,y,n){ //大格子中多占的位置 var posX=x, //大格子左上角位置 posY=y; for(var t=0; t<this.size [0]; t++) { for(var k=0; k<this.size [1]; k++){ name=(posX+t)+'_'+(posY+k); if(t==0 && k==0) { continue; } this.obj[name]=0; //多占的格子无坐标值 } } }; box.put=function(el){ var x,y; for(var i =0;i< this.oArray.length; i++){ x=box.gen.w*this.oArray[i][0]; y=box.gen.h*this.oArray[i][1]; box.mbox[i].style.cssText = "position:absolute;left:"+ x +"px;top:" + y + "px;"; } el.style.height= box.gen.h*(box.maxY+1) +'px'; }; </script> </head> <body> <div id="myWidget" class="myWidget"></div> <script> var myWidget = $id("myWidget"); //创建随机内容 var content = ''; for(i = 0; i < 30; i++) { if(!(Math.random()*3 >> 0)){ height = Math.floor(Math.random()*200 + 100); width = Math.floor(Math.random()*200 + 100); content += '<div class="MBox"><div class="widgetBox bigBox"><div style="width:' + width +'px;height:' + height +'px;margin:0 auto;" class="innerBox"></div></div></div>'; }else{ content += '<div class="MBox"><div class="widgetBox"></div></div>'; } }; myWidget.innerHTML = content; window.onload = function(){ box.setIfr(myWidget); box.init(myWidget); }; window.onresize = function(){ box.init(myWidget); }; </script> </body> </html>
现在这种布局已经不能叫瀑布流了,我们称之为格子块,格子块通过算法智能堆砌。
到最后,说点下睛也好,说添下足也好,我们再加一个拖动交换格子的效果。
<!doctype html> <html> <head> <meta charset="UTF-8" /> <title>宽高尺寸不同的格子堆砌(可拖动换位)</title> <style> body{background:#F6F7F8;} .myWidget{position:relative;overflow:hidden;zoom:1;margin:0 auto;} .MBox{float:left;} .widgetBox{position:relative;overflow:hidden;zoom:1;width:186px;height:166px;margin:6px;border:1px solid #E1E1E3;cursor:move; border-radius:10px; -moz-border-radius:10px; -webkit-border-radius:10px; box-shadow:2px 3px 5px #d3d3d3; -moz-box-shadow:2px 3px 5px #d3d3d3; -webkit-box-shadow:2px 3px 5px #d3d3d3; filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#fefefe, endColorstr=#e0e0e2); background: linear-gradient(top, #fefefe, #f6f6f6 ,#f3f3f3,#f2f2f2,#e0e0e2); background: -moz-linear-gradient(top, #fefefe, #f6f6f6 ,#f3f3f3,#f2f2f2,#e0e0e2); background: -webkit-gradient(linear, 0 0, 0 100% , from(#fefefe),to(#e0e0e2)); background: -webkit-linear-gradient(0 0, #fefefe, #f6f6f6 ,#f3f3f3,#f2f2f2,#e0e0e2); } </style> <script> var $id = function(o){ return document.getElementById(o) || o ;}; var getElementsByClassName = function(className,parent,tag) { parent = parent || document; if(parent.getElementsByClassName){ return parent.getElementsByClassName(className) }else{ tag = tag || '*'; var returnElements = [] var els = parent.getElementsByTagName(tag); className = className.replace(/\-/g, "\\-"); var pattern = new RegExp("(^|\\s)"+className+"(\\s|$)"); var i = 0; while(i < els.length){ if (pattern.test(els[i].className) ) { returnElements.push(els[i]); } i++; } return returnElements; } }; var Util = new Object(); Util.getOffset = function (el, isLeft) { var retValue = 0; // while (el != null) { retValue += el["offset" + (isLeft ? "Left" : "Top")]; // el = el.offsetParent; //} return retValue; }; Util.bindFunction = function (el, fucName) { return function () { return el[fucName].apply(el, arguments); }; }; Util.re_calcOff = function (el) { for (var i = 0; i < Util.dragArray.length; i++) { var ele = Util.dragArray[i]; ele.elm.pagePosLeft = Util.getOffset(ele.elm, true); ele.elm.pagePosTop = Util.getOffset(ele.elm, false); } var nextSib = el.elm.nextSibling; while (nextSib) { nextSib.pagePosTop -= el.elm.offsetHeight; nextSib = nextSib.nextSibling; } }; Util.hide = function () { Util.rootElement.style.display = "none"; }; Util.show = function () { Util.rootElement.style.display = ""; }; ghostElement = null; found = null; getGhostElement = function () { if (!ghostElement) { ghostElement = document.createElement("DIV"); ghostElement.className = "MBox ghostBox"; } return ghostElement; }; function draggable(el) { this._dragStart = start_Drag; this._drag = when_Drag; this._dragEnd = end_Drag; this._afterDrag = after_Drag; this.isDragging = false; this.elm = el; this.hasIFrame = this.elm.getElementsByTagName("IFRAME").length > 0; Drag.init(el, this.elm); this.elm.onDragStart = Util.bindFunction(this, "_dragStart"); this.elm.onDrag = Util.bindFunction(this, "_drag"); this.elm.onDragEnd = Util.bindFunction(this, "_dragEnd"); }; function start_Drag() { Util.re_calcOff(this); this.origNextSibling = this.elm.nextSibling; var _ghostElement = getGhostElement(); var offH = this.elm.offsetHeight; var offW = this.elm.offsetWidth; var offLeft = Util.getOffset(this.elm, true); var offTop = Util.getOffset(this.elm, false); // Util.hide(); //this.elm.parentNode.getElementsByTagName('iframe')[0].style.visibility = 'hidden'; this.elm.style.width = offW + "px"; _ghostElement.style.height = offH + "px"; _ghostElement.style.width = offW + "px"; this.elm.parentNode.insertBefore(_ghostElement, this.elm.nextSibling); this.elm.style.position = "absolute"; this.elm.style.zIndex = 100; this.elm.style.left = offLeft + "px"; this.elm.style.top = offTop + "px"; //Util.show(); this.isDragging = false; return false; }; function when_Drag(clientX, clientY) { if (!this.isDragging) { this.elm.style.filter = "alpha(opacity=70)"; this.elm.style.opacity = 0.7; this.isDragging = true; } found = null; var max_distance = 100000000; for (var i = 0; i < Util.dragArray.length; i++) { var ele = Util.dragArray[i]; var distance = Math.sqrt(Math.pow(clientX - ele.elm.pagePosLeft, 2) + Math.pow(clientY - ele.elm.offsetTop, 2)); if (ele == this) { continue; } if (isNaN(distance)) { continue; } if (distance < max_distance) { max_distance = distance; found = ele; } }; var _ghostElement = getGhostElement(); if (found != null) { if(this.elm.pagePosLeft < clientX){ found.elm.parentNode.insertBefore(_ghostElement, found.elm.nextSibling); }else{ found.elm.parentNode.insertBefore(_ghostElement, found.elm); } }; }; function end_Drag() { //this.elm.parentNode.getElementsByTagName('iframe')[0].style.visibility = 'visible'; if (this._afterDrag()) { } return true; }; function after_Drag() { var returnValue = false; // Util.hide(); this.elm.style.position = ""; this.elm.style.width = ""; this.elm.style.zIndex = ""; this.elm.style.filter = ""; this.elm.style.opacity = ""; var ele = getGhostElement(); if (ele.nextSibling != this.origNextSibling) { ele.parentNode.insertBefore(found.elm, this.elm); ele.parentNode.insertBefore(this.elm, ele.nextSibling); returnValue = true; } ele.parentNode.removeChild(ele); //Util.show(); box.init(Util.rootElement); return returnValue; }; var Drag = { obj:null, init:function (elementHeader, element) { elementHeader.onmousedown = Drag.start; elementHeader.obj = element; if (isNaN(parseInt(element.style.left))) { element.style.left = "0px"; } if (isNaN(parseInt(element.style.top))) { element.style.top = "0px"; } element.onDragStart = new Function(); element.onDragEnd = new Function(); element.onDrag = new Function(); }, start:function (event) { var element = Drag.obj = this.obj; event = Drag.fixE(event); if (event.which != 1) { return true; } element.onDragStart(); element.lastMouseX = event.clientX; element.lastMouseY = event.clientY; document.onmouseup = Drag.end; document.onmousemove = Drag.drag; return false; }, drag:function (event) { event = Drag.fixE(event); if (event.which == 0) { return Drag.end(); } var element = Drag.obj; var _clientX = event.clientY; var _clientY = event.clientX; if (element.lastMouseX == _clientY && element.lastMouseY == _clientX) { return false; }; if(_clientX + document.documentElement.scrollTop + document.body.scrollTop < 0 || _clientX > document.documentElement.offsetHeight){ return false; }; var sTo=0; if( _clientX < 0 ){ sTo=_clientX; }; if((_clientX - document.documentElement.clientHeight) > 0){ sTo=_clientX - document.documentElement.clientHeight; }; window.scrollBy(0,sTo); var _lastX = parseInt(element.style.top); var _lastY = parseInt(element.style.left); var newX, newY; newX = _lastY + _clientY - element.lastMouseX; newY = _lastX + _clientX - element.lastMouseY; element.style.left = newX + "px"; element.style.top = newY + sTo + "px"; element.lastMouseX = _clientY; element.lastMouseY = _clientX; element.onDrag(newX, newY); return false; }, end:function (event) { event = Drag.fixE(event); document.onmousemove = null; document.onmouseup = null; var _onDragEndFuc = Drag.obj.onDragEnd(); Drag.obj = null; return _onDragEndFuc; }, fixE:function (ig_) { if (typeof ig_ == "undefined") { ig_ = window.event; } if (typeof ig_.layerX == "undefined") { ig_.layerX = ig_.offsetX; } if (typeof ig_.layerY == "undefined") { ig_.layerY = ig_.offsetY; } if (typeof ig_.which == "undefined") { ig_.which = ig_.button; } return ig_; } }; var initDrag = function (el) { Util.rootElement = el; Util.elem = Util.rootElement.children; Util.dragArray = new Array(); var counter = 0; for (var i = 0; i < Util.elem.length; i++) { var elem = Util.elem[i]; Util.dragArray[counter] = new draggable(elem); counter++; }; box.setIfr(Util.rootElement); box.init(Util.rootElement); }; /* 格子排序 */ var box={}; box.gen={w:200,h:180}; box.init=function(el){ box.size=[]; //格子,[1,2]表示1X2的大格子 box.obj={}; box.oArray=[]; box.maxY=-1; box.mbox = getElementsByClassName("MBox",el,'div'); box.row = document.documentElement.offsetWidth / box.gen.w >> 0; //每行标准格数 el.style.width = box.row * box.gen.w + "px"; var i = 0 , nx, ny; while( i < this.mbox.length){ if( getElementsByClassName("bigBox",this.mbox[i],'div').length > 0 ){ nx=Math.ceil(this.mbox[i].offsetWidth / this.gen.w); nx=(nx > this.row) ? this.row : nx; //大小超出限制 ny=Math.ceil(this.mbox[i].offsetHeight / this.gen.h); this.size.push([nx,ny]); }else{ this.size.push(1); } i++; } box.sort(el); }; box.setIfr=function(el){ //大格子初始化 var ifr = getElementsByClassName("bigBox",el,'div');; if(ifr.length==0) return false; var i = 0, nx, ny, theifr; while(i < ifr.length){ theifr = getElementsByClassName("innerBox",ifr[i],'div'); nx=Math.ceil(theifr[0].offsetWidth / this.gen.w); //bigBox横向占的块数 ny=Math.ceil(theifr[0].offsetHeight / this.gen.h); ifr[i].style.width = nx*this.gen.w-14 + 'px' ; ifr[i].style.height = ny*this.gen.h-14 + 'px' ; i++; } }; box.sort=function(el){ var y=0, x=0, temp={x:Infinity, y:Infinity}, flag=Infinity, name; for(var n=0; n < this.size.length ; n++){ if(flag == 0){ x=temp.x; y=temp.y; } flag=flag-1; if(x > box.row-1){ //换行 x=0; y++; } name=x+'_'+y; //对象属性名(反映占领的格子) if(this.hasN(name)) { //判断属性名是否存在 n--; x++; if(flag<Infinity) flag=flag+1; continue; } if(!this.size .length){ //普通格子 this.obj[name]=[x,y]; //(反映坐标值) x++; } else{ //大格子 if(this.over(x,y,n)) { if(temp.y > y){ temp.y = y; temp.x = x; } if(temp.y < Infinity){ flag=1; } n--; x++; continue; } this.obj[name]=[x,y]; this.apply(x,y,n); x+=this.size [0]; } if(flag==-1) { flag = Infinity; temp.y = Infinity; temp.x = Infinity; } var h=this.size [1]-1 || 0; box.maxY=(box.maxY > y+h)? box.maxY : y+h; } for(var i in this.obj){ if(this.obj[i]===0 || !this.obj.hasOwnProperty(i)) continue; this.oArray.push(this.obj[i]); } box.put(el); }; box.hasN=function(n){ return n in this.obj; }; box.over=function(x,y,n){ //判断是否会重叠 var name; if(x+this.size [0] > this.row) return true; //超出显示范围 for(var k=1; k<this.size [1];k++){ name=x+'_'+(y-0+k); if(this.hasN(name)) {return true;} //左侧一列有无重叠 } for(k=1; k<this.size [0];k++){ name=(x-0+k)+'_'+y; if(this.hasN(name)) {return true;} //上侧一行有无重叠 } return false; }; box.apply=function(x,y,n){ //大格子中多占的位置 var posX=x, //大格子左上角位置 posY=y; for(var t=0; t<this.size [0]; t++) { for(var k=0; k<this.size [1]; k++){ name=(posX+t)+'_'+(posY+k); if(t==0 && k==0) { continue; } this.obj[name]=0; //多占的格子无坐标值 } } }; box.put=function(el){ var x,y; for(var i =0;i< this.oArray.length; i++){ x=box.gen.w*this.oArray[i][0]; y=box.gen.h*this.oArray[i][1]; box.mbox[i].style.cssText = "position:absolute;left:"+ x +"px;top:" + y + "px;"; }; el.style.height= box.gen.h*(box.maxY+1) +'px'; }; </script> </head> <body> <div id="myWidget" class="myWidget"></div> <script> var myWidget = $id("myWidget"); //创建随机内容 var content = ''; for(i = 0; i < 20; i++) { if(!(Math.random()*5 >> 0)){ height = Math.floor(Math.random()*200 + 100); width = Math.floor(Math.random()*200 + 100); content += '<div class="MBox"><div class="widgetBox bigBox"><div style="width:' + width +'px;height:' + height +'px;margin:0 auto;" class="innerBox">'+ i +'</div></div></div>'; }else{ content += '<div class="MBox"><div class="widgetBox">'+ i +'</div></div>'; } }; myWidget.innerHTML = content; //绑定拖动元素 initDrag(myWidget); window.onresize = function(){box.init(myWidget)}; </script> </body> </html>
相关文章推荐
- Android ListView功能扩展,实现高性能的瀑布流布局
- Android ListView功能扩展,实现高性能的瀑布流布局
- 网页瀑布流布局jQuery实现代码
- Android ListView功能扩展,实现高性能的瀑布流布局
- Android ListView功能扩展,实现高性能的瀑布流布局
- Android ListView功能扩展,实现高性能的瀑布流布局
- Android ListView功能扩展,实现高性能的瀑布流布局
- Android ListView功能扩展,实现高性能的瀑布流布局
- 网页瀑布流布局jQuery实现代码
- Android ListView功能扩展,实现高性能的瀑布流布局
- Android ListView功能扩展,实现高性能的瀑布流布局
- Android ListView功能扩展,实现高性能的瀑布流布局
- Android ListView 功能扩展,实现高性能的瀑布流布局
- CSS垂直居中网页布局实现的5种方法
- 扩展javascript的Date方法实现代码(prototype)
- C# ASP.NET 最常用的通用权限的3个方法例子展示(每个功能一行代码实现)
- CSS_DIV学习记录2(用背景颜色实现一个网页的完整布局)
- Asp.Net完整实现网页保存为图片代码
- CSS垂直居中网页布局实现的5种方法
- 扩展jquery实现客户端表格的分页、排序功能代码