完整代码:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>瀑布流</title>
  7. <style type="text/css">
  8. img {
  9. width: 300px;
  10.  
  11. }
  12.  
  13. li {
  14. position: absolute;
  15. s left: 0;
  16. top: 0;
  17. list-style: none;
  18. }
  19.  
  20. ul {
  21. margin: 0 auto;
  22. position: relative;
  23. }
  24.  
  25. * {
  26. margin: 0;
  27. padding: 0;
  28. }
  29. </style>
  30. </head>
  31. <body>
  32. <ul></ul>
  33. </body>
  34. <script src="utils.js"></script>
  35. <script>
  36. let ul = document.querySelector('ul'), //获取ul标签
  37. list = ul.children, //动态更新ul里面的子元素
  38. teep = 10, //间距
  39. width = 300, //每张图片的宽度
  40. cols = Math.floor(document.documentElement.clientWidth / (width + teep)), //计算有多少列
  41. hh = [], //存取每一列的高度
  42. num = 0, //记录加载完成图片数量
  43. om = 0 //记录已经排版完成的li数量
  44. ul.style.width = cols * (width + teep) - teep + 'px' //计算ul的宽度
  45. get({ //提前封装好的方法
  46. url: 'http://rap2.taobao.org:38080/app/mock/256901/json'
  47. })
  48. .then(a => { //请求数据
  49. a = JSON.parse(a).img
  50. let dom = document.createDocumentFragment() //创建文档碎片
  51. a.forEach((item, index) => { //有多少条数据就创建多少个li
  52. let li = document.createElement('li')
  53. li.innerHTML = `<img src="${item.src}">`
  54. dom.appendChild(li) //把li添加到文档碎片中
  55. })
  56. ul.appendChild(dom) //将文档碎片添加到ul中
  57. let imgs = Array.from(list).reduce((curr, item, index) => { //将每张img节点组成数组
  58. if (om <= index) {
  59. curr.push(item.querySelector('img'))
  60. }
  61. return curr
  62. }, [])
  63.  
  64. Array.from(imgs).forEach(item => { //遍历每张图片
  65. item.onload = () => { //该图片加载完成
  66. num++
  67. if (num === imgs.length) { //图片都加载完成了
  68. for (let i = om; i < list.length; i++) { //遍历ul下的每个li
  69. if (i < cols) { //给第一行每个li设置left/top值
  70. list[i].style.left = (width + teep) * i + 'px'
  71. list[i].style.top = teep + 'px'
  72. hh.push(list[i].offsetHeight + teep * 2)
  73. } else { //除了第一行剩下的li
  74. let minHeight = Math.min(...hh) //求出最小高度
  75. let minIndex = hh.indexOf(minHeight) //求出最小高度的索引值
  76. list[i].style.left = (width + teep) * minIndex + 'px'
  77. list[i].style.top = minHeight + 'px'
  78. hh[minIndex] = list[i].offsetHeight + minHeight + teep //将最小高度更新
  79. }
  80. }
  81. om = list.length //更新排版完成数量
  82. ul.style.height = ul.scrollHeight + 'px' //给ul设置高度
  83. }
  84. }
  85. })
  86. })
  87. </script>
  88. </html>

如果要复制运行看效果的话,需要引入我已经封装好的get请求方法

