自己封装jquery瀑布流插件

[1] 首先jQuery中封装插件的方法有两个:

(1) jquery.fn.extend(object)

(2)jquery.extend(object)

这里我们采用第一种方法优点是可以利用获取对象进行调用

注意:我们的插件遵循一般的jq插件的命名规范,jquery.插件名.js =>  jquery.waterfall.js

[2]理解瀑布流是什么:

顾名思义,瀑布流的内容就好像瀑布一样倾泻而下从上到下进行排布

[example]:

【瀑布流的核心就是】

[1]宽度一致,高度参差不齐

[2]新增行的内容,优先添加到“最矮”的下方

[难点]

当我们到达新的一行时候,如何获取上一行高度最小的行高

[解决]

可以定义一个数组专门放置高度,新增了以后替换掉数组中的原始高度即可


 

所谓瀑布流就是一种布局方式,items中的item宽度一样,高度层次错落,我们称为瀑布流:(思想见下图)

用户自己书写浏览器端和服务器的代码,只需要利用$()获取事件源对象调用我们书写的瀑布流插件进行布局就可以实现ajax的瀑布流效果了

[3]瀑布流思想及代码:

条件:

这里我们书写瀑布流插件分为三个步骤:

[步骤1]:

为了计算 获取一些必须知道的值:

容器的宽度,子元素的宽度,每一行放置的元素的个数,以及每个元素之间的间距

 1 //把this 定义$_this变量 方便观察
 2         var $_this = this;
 3         //父盒子宽度
 4         var totalWidth = $_this.width();
 5         //子盒子宽度
 6         var itemWidth  = $_this.children('.item').width();
 7         //每一行的个数 4.1 4.9
 8         var colNum = Math.floor(totalWidth/itemWidth);
 9         //间距(总宽度-个数*子元素宽度)/(个数-1)
10         var margin  = (totalWidth-(itemWidth*colNum))/(colNum-1);

[步骤2]:

获取了上述的数据之后我们开始最重要的步骤二

我们需要计算每一个元素的top还有left值(对父盒子进行相对定位,子盒子进行绝对定位实现高度参差不齐的效果)

1 准备一个数组  数组的元素的个数 跟每一行的个数一直里面是默认值(比如我这里的10或者margin(反正随意给个默认值啦当然没有默认值也不碍事))

2  循环我们所有的item元素

  获取子元素的高度

  通过我们在步骤1中定义的数组来获取最小的值

 3  修改我们在步骤1中定义的数组对应的索引值即可

 1 //步骤2.1  准备高度数组
 2         //高度数组
 3         var heightArr = [];
 4         //循环为高度数组 赋值初始值
 5         for(var i = 0;i<colNum;i++) {
 6             heightArr[i] = margin;
 7             //给margin是为了看起来好看一点
 8         }
 9 
10         //步骤2.2循环子元素 获取数组中最小的索引  修改当前循环的元素的top 和 left值
11         //jq中循环数组的方法
12         $_this.children('item').each(function () {
13             //获取当前循环的子元素的高度
14             var currentHeight = $(element).height();
15             //计算该元素放在哪个位置
16             //先假设索引为0的是最小值
17             var minindex = 0;
18             var minHeight = heightArr[0];
19             for(var i = 0;i<heightArr.length;i++) {
20                 //跟我们假设的最小值进行比较
21                 if(heightArr[i]<minHeight) {
22                     //替换一下
23                     minHeight = heightArr[i];
24                     minindex = i;
25                 }
26             }
27             //循环完毕最小的高度以及最小的索引值
28 
29             //设置给当前循环的子元素即可
30             //top高度为计算出来的最小高度
31             //left左间距为宽度 * 索引 +宽度 * 间距
32             $(element).css({
33                 top:minHeight,
34                 left:minindex*(itemWidth+margin)
35             })
36 
37             //步骤2.3 修改步骤1中创建的高度数组
38             //修改minindex对应的值即可
39             minHeight+=currentHeight;//加上自己的高度
40             minHeight+=margin;//为了美观 把间距加上去
41             heightArr[minindex] = minHeight;
42         })

