原生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 ...
随机推荐
- ambari hdp ssh链接错误
错误信息: ERROR 2019-09-05 10:29:05,700 NetUtil.py:96 - EOF occurred in violation of protocol (_ssl.c:57 ...
- hdu2138 How many prime numbers 米勒测试
hdu2138 How many prime numbers #include <bits/stdc++.h> using namespace std; typedef long long ...
- 查找算法----二分查找与hash查找
二分查找 有序列表对于我们的实现搜索是很有用的.在顺序查找中,当我们与第一个元素进行比较时,如果第一个元素不是我们要查找的,则最多还有 n-1 个元素需要进行比较. 二分查找则是从中间元素开始,而不是 ...
- 《机器学习_07_02_svm_软间隔支持向量机》
一.简介 上一节介绍了硬间隔支持向量机,它可以在严格线性可分的数据集上工作的很好,但对于非严格线性可分的情况往往就表现很差了,比如: import numpy as np import matplot ...
- ES[7.6.x]学习笔记(九)搜索
搜索是ES最最核心的内容,没有之一.前面章节的内容,索引.动态映射.分词器等都是铺垫,最重要的就是最后点击搜索这一下.下面我们就看看点击搜索这一下的背后,都做了哪些事情. 分数(score) ES的搜 ...
- Apache Module mod_reqtimeout
Apache Module mod_reqtimeout Available Languages: en Description: Set timeout and minimum data rate ...
- Spring 基于注解的配置 简介
基于注解的配置 从 Spring 2.5 开始就可以使用注解来配置依赖注入.而不是采用 XML 来描述一个 bean 连线,你可以使用相关类,方法或字段声明的注解,将 bean 配置移动到组件类本身. ...
- LightOJ1197
题目链接:https://vjudge.net/problem/LightOJ-1197 题目大意: 给你 a 和 b (1 ≤ a ≤ b < 231, b - a ≤ 100000),求出 ...
- 一个茴字有三种写法——吐槽C#9.0的Records
最近是微软开了Build 2020大会,由于疫情原因,改成了在线举行,Build大会上,C#公布9.0版本. 我个人对于C#的更新向来都是喜闻乐见,乐于接受的,对于博客园上某些人天天嘲讽C#只会增加语 ...
- python+selenium 自动化测试框架-学习记录
本人小白一枚,想着把学习时的东西以博客的方式记录下来,文章中有不正确的地方请大佬多多指点!!共同学习 前期准备 安装python3.selenium.下载对应版本的webdriver:安装所需的第三 ...