热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

class原生js获取父元素_原生js实现瀑布流效果

题外话:最近新建了一个专栏,里面专门用来发布一些前端学习中的一些小demo,但是以我一己之力想要将专栏丰富起来还是有点困难,
03f78fd980cab18521383c551c59df56.png

题外话:最近新建了一个专栏,里面专门用来发布一些前端学习中的一些小demo,但是以我一己之力想要将专栏丰富起来还是有点困难,所以,如果有想成为专栏作者或者想要投稿的小伙伴私我。

关注公众平台:【资料分享大师】

其他文章参考:

天之蓝源:三分钟在GitHub上搭建个人博客​zhuanlan.zhihu.com
fb32f788a50c21c268cae17960db20e3.png
天之蓝源:零基础Hexo+Github搭建静态个人博客​zhuanlan.zhihu.com
6cd89aad490d3ce2287fcf3b2d80927b.png
天之蓝源:原生js实现点击按钮复制文本内容​zhuanlan.zhihu.com
94b621e6926147456e8c0031083e7867.png
天之蓝源:九种跨域方式实现原理​zhuanlan.zhihu.com
e1c07fc845d7a10a1ac628fa2331f6fe.png
天之蓝源:前端面试考点多?看这些文章就够了(转载)​zhuanlan.zhihu.com
3a5fdf71d6f43b47df107db92c3b7894.png
天之蓝源:干货!值得收藏的前端学习网站​zhuanlan.zhihu.com
29aa3d23ad65e57825dccfd78e7e6beb.png
天之蓝源:原生JS实现一个日期选择器(DatePicker)组件​zhuanlan.zhihu.com
a5f6fa19be073d91557e95e2c2f0d151.png
天之蓝源:原生js一步一步实现《别踩白块儿》小游戏​zhuanlan.zhihu.com
472f9bd980d9c2eb911cd450bd53f154.png
天之蓝源:原生js利用localstorage实现简易TODO list应用​zhuanlan.zhihu.com
3acc9cefb5d22a4e3cc90a7177e04a18.png
天之蓝源:原生js实现瀑布流效果​zhuanlan.zhihu.com
8b4d61a48a53955464be13fd42a81d0f.png
天之蓝源:原生js实现图片懒加载(lazyLoad)​zhuanlan.zhihu.com
f36d48fe375dbcb2dd3d39439e2a3c34.png
天之蓝源:原生js实现简单路由切换​zhuanlan.zhihu.com
9f20df78e9a9683f9af153e937c90aa6.png

进入正题-------->

前言:知识是学不完的,可是我们为什么还是要不停的去学习呢。原因很简单,因为我们要产生更多的知识,让更多的人学不完!前端技术也是在不停的革新,我们要做那个让别人有学不完的知识的人!

我们要实现的效果:

7181b841e684990ba496d0876e8b69fa.png
原生js实现瀑布流式布局https://www.zhihu.com/video/1072171787252445184

一.什么是瀑布流

瀑布流,又被称作为瀑布流式布局,是一种比较流行的网站页面布局方式,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部。这种布局方式常见于一些图片为主的网站,就比如说一些常见的网站:

5416ddb4093c2f1df87d143537895125.png
瀑布流式布局
fc28017d9dc6b9ad8d4dc7285c4d251f.png
瀑布流式布局

由上面的两张图我们可以很容易的明白什么是瀑布流式布局,可以看出,每个图片的高度是不一样的但是它们的宽度是统一的,每个图片之间的间隙也是均匀的。

总结瀑布流式布局的特征如下:

  • 内容框宽度固定,高度不固定。
  • 内容框从左到右排列,一行排满后,其余内容框就会按顺序排在短的一列后。

二.为什么要用瀑布流布局

1、吸引用户

当用户在浏览瀑布流式布局的时候(这里抛开懒加载),用户会产生一种错觉,就是信息是不停的在更新的,这会激发用户的好奇心,使用户不停的往下滑动。

2.良好视觉体验

采用瀑布流布局的方式可以打破常规网站布局排版,给用户眼前一亮的新鲜感,用户在浏览内容时会感到很有新鲜感,带来良好的视觉体验。

3.更好的适应移动端

由于移动设备屏幕比电脑小,一个屏幕显示的内容不会非常多,因此可能要经常翻页。而在建网站时使用瀑布流布局,用户则只需要进行滚动就能够不断浏览内容。(这一点和懒加载有一点像)