[步骤3]修改父盒子的高度对父盒子的siblings影响降到最低

 1 /*
 2             //修改父盒子的高度即可
 3             //获取高度数组中最大的值
 4             //修改父盒子的高度为计算出来的最大的值
 5         */
 6         var maxHeight = heightArr[0];
 7         for(var i = 0;i<heightArr.length;i++) {
 8             if(heightArr[i]>maxHeight) {
 9                 maxHeight = heightArr[i];
10             }
11         }
12         //循环完毕之后  最大值就有了
13         $_this.height(maxHeight);

[插件代码]

 1 $.fn.extend({
 2     waterfall:function(){
 3         // console.log('我自己写的瀑布流插件');
 4 
 5         // 步骤1
 6         /*
 7             为了 计算 获取一些 必须知道的值
 8             容器的宽度 .items的 宽度
 9             子元素的宽度 .child().width()
10             每一行放置的元素个数
11             计算间距
12         */
13         //把this 定义$_this变量 方便观察
14         var $_this = this;
15         //父盒子宽度
16         var totalWidth = $_this.width();
17         //子盒子宽度
18         var itemWidth  = $_this.children('.item').width();
19         //每一行的个数 4.1 4.9
20         var colNum = Math.floor(totalWidth/itemWidth);
21         //间距(总宽度-个数*子元素宽度)/(个数-1)
22         var margin  = (totalWidth-(itemWidth*colNum))/(colNum-1);
23 
24         //步骤2
25         /*
26           计算每一个元素的top还有left的值
27           1  准备一个数组 数组的元素的个数 跟每一行的个数一直里面是默认值(比如是10或者是margin)
28           2  循环我们的所有item元素
29                   获取子元素的高度
30                   通过我们在步骤1中定义的数组获取最小的值
31                   根据获取的最小的索引值计算left 和 top
32           3  修改我们在步骤一中定义的数组对应索引的值即可
33          */
34 
35         //步骤2.1  准备高度数组
36         //高度数组
37         var heightArr = [];
38         //循环为高度数组 赋值初始值
39         for(var i = 0;i<colNum;i++) {
40             heightArr[i] = margin;
41             //给margin是为了看起来好看一点
42         }
43 
44         //步骤2.2循环子元素 获取数组中最小的索引  修改当前循环的元素的top 和 left值
45         //jq中循环数组的方法
46         $_this.children('item').each(function () {
47             //获取当前循环的子元素的高度
48             var currentHeight = $(element).height();
49             //计算该元素放在哪个位置
50             //先假设索引为0的是最小值
51             var minindex = 0;
52             var minHeight = heightArr[0];
53             for(var i = 0;i<heightArr.length;i++) {
54                 //跟我们假设的最小值进行比较
55                 if(heightArr[i]<minHeight) {
56                     //替换一下
57                     minHeight = heightArr[i];
58                     minindex = i;
59                 }
60             }
61             //循环完毕最小的高度以及最小的索引值
62 
63             //设置给当前循环的子元素即可
64             //top高度为计算出来的最小高度
65             //left左间距为宽度 * 索引 +宽度 * 间距
66             $(element).css({
67                 top:minHeight,
68                 left:minindex*(itemWidth+margin)
69             })
70 
71             //步骤2.3 修改步骤1中创建的高度数组
72             //修改minindex对应的值即可
73             minHeight+=currentHeight;//加上自己的高度
74             minHeight+=margin;//为了美观 把间距加上去
75             heightArr[minindex] = minHeight;
76         })
77 
78         //步骤3
79         /*
80             //修改父盒子的高度即可
81             //获取高度数组中最大的值
82             //修改父盒子的高度为计算出来的最大的值
83         */
84         var maxHeight = heightArr[0];
85         for(var i = 0;i<heightArr.length;i++) {
86             if(heightArr[i]>maxHeight) {
87                 maxHeight = heightArr[i];
88             }
89         }
90         //循环完毕之后  最大值就有了
91         $_this.height(maxHeight);
92 
93     }
94 })

 

posted @ 2018-03-15 11:04  Lay-Buddhist  阅读(258)  评论(0)    收藏  举报