网页瀑布流布局实现方法及功能扩展

Web前端评论1K阅读模式

现在这种布局已经不能叫瀑布流了,我们称之为格子块,格子块通过算法智能堆砌。

到最后,说点下睛也好,说添下足也好,我们再加一个拖动交换格子的效果。

  1. <!doctype html>  
  2.   <html>  
  3.   <head>  
  4.   <meta charset="UTF-8" />  
  5.   <title>宽高尺寸不同的格子堆砌(可拖动换位)</title>  
  6.   <style>  
  7.   body{background:#F6F7F8;}  
  8.   .myWidget{position:relative;overflow:hidden;zoom:1;margin:0 auto;}  
  9.   .MBox{float:left;}  
  10.   .widgetBox{position:relative;overflow:hidden;zoom:1;width:186px;height:166px;margin:6px;border:1px solid #E1E1E3;cursor:move;  
  11. border-radius:10px;  
  12. -moz-border-radius:10px;  
  13. -webkit-border-radius:10px;  
  14. box-shadow:2px 3px 5px #d3d3d3;  
  15. -moz-box-shadow:2px 3px 5px #d3d3d3;  
  16. -webkit-box-shadow:2px 3px 5px #d3d3d3;  
  17. filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#fefefe, endColorstr=#e0e0e2);  
  18. background: linear-gradient(top, #fefefe, #f6f6f6 ,#f3f3f3,#f2f2f2,#e0e0e2);  
  19. background: -moz-linear-gradient(top, #fefefe, #f6f6f6 ,#f3f3f3,#f2f2f2,#e0e0e2);  
  20. background: -webkit-gradient(linear, 0 0, 0 100% , from(#fefefe),to(#e0e0e2));  
  21. background: -webkit-linear-gradient(0 0, #fefefe, #f6f6f6 ,#f3f3f3,#f2f2f2,#e0e0e2);  
  22. }  
  23. </style>  
  24. <script>  
  25. var $id = function(o){ return document.getElementById(o) || o ;};  
  26. var getElementsByClassName = function(className,parent,tag) {  
  27. parent = parent || document;  
  28. if(parent.getElementsByClassName){  
  29. return  parent.getElementsByClassName(className)  
  30. }else{  
  31. tag = tag || '*';  
  32. var returnElements = []  
  33. var els =  parent.getElementsByTagName(tag);  
  34. className = className.replace(/\-/g, "\\-");  
  35. var pattern = new RegExp("(^|\\s)"+className+"(\\s|$)");  
  36. var i = 0;  
  37. while(i < els.length){  
  38. if (pattern.test(els[i].className) ) {  
  39. returnElements.push(els[i]);  
  40. }  
  41. i++;  
  42. }  
  43. return returnElements;  
  44. }  
  45. };  
  46. var Util = new Object();  
  47. Util.getOffset = function (el, isLeft) {  
  48. var retValue = 0;  
  49. // while (el != null) {  
  50. retValue += el["offset" + (isLeft ? "Left" : "Top")];  
  51. //   el = el.offsetParent;  
  52. //}  
  53. return retValue;  
  54. };  
  55. Util.bindFunction = function (el, fucName) {  
  56. return function () {  
  57. return el[fucName].apply(el, arguments);  
  58. };  
  59. };  
  60. Util.re_calcOff = function (el) {  
  61. for (var i = 0; i < Util.dragArray.length; i++) {  
  62. var ele = Util.dragArray[i];  
  63. ele.elm.pagePosLeft = Util.getOffset(ele.elm, true);  
  64. ele.elm.pagePosTop = Util.getOffset(ele.elm, false);  
  65. }  
  66. var nextSib = el.elm.nextSibling;  
  67. while (nextSib) {  
  68. nextSib.pagePosTop -= el.elm.offsetHeight;  
  69. nextSib = nextSib.nextSibling;  
  70. }  
  71. };  
  72. Util.hide = function () {  
  73. Util.rootElement.style.display = "none";  
  74. };  
  75. Util.show = function () {  
  76. Util.rootElement.style.display = "";  
  77. };  
  78. ghostElement = null;  
  79. found = null;  
  80. getGhostElement = function () {  
  81. if (!ghostElement) {  
  82. ghostElement = document.createElement("DIV");  
  83. ghostElement.className = "MBox ghostBox";  
  84. }  
  85. return ghostElement;  
  86. };  
  87. function draggable(el) {  
  88. this._dragStart = start_Drag;  
  89. this._drag = when_Drag;  
  90. this._dragEnd = end_Drag;  
  91. this._afterDrag = after_Drag;  
  92. this.isDragging = false;  
  93. this.elm = el;  
  94. this.hasIFrame = this.elm.getElementsByTagName("IFRAME").length > 0;  
  95. Drag.init(el, this.elm);  
  96. this.elm.onDragStart = Util.bindFunction(this, "_dragStart");  
  97. this.elm.onDrag = Util.bindFunction(this, "_drag");  
  98. this.elm.onDragEnd = Util.bindFunction(this, "_dragEnd");  
  99. };  
  100. function start_Drag() {  
  101. Util.re_calcOff(this);  
  102. this.origNextSibling = this.elm.nextSibling;  
  103. var _ghostElement = getGhostElement();  
  104. var offH = this.elm.offsetHeight;  
  105. var offW = this.elm.offsetWidth;  
  106. var offLeft = Util.getOffset(this.elm, true);  
  107. var offTop = Util.getOffset(this.elm, false);  
  108. // Util.hide();  
  109. //this.elm.parentNode.getElementsByTagName('iframe')[0].style.visibility = 'hidden';  
  110. this.elm.style.width = offW + "px";  
  111. _ghostElement.style.height = offH + "px";  
  112. _ghostElement.style.width = offW + "px";  
  113. this.elm.parentNode.insertBefore(_ghostElement, this.elm.nextSibling);  
  114. this.elm.style.position = "absolute";  
  115. this.elm.style.zIndex = 100;  
  116. this.elm.style.left = offLeft + "px";  
  117. this.elm.style.top = offTop + "px";  
  118. //Util.show();  
  119. this.isDragging = false;  
  120. return false;  
  121. };  
  122. function when_Drag(clientX, clientY) {  
  123. if (!this.isDragging) {  
  124. this.elm.style.filter = "alpha(opacity=70)";  
  125. this.elm.style.opacity = 0.7;  
  126. this.isDragging = true;  
  127. }  
  128. found = null;  
  129. var max_distance = 100000000;  
  130. for (var i = 0; i < Util.dragArray.length; i++) {  
  131. var ele = Util.dragArray[i];  
  132. var distance = Math.sqrt(Math.pow(clientX - ele.elm.pagePosLeft, 2) + Math.pow(clientY -  ele.elm.offsetTop, 2));  
  133. if (ele == this) {  
  134. continue;  
  135. }  
  136. if (isNaN(distance)) {  
  137. continue;  
  138. }  
  139. if (distance < max_distance) {  
  140. max_distance = distance;  
  141. found = ele;  
  142. }  
  143. };  
  144. var _ghostElement = getGhostElement();  
  145. if (found != null) {  
  146. if(this.elm.pagePosLeft < clientX){  
  147. found.elm.parentNode.insertBefore(_ghostElement, found.elm.nextSibling);  
  148. }else{  
  149. found.elm.parentNode.insertBefore(_ghostElement, found.elm);  
  150. }  
  151. };  
  152. };  
  153. function end_Drag() {  
  154. //this.elm.parentNode.getElementsByTagName('iframe')[0].style.visibility = 'visible';  
  155. if (this._afterDrag()) {  
  156. }  
  157. return true;  
  158. };  
  159. function after_Drag() {  
  160. var returnValue = false;  
  161. // Util.hide();  
  162. this.elm.style.position = "";  
  163. this.elm.style.width = "";  
  164. this.elm.style.zIndex = "";  
  165. this.elm.style.filter = "";  
  166. this.elm.style.opacity = "";  
  167. var ele = getGhostElement();  
  168. if (ele.nextSibling != this.origNextSibling) {  
  169. ele.parentNode.insertBefore(found.elm, this.elm);  
  170. ele.parentNode.insertBefore(this.elm, ele.nextSibling);  
  171. returnValue = true;  
  172. }  
  173. ele.parentNode.removeChild(ele);  
  174. //Util.show();  
  175. box.init(Util.rootElement);  
  176. return returnValue;  
  177. };  
  178. var Drag = {  
  179. obj:null,  
  180. init:function (elementHeader, element) {  
  181. elementHeader.onmousedown = Drag.start;  
  182. elementHeader.obj = element;  
  183. if (isNaN(parseInt(element.style.left))) {  
  184. element.style.left = "0px";  
  185. }  
  186. if (isNaN(parseInt(element.style.top))) {  
  187. element.style.top = "0px";  
  188. }  
  189. element.onDragStart = new Function();  
  190. element.onDragEnd = new Function();  
  191. element.onDrag = new Function();  
  192. },  
  193. start:function (event) {  
  194. var element = Drag.obj = this.obj;  
  195. event = Drag.fixE(event);  
  196. if (event.which != 1) {  
  197. return true;  
  198. }  
  199. element.onDragStart();  
  200. element.lastMouseX = event.clientX;  
  201. element.lastMouseY = event.clientY;  
  202. document.onmouseup = Drag.end;  
  203. document.onmousemove = Drag.drag;  
  204. return false;  
  205. },  
  206. drag:function (event) {  
  207. event = Drag.fixE(event);  
  208. if (event.which == 0) {  
  209. return Drag.end();  
  210. }  
  211. var element = Drag.obj;  
  212. var _clientX = event.clientY;  
  213. var _clientY = event.clientX;  
  214. if (element.lastMouseX == _clientY && element.lastMouseY == _clientX) {  
  215. return false;  
  216. };  
  217. if(_clientX + document.documentElement.scrollTop + document.body.scrollTop < 0 ||  _clientX > document.documentElement.offsetHeight){  
  218. return false;  
  219. };  
  220. var sTo=0;  
  221. if( _clientX < 0 ){  
  222. sTo=_clientX;  
  223. };  
  224. if((_clientX - document.documentElement.clientHeight) > 0){  
  225. sTo=_clientX - document.documentElement.clientHeight;  
  226. };  
  227. window.scrollBy(0,sTo);  
  228. var _lastX = parseInt(element.style.top);  
  229. var _lastY = parseInt(element.style.left);  
  230. var newX, newY;  
  231. newX = _lastY + _clientY - element.lastMouseX;  
  232. newY = _lastX + _clientX - element.lastMouseY;  
  233. element.style.left = newX  + "px";  
  234. element.style.top = newY + sTo + "px";  
  235. element.lastMouseX = _clientY;  
  236. element.lastMouseY = _clientX;  
  237. element.onDrag(newX, newY);  
  238. return false;  
  239. },  
  240. end:function (event) {  
  241. event = Drag.fixE(event);  
  242. document.onmousemove = null;  
  243. document.onmouseup = null;  
  244. var _onDragEndFuc = Drag.obj.onDragEnd();  
  245. Drag.obj = null;  
  246. return _onDragEndFuc;  
  247. },  
  248. fixE:function (ig_) {  
  249. if (typeof ig_ == "undefined") {  
  250. ig_ = window.event;  
  251. }  
  252. if (typeof ig_.layerX == "undefined") {  
  253. ig_.layerX = ig_.offsetX;  
  254. }  
  255. if (typeof ig_.layerY == "undefined") {  
  256. ig_.layerY = ig_.offsetY;  
  257. }  
  258. if (typeof ig_.which == "undefined") {  
  259. ig_.which = ig_.button;  
  260. }  
  261. return ig_;  
  262. }  
  263. };  
  264. var initDrag = function (el) {  
  265. Util.rootElement = el;  
  266. Util.elem = Util.rootElement.children;  
  267. Util.dragArray = new Array();  
  268. var counter = 0;  
  269. for (var i = 0; i < Util.elem.length; i++) {  
  270. var elem = Util.elem[i];  
  271. Util.dragArray
    0
    +
    网站访问量
     = new draggable(elem);  
  272. counter++;  
  273. };  
  274. box.setIfr(Util.rootElement);  
  275. box.init(Util.rootElement);  
  276. };  
  277. /* 格子排序 */  
  278. var box={};  
  279. box.gen={w:200,h:180};  
  280. box.init=function(el){  
  281. box.size=[]; //格子,[1,2]表示1X2的大格子  
  282. box.obj={};  
  283. box.oArray=[];  
  284. box.maxY=-1;  
  285. box.mbox = getElementsByClassName("MBox",el,'div');  
  286. box.row = document.documentElement.offsetWidth / box.gen.w >> 0;  //每行标准格数  
  287. el.style.width = box.row * box.gen.w + "px";  
  288. var i = 0 , nx, ny;  
  289. while( i < this.mbox.length){  
  290. if( getElementsByClassName("bigBox",this.mbox[i],'div').length > 0 ){  
  291. nx=Math.ceil(this.mbox[i].offsetWidth / this.gen.w);  
  292. nx=(nx > this.row) ? this.row : nx; //大小超出限制  
  293. ny=Math.ceil(this.mbox[i].offsetHeight / this.gen.h);  
  294. this.size.push([nx,ny]);  
  295. }else{  
  296. this.size.push(1);  
  297. }  
  298. i++;  
  299. }  
  300. box.sort(el);  
  301. };  
  302. box.setIfr=function(el){  //大格子初始化  
  303. var ifr = getElementsByClassName("bigBox",el,'div');;  
  304. if(ifr.length==0) return false;  
  305. var i = 0, nx, ny, theifr;  
  306. while(i < ifr.length){  
  307. theifr =  getElementsByClassName("innerBox",ifr[i],'div');  
  308. nx=Math.ceil(theifr[0].offsetWidth / this.gen.w); //bigBox横向占的块数  
  309. ny=Math.ceil(theifr[0].offsetHeight / this.gen.h);  
  310. ifr[i].style.width = nx*this.gen.w-14 + 'px' ;  
  311. ifr[i].style.height = ny*this.gen.h-14 + 'px' ;  
  312. i++;  
  313. }  
  314. };  
  315. box.sort=function(el){  
  316. var y=0, x=0, temp={x:Infinity, y:Infinity}, flag=Infinity, name;  
  317. for(var n=0; n < this.size.length ; n++){  
  318. if(flag == 0){  
  319. x=temp.x;  
  320. y=temp.y;  
  321. }  
  322. flag=flag-1;  
  323. if(x > box.row-1){ //换行  
  324. x=0;  
  325. y++;  
  326. }  
  327. name=x+'_'+y;  //对象属性名(反映占领的格子)  
  328. if(this.hasN(name)) {  //判断属性名是否存在  
  329. n--;  
  330. x++;  
  331. if(flag<Infinity) flag=flag+1;  
  332. continue;  
  333. }  
  334. if(!this.size[n].length){  //普通格子  
  335. this.obj[name]=[x,y];  //(反映坐标值)  
  336. x++;  
  337. }  
  338. else{  //大格子  
  339. if(this.over(x,y,n)) {  
  340. if(temp.y > y){  
  341. temp.y = y;  
  342. temp.x = x;  
  343. }  
  344. if(temp.y < Infinity){  
  345. flag=1;  
  346. }  
  347. n--;  
  348. x++;  
  349. continue;  
  350. }  
  351. this.obj[name]=[x,y];  
  352. this.apply(x,y,n);  
  353. x+=this.size[n][0];  
  354. }  
  355. if(flag==-1) {  
  356. flag =  Infinity;  
  357. temp.y = Infinity;  
  358. temp.x = Infinity;  
  359. }  
  360. var h=this.size[n][1]-1 || 0;  
  361. box.maxY=(box.maxY > y+h)? box.maxY : y+h;  
  362. }  
  363. for(var i in this.obj){  
  364. if(this.obj[i]===0 || !this.obj.hasOwnProperty(i)) continue;  
  365. this.oArray.push(this.obj[i]);  
  366. }  
  367. box.put(el);  
  368. };  
  369. box.hasN=function(n){  
  370. return n in this.obj;  
  371. };  
  372. box.over=function(x,y,n){  //判断是否会重叠  
  373. var name;  
  374. if(x+this.size[n][0] > this.row) return true; //超出显示范围  
  375. for(var k=1; k<this.size[n][1];k++){  
  376. name=x+'_'+(y-0+k);  
  377. if(this.hasN(name)) {return true;}  //左侧一列有无重叠  
  378. }  
  379. for(k=1; k<this.size[n][0];k++){  
  380. name=(x-0+k)+'_'+y;  
  381. if(this.hasN(name)) {return true;}  //上侧一行有无重叠  
  382. }  
  383. return false;  
  384. };  
  385. box.apply=function(x,y,n){  //大格子中多占的位置  
  386. var posX=x, //大格子左上角位置  
  387. posY=y;  
  388. for(var t=0; t<this.size[n][0]; t++) {  
  389. for(var k=0; k<this.size[n][1]; k++){  
  390. name=(posX+t)+'_'+(posY+k);  
  391. if(t==0 && k==0) { continue; }  
  392. this.obj[name]=0;   //多占的格子无坐标值  
  393. }  
  394. }  
  395. };  
  396. box.put=function(el){  
  397. var x,y;  
  398. for(var i =0;i< this.oArray.length; i++){  
  399. x=box.gen.w*this.oArray[i][0];  
  400. y=box.gen.h*this.oArray[i][1];  
  401. box.mbox[i].style.cssText = "position:absolute;left:"+ x +"px;top:" + y + "px;";  
  402. };  
  403. el.style.height= box.gen.h*(box.maxY+1) +'px';  
  404. };  
  405. </script>  
  406. </head>  
  407. <body>  
  408. <div id="myWidget" class="myWidget"></div>  
  409. <script>  
  410. var myWidget = $id("myWidget");  
  411. //创建随机内容  
  412. var content = '';  
  413. for(i = 0; i < 20; i++) {  
  414. if(!(Math.random()*5 >> 0)){  
  415. height = Math.floor(Math.random()*200 + 100);  
  416. width = Math.floor(Math.random()*200 + 100);  
  417. 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>';  
  418. }else{  
  419. content += '<div class="MBox"><div class="widgetBox">'+ i +'</div></div>';  
  420. }  
  421. };  
  422. myWidget.innerHTML = content;  
  423. //绑定拖动元素  
  424. initDrag(myWidget);  
  425. window.onresize = function(){box.init(myWidget)};  
  426. </script>  
  427. </body>  
  428. </html>  

本站文章大部分始于原创,用于个人学习记录,可能对您有所帮助,仅供参考!

weinxin
我的微信
版权声明
本站原创文章转载请注明文章出处及链接,谢谢合作!
 
匿名

发表评论

匿名网友
:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

拖动滑块以完成验证