代码如下:

  1. function ajax(obj, fn) {
  2. let ajx = new XMLHttpRequest() //创建ajax实例
  3. obj.type = obj.type ? obj.type : 'get' //判断type存不存在,不存在默认等于get
  4. let data = '' //向后端发送的数据
  5. if (obj.data) { //判断是否存在
  6. for (let i in obj.data) {
  7. data += i + '=' + obj.data[i] + '&' //键值拼接成name=zhagnsan&age=18形式
  8. }
  9. let k = data.split('')
  10. k.splice(data.length - 1, 1)
  11. data = k.join('')
  12. }
  13. if (obj.type == 'get') { //处理get请求发送数据
  14. ajx.open(obj.type, obj.url + '?' + data) //地址上拼接数据
  15. ajx.send()
  16. } else if (obj.type == 'post') { //处理post请求发送数据
  17. ajx.open(obj.type, obj.url)
  18. ajx.setRequestHeader('content-type', 'application/x-www-form-urlencoded') //设置请求头
  19. ajx.send(data) //发送数据
  20. }
  21. ajx.onreadystatechange = () => {
  22. if (ajx.readyState == 4) {
  23. if (ajx.status == 200) {
  24. /*
  25. 将得到的数据传给回调函数
  26. 短路写法,如果不传fn为空不会执行,有值就执行
  27. */
  28. fn && fn(ajx.responseText)
  29. }
  30. }
  31. }
  32. }
  33.  
  34. // ajax({ //调用封装的方法
  35. // type: 'get', //可以不写,默认get
  36. // url: 'http://localhost/day02/api/gouwu.php', //请求地址
  37. // data: { //需要传输的数据,可选
  38. // name: 'zhangsan',
  39. // age: 18
  40. // }
  41. // },a=>{//处理的到的数据
  42. // console.log(a)
  43. // })
  44.  
  45. function jsonp(obj) {
  46. let sc = document.createElement('script')
  47. let data = ''
  48. if (obj.data) {
  49. for (let i in obj.data) {
  50. data += `${i}=${obj.data[i]}&`
  51. }
  52. data = data.slice(0, -1)
  53. sc.setAttribute('src', obj.url + `?cd=${obj.cd}&${data}`)
  54. } else {
  55. sc.setAttribute('src', obj.url + `?cd=${obj.cd}`)
  56. }
  57.  
  58. document.body.appendChild(sc)
  59. }
  60.  
  61. // jsonp({
  62. // url:'http://localhost/day02/api/gouwu.php',
  63. // cd:'fn'
  64. // },a=>{
  65. // console.log(a)
  66. // })
  67.  
  68. function get(obj) {
  69. return new Promise((resolve, reject) => {
  70. let a = new XMLHttpRequest()
  71. let data = ''
  72. if (obj.data) {
  73. for (let i in obj.data) {
  74. data += i + '=' + obj.data[i] + '&'
  75. }
  76. data = data.slice(0, -1)
  77. a.open('get', obj.url + '?' + data)
  78. }else{
  79. a.open('get', obj.url)
  80. }
  81. a.send()
  82. a.onreadystatechange = () => {
  83. if (a.readyState === 4) {
  84. if (a.status === 200) {
  85. resolve(a.responseText)
  86. } else {
  87. reject()
  88. }
  89. }
  90. }
  91. })
  92.  
  93. }
  94. // get({//调用格式
  95. // url:'http://localhost/day02/api/gouwu.php',//获取的地址
  96. // data:{ //可不写
  97. // a:1,
  98. // b:2
  99. // }
  100. // }).then(a=>{//获取数据成功
  101. // console.log(a)
  102. // }).catch(err=>{ //获取数据失败
  103. // console.log(err)
  104. // })