三.实现原理

我们已经总结出了瀑布流式布局的两大特征:

  • 内容框宽度固定,高度不固定。
  • 内容框从左到右排列,一行排满后,其余内容框就会按顺序排在短的一列后。

那么我们根据这两大特征就不难想出它的实现原理:

首先我们先通过计算一行能够容纳几列元素(因为我们需要在不同的设备上浏览),然后在通过计算比较找出这一列元素中高度之和最小一列,然后将下一行的第一个元素添加至高度之和最小的这一列的下面,然后继续计算所有列中高度之和最小的那一列,然后继续将新元素添加至高度之和最小的那一列后面,直至所有元素添加完毕。

可能饶了这么一大段话还是有小伙伴不明白,我们还是看图说话,这才是最容易理解的;

(1)首先我们放上一行

,它们高度不同,宽度相同:

f5c2d5e4a32b9d9adfc54396d53e092b.png
高度不同,宽度相同

(2)找出所有元素高度之和的最小的那列在那一列的下面添加新的元素

c945854e1996e93d842e0945e1c72749.png
在第五列添加新元素

(3)然后继续计算,获取高度之和最小的那一列,在那一列继续添加新元素

52bed97511b05223b0324f3687f059aa.png
继续在高度之和最小那一列添加新元素

看了这几张图是不是明确了很多,就是这样不停的计算,不停的添加新元素,直至所有元素添加完成。但是我们都知道一些元素是块级元素,一个元素占据一行,这里就会有小伙伴想到了,我们可以利用浮动啊,具体是不是,我们继续实验。

现在明白了瀑布流是布局是怎么实现的了,那么就来写具体的代码来实现一下吧!

四.实现步骤及方法

1.通过浮动的方式进行布局

首先我们添加一些

元素,并设置为左浮动,分别给这些
元素给予不同的背景方便我们观察,注意,这些元素的宽度是一样的,只是高度不一样。

097f548119e0ec179e9769ba6301d37d.png
通过左浮动设置的布局

这就是通过左浮动设置的布局样式,我们可以看到在第二行的时候,第七个盒子浮动是根据第三个盒子来进行定位的。第三行的时候第七个盒子又挡住了第十个盒子的去路,所以这样我们是没法完成布局的。

2.通过定位的方式进行布局

前面我们已经知道了浮动布局不能满足我们的需求,所以我们寻求另外一种布局方式,那就是通过定位,给每个盒子设置定位属性后,我们就可以通过动态的设置相应的top,left值来让盒子规规矩矩的为我们排列。

(一)给所有盒子的父元素加上相对定位属性,给所有盒子加上绝对定位属性:

position:relative;
position:absolute;

(二)定位之后我们得到的界面是这样的:

85860d94fdead5bf9cdcc3f2901d8d11.png
设置定位后的元素

(三)如何判断一行有多少列:

因为我们的界面宽度是变化的,所以列数也需要跟着变化,动态设置列数的原理大致如下:

1.获取到页面的宽度

2.获取到每个盒子的宽度

3.需要显示的列数 = 页面宽度/盒子宽度

注意:一般盒子之间都有一个间隙,所以我们的公式变成如下:

显示的列数(column) = 页面宽度(pageWidth)/(盒子宽度(itemWidth)+间隙(gap))

(四)排列第一行

  • 我们有很多盒子&#xff0c;太多了我们就不好管理&#xff0c;所以我们把所有盒子装进一个数组arr里面&#xff0c;下标从0开始&#xff0c;用i来代表盒子。那么我们如何知道这个盒子是不是应该排列在第一行呢。其实很简单&#xff0c;想一下&#xff0c;我们这么多盒子&#xff0c;全部都要动态布局&#xff0c;动态的设置他的left、top值&#xff0c;那么for循环肯定是避免不了的&#xff0c;当i&#xff08;所有盒子的索引&#xff09;的时候&#xff0c;盒子应该在第一行。比如说我们一行有5个盒子&#xff0c;那么第五个盒子的索引就是4&#xff0c;由于4<5&#xff0c;所以在第一行&#xff0c;如果索引为6&#xff0c;由于6>5&#xff0c;所以在第二行。代码基本就是这个样子

