JS实现动态瀑布流及放大切换图片效果(js案例)
整理了一下当时学js写的一些案例,再次体验了一把用原生JS实现动态瀑布流效果的乐趣,现在把它整理出来,需要的小伙伴可以参考一下。
该案例主要是用HTML+CSS控制样式,通过JS实现全局瀑布流以及点击图片放大、上下切换效果。HTML布局写的很简单,图片加载主要是在JS中通过访问自定义的JSON字符串来实现。
动态瀑布流的原理简单理解就是把新需要加载的图片放在上一排总高度最小的图片或模块下面,实现参差不齐的多栏布局效果。
具体效果如下:
做这个案例我用了之前自己封装的框架,所以小伙伴需要到我的另一篇文章里面自己下载,链接:https://www.cnblogs.com/xyyl/p/10912037.html
**HTML代码:**
<template id="temp"> <div> <figure> <img src="{{img}}"> <p>{{info}}</p> </figure> </div> </template> <template id="temp1"> <img src="{{src}}"> <p>{{info}}</p> <aside> <a href="##" class="prev">上一张</a> <a href="##" class="next">下一张</a> </aside> </template> <section id="box" class="box"></section> <div id="show_big" class="show_big"> <img src="images/w_1.jpg"> <p id="txt">这是详细内容</p> <aside> <a href="##" class="pre">上一张</a> <a href="##" class="next">下一张</a> </aside> </div> <div class="mask" id="mask"></div> <span id="show" class="show"></span>
**css代码:**
*{ margin: 0; padding: 0; } section.box{ margin: 0 auto; position: relative; font-size: 0;//行块取消间距 } section.box div{ width: 200px; padding: 14px 7px 0; box-sizing: border-box; /*float: left;*/ display: inline-block; vertical-align: top; } section.box div figure{ border: 1px #cccccc solid; border-radius: 4px; padding: 10px; box-shadow: 0 0 3px 1px rgba(0,0,0,.1); } section.box div figure img{ width: 100%; } section.box div figure p{ font-size: 16px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } span.show{ position: fixed; bottom: 0; } div.show_big{ background-color: #f2f2f2; border-radius: 4px; position: fixed; padding: 10px; top: 50px; box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.5); display: none; z-index: 100; } div.mask{ content: ''; position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(101, 101, 101, 0.28); display: none; } div.show_big img{ border-radius: 3px; } div.show_big p{ font-size: 13px; color: #666666; text-indent: 2em; line-height: 17px; margin-bottom: 10px; overflow : hidden;/*多行文本省略号*/ text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; } div.show_big aside{ display: flex; justify-content: space-around; } div.show_big a{ display: inline-block; padding: 5px 13px; background-color: #318fff; color: white; line-height: 17px; text-decoration: none; border-radius: 2px; }
**JS代码:**
var data=[ {src:'images/w_1.jpg',info:'描述内容描述内容描述内容描述内容描述内容描述内容描述内容描述内容描述内容描述内容描述内容描述内容描述内容描述内容描述内容描述内容描述内容描述内容'}, {src:'images/w_2.jpg',info:'描述内容'}, {src:'images/w_3.jpg',info:'描述内容'}, {src:'images/w_4.jpg',info:'描述内容'}, {src:'images/w_5.jpg',info:'描述内容'}, {src:'images/w_6.jpg',info:'描述内容'}, {src:'images/w_7.jpg',info:'描述内容'}, {src:'images/w_8.jpg',info:'描述内容'}, {src:'images/w_9.jpg',info:'描述内容'}, {src:'images/w_10.jpg',info:'描述内容'}, {src:'images/w_11.jpg',info:'描述内容'}, {src:'images/w_17.jpg',info:'描述内容'} ]; var data1=[ {src:'images/w_4.jpg',info:'描述内容'}, {src:'images/w_5.jpg',info:'描述内容'}, {src:'images/w_6.jpg',info:'描述内容'}, {src:'images/w_7.jpg',info:'描述内容'}, {src:'images/w_8.jpg',info:'描述内容'}, {src:'images/w_9.jpg',info:'描述内容'}, {src:'images/w_17.jpg',info:'描述内容'} ]; var json={data,data1};//这里是图片数据 var img_w=200; var len; var box=sEO.$('#box'); resize(); function resize() { //len:每排显示的图片数目 len=parseInt((window.innerWidth-17)/img_w); box.style.width=len*img_w+'px';//瀑布流总的宽度 } var temp=sEO.$('#temp').innerHTML; function load_img(arr) { //动态添加图片 var str=''; arr.forEach(function (el,i) { str+=temp.replace('{{img}}',el.src).replace('{{info}}',el.info); }); box.innerHTML+=str; } load_img(data);//自动加载图片带HTML中 var divs=sEO.$('#box div'); function isComplete(els,fun) {//判断图片是否全部加载完成,完成之后才执行回调函数fun var flag=true;//设置一个标志,flag=true表示所有图片加载完成 els.forEach(function (div,i) { var img=div.getElementsByTagName('img')[0]; if (!img.complete)flag=false;//表示存在图片加载未完成 return false; }); if (flag)fun(); } function water(oarr) {//瀑布流具体实现 var arr=[]; var timer=setInterval(function () { isComplete(oarr,function () { clearInterval(timer); oarr.forEach(function (div, i) { if (i<len){ arr.push(div.offsetHeight);//把第一排div的高储存起来 }else {//通过div的left和top决定div的位置 var min_h=Math.min.apply(null,arr);//求上一排总高度的最小值 var index=arr.indexOf(min_h);//求最小高度那一列的下标 div.style.cssText=`position: absolute;left: ${index*img_w}px;top: ${arr[index]}px;`; arr[index]+=div.offsetHeight;//储存的当前添加图片的那一列的高度改变 } }) }) },100); } water(divs); var j_len=json.length,j=1; var show=sEO.$('#show'); window.onscroll=function () { var div_e=divs[divs.length-1]; var h=div_e.offsetHeight; var top=div_e.offsetTop; if (sEO.getScroll(document).top+window.innerHeight>h/2+top){ if (j<j_len){ //当最后半屏图片即将显示完时 load_img(data1); //动态添加数据 divs=sEO.$('#box div'); water(divs); j++; }else {//当导航条滑动到最后时提示,页面到底 show.innerText='我是有底线的噢'; show.style.left=(window.innerWidth-show.offsetWidth)/2+'px'; } }else { show.innerText=''; } }; divs=sEO.$('#box div'); window.onresize=function () {//浏览器窗口发生变化,瀑布流排列调整 resize(); water(divs) }; divs.forEach(function (div,i) {//未每张图片添加自定义属性i div.i=i; }); /*到这里动态瀑布流结束, 接下来是点击图片放大及上下切换效果实现*/ var temp1=sEO.$('#temp1').innerHTML; var show_big=sEO.$('#show_big'); var info=sEO.$('#txt'); var mask=sEO.$('#mask'); var index,txt,show_imgW; sEO.agent(box,'img','click',function () {//为每张图片添加事件代理 show_big.style.display='block'; src=this.getAttribute('src'); txt=this.nextElementSibling.innerHTML; public_b(); mask.style.display='block'; index=this.parentNode.parentNode.i; //当前点击的图片位置 }); sEO.agent(show_big,'a','click',function () { //为左右图片切换按钮添加时间代理 var cls=this.className; cls==='prev'?index--:index++; index=index===-1?(divs.length-1):index;/*图片循环加载*/ index=index===divs.length?0:index; src=divs[index].children[0].children[0].getAttribute('src');/*点击之后图片路径*/ txt=divs[index].children[0].children[1].innerHTML;/*点击之后图片描述内容*/ public_b() }); var show_img,max_h; function public_b() { show_big.innerHTML=temp1.replace('{{src}}',src).replace('{{info}}',txt); show_img=show_big.children[0]; // var img_h=show_big.children[0].offsetHeight; max_h=window.innerHeight-140; // if (img_h>max_h)img_h=max_h; show_img.style.height=max_h+'px'; show_imgW=show_big.children[0].offsetWidth; show_big.style.width=show_imgW+'px'; info.style.width=show_imgW-20+'px'; show_big.style.left=(window.innerWidth-show_imgW)/2+'px'; show_img.onclick=mask.onclick=hidden; } function hidden() { show_big.style.display=''; mask.style.display=''; this.onclick=null; }