原生js实现图片瀑布流布局,注释超详细的更多相关文章

  1. 原生js实现的瀑布流布局

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. js 实现图片瀑布流效果,可更改配置参数 带完整版解析代码[waterFall.js]

    前言:         本人纯小白一个,有很多地方理解的没有各位大牛那么透彻,如有错误,请各位大牛指出斧正!小弟感激不尽.         本篇文章为您分析一下原生JS实现图片瀑布流效果 页面需求 1 ...

  3. 原生JS—实现图片循环切换的两种方法

    今天我们主要讲讲如何使用原生JS实现图片的循环切换的方法.多余的话我们就不多说了,我们一个一个开始讲吧. 1  原生JS实现图片循环切换 -- 方法一 在上栗子之前我们先简单介绍一下所用的一些知识点. ...

  4. 原生JS—实现图片循环切换及监测鼠标滚动切换图片

    今天我们主要讲讲如何使用原生JS实现图片的循环切换的方法以及如何检测鼠标滚动循环切换图片.多余的话我们就不多说了,我们一个一个开始讲吧. 1  原生JS实现图片循环切换 -- 方法一 在上栗子之前我们 ...

  5. 页面性能优化-原生JS实现图片懒加载

    在项目开发中,我们往往会遇到一个页面需要加载很多图片的情况.我们可以一次性加载全部的图片,但是考虑到用户有可能只浏览部分图片.所以我们需要对图片加载进行优化,只加载浏览器窗口内的图片,当用户滚动时,再 ...

  6. 原生js实现图片轮播思路分析

    一.复习原生js实现图片轮播 1.要点 自动轮播 点击小圆圈按钮,显示相应图片 点击左右箭头,实现向前向后轮播图片 2.实现思路 <div id="container"> ...

  7. 原生JS实现图片循环切换

    <!-- <!DOCTYPE html> <html> <head> <title>原生JS实现图片循环切换 —— 方法一</title&g ...

  8. 原生 JS 实现一个瀑布流插件

    更好的阅读体验,点击 原文地址 瀑布流布局中的图片有一个核心特点 -- 等宽不定等高,瀑布流布局在国内网网站都有一定规模的使用,比如pinterest.花瓣网等等.那么接下来就基于这个特点开始瀑布流探 ...

  9. 基于原生js的图片延迟加载

    当页面图片比较多的时候,我们通常会做一个延迟加载,避免页面打开时一下子的请求数太多,加载过慢影响用户体验. 如果项目用了jquery框架,则可以直接用 jquery.lazyload.可在jquery ...

随机推荐

  1. HttpServletResponse和HttpServletRequest的简单实用

    1.HttpServletResponse web服务器接收到客户端的http请求,针对这个请求,分别创建一一个代表请求的HttpServletRequest 对象,代表响应的- -个HttpServ ...

  2. 数据结构----链表Link

    链表简介与数据结构 单向链表也叫单链表,是表中最简单的一种形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域.这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值. 单向链 ...

  3. 苏浪浪 201771010120 第三周 Java基本程序设计总结

    理论知识: Java有五种语句: (1)方法调用语句(2)表达式语句(3)复合语句(4)控制语句(5)package.import语句 3.8控制流程 3.9大数值 *如果基本的整型和浮点型数据无法达 ...

  4. HDU2819

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2819 题目大意: 给出一个N*N的0/1矩阵,只能交换整行或者整列,问最少交换多少次可以变成一个主对角 ...

  5. 统计元音(hdu20)

    输入格式:输入一个整型,再循环输入带空格的字符串. 思考:先用scanf()函数输入一个整型,后面直接来个大循环,带空格字符串输入直接用gets()函数. 注意:由于scanf()里面多加了%c,&a ...

  6. 【Java】几种典型的内存溢出案例,都在这儿了!

    写在前面 作为程序员,多多少少都会遇到一些内存溢出的场景,如果你还没遇到,说明你工作的年限可能比较短,或者你根本就是个假程序员!哈哈,开个玩笑.今天,我们就以Java代码的方式来列举几个典型的内存溢出 ...

  7. Kubernetes 基础资料

    概述 这篇文章用来记录Kubernetes 的基础资料,整体以最新官方文档为准. 因为k8s整体比较偏运维,作为研发可先大致了解其概念及初级使用方式,后面重点学习点会放在service mesh is ...

  8. Pytorch写CNN

    用Pytorch写了两个CNN网络,数据集用的是FashionMNIST.其中CNN_1只有一个卷积层.一个全连接层,CNN_2有两个卷积层.一个全连接层,但训练完之后的准确率两者差不多,且CNN_1 ...

  9. css background-image 学习笔记

    先给出图片原样 1.默认从从上到右下1比1 填充的,如果元素的高度和宽度小于图片,则只能显示部分图片.效果如下图 2.如果元素的高度和宽度大于图片,则默认会用图片平铺元素.效果如下图 3.可以是用ba ...

  10. 50个SQL语句(MySQL版) 问题十一

    --------------------------表结构-------------------------- student(StuId,StuName,StuAge,StuSex) 学生表 tea ...