if (i }

  • 知道了盒子在第1行之后&#xff0c;我们只需要动态的设置盒子的left值就能排列好了。
  • 怎么动态计算每个盒子的left值呢&#xff1a;left&#61;i*(itemWidth&#43;gap)&#xff0c;比如说我们排列第二个盒子&#xff0c;它的索引值i就是1&#xff0c;i*(itemWidth&#43;gap)刚好就是第一个盒子和间隙的宽度和&#xff0c;所以距离left值也刚刚好。

说了这么多&#xff0c;画个图理解一下&#xff1a;

037f792341161a3b2d911657e84986cb.png
获取left值

&#xff08;五&#xff09;获取所有列的高度和

  • 在第一行排列好后&#xff0c;我们就需要排列第二行了&#xff0c;但是第二行我们需要用到top值了&#xff0c;前面原理的时候说了&#xff0c;我们就是根据每一列的最小高度和来进行排列&#xff0c;所以这里我们需要计算出第一行所有列的高度和并保存。
  • 我们定义一个数组arr来保存高度。

我们需要在页面一进入的时候就获取高度&#xff0c;也就是写在onload里面&#xff0c;因为图片的加载特征是&#xff1a;等页面都加载完之后才去请求加载&#xff0c;所以不写在入口函数里可能会出现高度获取不到的情况。

&#xff08;六&#xff09;排列第二行

  • 获取到刚刚数组中&#xff0c;高度最小的那一列&#xff0c;将第2行的第1个盒子放置在它的下方&#xff1b;
  • 此时的left值就是高度最小列的offsetLeft&#xff1b;top值就是第1行高度最小列的高度(为了布局美观可以加上上下间隙gap)。
  • 记录下高度最小列的索引index&#xff0c;后面计算会用到&#xff1b;
  • 设置完成之后&#xff0c;会发现后面所有的盒子都叠在这个高度最小列的下面&#xff0c;原因就是此时的最小列高度没有改变&#xff0c;应该加上下面盒子 的高度&#xff0c;得出一个新高度。我们需要在最小列后面加了一个盒子之后重新计算所有列的最小高度的列。

看图说话&#xff1a;我们看到第六个盒子下面下面全是其他盒子。

542058135e7be5a039132f1ec742369e.png
将第二行第一个盒子排列在最小高度和的那一列下面

&#xff08;七&#xff09;重新获取最小高度列的高度

  • 排了第二行的第一个盒子之后&#xff0c;最小高度列已经发生了变化&#xff0c;我们需要重新计算一下
  • 当前高度最小列的高度 &#61; 当前高度最小列的高度 &#43; 间隙 &#43; 下面图片盒子的高度

看图说话&#xff1a;现在知道我们保留index做什么了吧。

02ac20560c6c4384dfd9d7061259ca34.png

&#xff08;八&#xff09;设置为响应式

  • 将整个设置样式的部分封装成一个函数&#xff0c;在onload里面注册一个resize事件&#xff0c;只要页面一发生改变&#xff0c;就触发样式部分的代码。

实时改变pageWidth的宽度&#xff0c;这样瀑布流就会是一个响应式的效果了

&#xff08;九&#xff09;添加懒加载效果

懒加载的实现原理可以参考我的上一篇文章&#xff0c;说得很清楚详细。大致原理用一张图来描述&#xff1a;

fb13b3314017b987f332a51e8b3ad6eb.png
懒加载实现原理图

&#xff08;十&#xff09;所有代码(没有包含懒加载代码)





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22



注意&#xff1a;如果要加入懒加载效果的话&#xff0c;可以参考我的之前一篇文章&#xff0c;讲的较为详细&#xff0c;由于这里没有在

里面添加图片&#xff0c;所以&#xff0c;不能实现懒加载效果。这里只设置了div&#xff0c;并且分别给div设置的高度&#xff0c;稍加繁琐。如果有合适的图片资源&#xff0c;可以不用设置。

五.总结

到这里&#xff0c;我们的瀑布流式布局布局也算讲完了&#xff0c;讲得过程比较啰嗦&#xff0c;也是为了让更多的人能够轻松理解。从整个实现过程来看&#xff0c;我们主要有两个重点&#xff1a;

  • 瀑布流式布局是利用定位来实现的&#xff0c;动态的改变元素的top和left值。
  • 获取最小高度和的列并保存它的索引&#xff0c;以便让下一行的元素知道该放在哪里。

六.源码

更多源码请移步GitHub&#xff1a;

Hacker233/Javascript​github.com
a5117b9de1b68f97d0c01047809fcc20.png



推荐阅读
author-avatar
amy
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有