原生js实现图片瀑布流布局,注释超详细
完整代码:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>瀑布流</title>
- <style type="text/css">
- img {
- width: 300px;
- }
- li {
- position: absolute;
- s left: 0;
- top: 0;
- list-style: none;
- }
- ul {
- margin: 0 auto;
- position: relative;
- }
- * {
- margin: 0;
- padding: 0;
- }
- </style>
- </head>
- <body>
- <ul></ul>
- </body>
- <script src="utils.js"></script>
- <script>
- let ul = document.querySelector('ul'), //获取ul标签
- list = ul.children, //动态更新ul里面的子元素
- teep = 10, //间距
- width = 300, //每张图片的宽度
- cols = Math.floor(document.documentElement.clientWidth / (width + teep)), //计算有多少列
- hh = [], //存取每一列的高度
- num = 0, //记录加载完成图片数量
- om = 0 //记录已经排版完成的li数量
- ul.style.width = cols * (width + teep) - teep + 'px' //计算ul的宽度
- get({ //提前封装好的方法
- url: 'http://rap2.taobao.org:38080/app/mock/256901/json'
- })
- .then(a => { //请求数据
- a = JSON.parse(a).img
- let dom = document.createDocumentFragment() //创建文档碎片
- a.forEach((item, index) => { //有多少条数据就创建多少个li
- let li = document.createElement('li')
- li.innerHTML = `<img src="${item.src}">`
- dom.appendChild(li) //把li添加到文档碎片中
- })
- ul.appendChild(dom) //将文档碎片添加到ul中
- let imgs = Array.from(list).reduce((curr, item, index) => { //将每张img节点组成数组
- if (om <= index) {
- curr.push(item.querySelector('img'))
- }
- return curr
- }, [])
- Array.from(imgs).forEach(item => { //遍历每张图片
- item.onload = () => { //该图片加载完成
- num++
- if (num === imgs.length) { //图片都加载完成了
- for (let i = om; i < list.length; i++) { //遍历ul下的每个li
- if (i < cols) { //给第一行每个li设置left/top值
- list[i].style.left = (width + teep) * i + 'px'
- list[i].style.top = teep + 'px'
- hh.push(list[i].offsetHeight + teep * 2)
- } else { //除了第一行剩下的li
- let minHeight = Math.min(...hh) //求出最小高度
- let minIndex = hh.indexOf(minHeight) //求出最小高度的索引值
- list[i].style.left = (width + teep) * minIndex + 'px'
- list[i].style.top = minHeight + 'px'
- hh[minIndex] = list[i].offsetHeight + minHeight + teep //将最小高度更新
- }
- }
- om = list.length //更新排版完成数量
- ul.style.height = ul.scrollHeight + 'px' //给ul设置高度
- }
- }
- })
- })
- </script>
- </html>
如果要复制运行看效果的话,需要引入我已经封装好的get请求方法
代码如下:
- function ajax(obj, fn) {
- let ajx = new XMLHttpRequest() //创建ajax实例
- obj.type = obj.type ? obj.type : 'get' //判断type存不存在,不存在默认等于get
- let data = '' //向后端发送的数据
- if (obj.data) { //判断是否存在
- for (let i in obj.data) {
- data += i + '=' + obj.data[i] + '&' //键值拼接成name=zhagnsan&age=18形式
- }
- let k = data.split('')
- k.splice(data.length - 1, 1)
- data = k.join('')
- }
- if (obj.type == 'get') { //处理get请求发送数据
- ajx.open(obj.type, obj.url + '?' + data) //地址上拼接数据
- ajx.send()
- } else if (obj.type == 'post') { //处理post请求发送数据
- ajx.open(obj.type, obj.url)
- ajx.setRequestHeader('content-type', 'application/x-www-form-urlencoded') //设置请求头
- ajx.send(data) //发送数据
- }
- ajx.onreadystatechange = () => {
- if (ajx.readyState == 4) {
- if (ajx.status == 200) {
- /*
- 将得到的数据传给回调函数
- 短路写法,如果不传fn为空不会执行,有值就执行
- */
- fn && fn(ajx.responseText)
- }
- }
- }
- }
- // ajax({ //调用封装的方法
- // type: 'get', //可以不写,默认get
- // url: 'http://localhost/day02/api/gouwu.php', //请求地址
- // data: { //需要传输的数据,可选
- // name: 'zhangsan',
- // age: 18
- // }
- // },a=>{//处理的到的数据
- // console.log(a)
- // })
- function jsonp(obj) {
- let sc = document.createElement('script')
- let data = ''
- if (obj.data) {
- for (let i in obj.data) {
- data += `${i}=${obj.data[i]}&`
- }
- data = data.slice(0, -1)
- sc.setAttribute('src', obj.url + `?cd=${obj.cd}&${data}`)
- } else {
- sc.setAttribute('src', obj.url + `?cd=${obj.cd}`)
- }
- document.body.appendChild(sc)
- }
- // jsonp({
- // url:'http://localhost/day02/api/gouwu.php',
- // cd:'fn'
- // },a=>{
- // console.log(a)
- // })
- function get(obj) {
- return new Promise((resolve, reject) => {
- let a = new XMLHttpRequest()
- let data = ''
- if (obj.data) {
- for (let i in obj.data) {
- data += i + '=' + obj.data[i] + '&'
- }
- data = data.slice(0, -1)
- a.open('get', obj.url + '?' + data)
- }else{
- a.open('get', obj.url)
- }
- a.send()
- a.onreadystatechange = () => {
- if (a.readyState === 4) {
- if (a.status === 200) {
- resolve(a.responseText)
- } else {
- reject()
- }
- }
- }
- })
- }
- // get({//调用格式
- // url:'http://localhost/day02/api/gouwu.php',//获取的地址
- // data:{ //可不写
- // a:1,
- // b:2
- // }
- // }).then(a=>{//获取数据成功
- // console.log(a)
- // }).catch(err=>{ //获取数据失败
- // console.log(err)
- // })
原生js实现图片瀑布流布局,注释超详细的更多相关文章
- 原生js实现的瀑布流布局
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- js 实现图片瀑布流效果,可更改配置参数 带完整版解析代码[waterFall.js]
前言: 本人纯小白一个,有很多地方理解的没有各位大牛那么透彻,如有错误,请各位大牛指出斧正!小弟感激不尽. 本篇文章为您分析一下原生JS实现图片瀑布流效果 页面需求 1 ...
- 原生JS—实现图片循环切换的两种方法
今天我们主要讲讲如何使用原生JS实现图片的循环切换的方法.多余的话我们就不多说了,我们一个一个开始讲吧. 1 原生JS实现图片循环切换 -- 方法一 在上栗子之前我们先简单介绍一下所用的一些知识点. ...
- 原生JS—实现图片循环切换及监测鼠标滚动切换图片
今天我们主要讲讲如何使用原生JS实现图片的循环切换的方法以及如何检测鼠标滚动循环切换图片.多余的话我们就不多说了,我们一个一个开始讲吧. 1 原生JS实现图片循环切换 -- 方法一 在上栗子之前我们 ...
- 页面性能优化-原生JS实现图片懒加载
在项目开发中,我们往往会遇到一个页面需要加载很多图片的情况.我们可以一次性加载全部的图片,但是考虑到用户有可能只浏览部分图片.所以我们需要对图片加载进行优化,只加载浏览器窗口内的图片,当用户滚动时,再 ...
- 原生js实现图片轮播思路分析
一.复习原生js实现图片轮播 1.要点 自动轮播 点击小圆圈按钮,显示相应图片 点击左右箭头,实现向前向后轮播图片 2.实现思路 <div id="container"> ...
- 原生JS实现图片循环切换
<!-- <!DOCTYPE html> <html> <head> <title>原生JS实现图片循环切换 —— 方法一</title&g ...
- 原生 JS 实现一个瀑布流插件
更好的阅读体验,点击 原文地址 瀑布流布局中的图片有一个核心特点 -- 等宽不定等高,瀑布流布局在国内网网站都有一定规模的使用,比如pinterest.花瓣网等等.那么接下来就基于这个特点开始瀑布流探 ...
- 基于原生js的图片延迟加载
当页面图片比较多的时候,我们通常会做一个延迟加载,避免页面打开时一下子的请求数太多,加载过慢影响用户体验. 如果项目用了jquery框架,则可以直接用 jquery.lazyload.可在jquery ...
随机推荐
- HttpServletResponse和HttpServletRequest的简单实用
1.HttpServletResponse web服务器接收到客户端的http请求,针对这个请求,分别创建一一个代表请求的HttpServletRequest 对象,代表响应的- -个HttpServ ...
- 数据结构----链表Link
链表简介与数据结构 单向链表也叫单链表,是表中最简单的一种形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域.这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值. 单向链 ...
- 苏浪浪 201771010120 第三周 Java基本程序设计总结
理论知识: Java有五种语句: (1)方法调用语句(2)表达式语句(3)复合语句(4)控制语句(5)package.import语句 3.8控制流程 3.9大数值 *如果基本的整型和浮点型数据无法达 ...
- HDU2819
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2819 题目大意: 给出一个N*N的0/1矩阵,只能交换整行或者整列,问最少交换多少次可以变成一个主对角 ...
- 统计元音(hdu20)
输入格式:输入一个整型,再循环输入带空格的字符串. 思考:先用scanf()函数输入一个整型,后面直接来个大循环,带空格字符串输入直接用gets()函数. 注意:由于scanf()里面多加了%c,&a ...
- 【Java】几种典型的内存溢出案例,都在这儿了!
写在前面 作为程序员,多多少少都会遇到一些内存溢出的场景,如果你还没遇到,说明你工作的年限可能比较短,或者你根本就是个假程序员!哈哈,开个玩笑.今天,我们就以Java代码的方式来列举几个典型的内存溢出 ...
- Kubernetes 基础资料
概述 这篇文章用来记录Kubernetes 的基础资料,整体以最新官方文档为准. 因为k8s整体比较偏运维,作为研发可先大致了解其概念及初级使用方式,后面重点学习点会放在service mesh is ...
- Pytorch写CNN
用Pytorch写了两个CNN网络,数据集用的是FashionMNIST.其中CNN_1只有一个卷积层.一个全连接层,CNN_2有两个卷积层.一个全连接层,但训练完之后的准确率两者差不多,且CNN_1 ...
- css background-image 学习笔记
先给出图片原样 1.默认从从上到右下1比1 填充的,如果元素的高度和宽度小于图片,则只能显示部分图片.效果如下图 2.如果元素的高度和宽度大于图片,则默认会用图片平铺元素.效果如下图 3.可以是用ba ...
- 50个SQL语句(MySQL版) 问题十一
--------------------------表结构-------------------------- student(StuId,StuName,StuAge,StuSex) 学生表 tea ...