前端瀑布流详解以及前后台交互瀑布流

一、前端简单瀑布流以及无限加载瀑布流

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<style>
    .container{  position: relative; margin: 0 auto;  }
    .in{  float: left;  }
    .in img{
    	margin:10px;
    	padding:10px;
    	border: 1px solid pink;
    	border-radius: 15px;
    	box-shadow: 0 0 5px orange;
    }
	</style>
</head>
<body>
	<div class="container"></div>
	<script>
	//得到外部div元素
	var outDiv = document.querySelector('.container');
	//模拟后台给的数据
    var imgArr = ['1','2','3','4','5','6','7','8','9','10','11','12','13','14','15'];
    
    //填充图片
    function fullImg (){
    	//循环遍历img数组
    	for(var i=0; i<imgArr.length; i++){
    		// 创建div包裹img元素  有多少img创建多少个div
	    	var div = document.createElement('div');
	    	//给每一个div设置类名in
	    	div.className = 'in';
	    	//添加img元素
	    	div.innerHTML = '<img src="images/pblimg/i'+imgArr[i]+'.jpg" alt="">';
	    	//把每一个div拼接到外部div中
	    	outDiv.append(div);
        }
    }
    //构建瀑布流形式
    function creatWaterFull (){
    	//得到页面中所有的放img的div
    	var indivs = document.getElementsByClassName('in');
    	//用页面宽度除以任意一个div的宽度向下取整得到一行可以放几个div
	    var num = Math.floor(document.documentElement.clientWidth/indivs[0].offsetWidth);
	    //根据一行可以放几个div,然后乘以任意一个div的宽度得到外部div的宽度,进而实现盒子居中
	    outDiv.style.width = num * indivs[0].offsetWidth + 'px';
	    //定义空数组存放第一行div的高
	    var heightArr = [];
	    //遍历所有div
	    for(var i=0; i<indivs.length; i++){
	    	//如果i<num 说明是第一行的div元素 
	    	if(i<num){
	    		//把第一行的div的高放到高度数组里
	    		heightArr.push(indivs[i].offsetHeight);
	    	//否则 是其余所有行的div元素
	    	}else{
	    		//给每一个div开启定位
	    		indivs[i].style.position = 'absolute';
	    		//巧用apply方法 得到heightArr高度数组中最小的那个高,赋值给变量minHeight
	    		var minHeight = Math.min.apply(null,heightArr);
	    		//得到最小的那个高在高度数组中的下标(因为和indivs数组里的下标是同步的)
	    		var minIndex = heightArr.indexOf(minHeight);
	    		//设置top值  top值就是最小的那个高的高度,上面已经获取到minHeight
	    		indivs[i].style.top = minHeight + 'px';
	    		//设置lef值  left值就是最小的那个高的offsetleft值
	    		//此时minIndex就派上用场了 也就是indiv数组里高度最小的那个div的下标的offsetleft值
	    		indivs[i].style.left = indivs[minIndex].offsetLeft + 'px';
	    		//变更高度数组,heightArr数组里面最小的那个高每次加上当前的高
	    	    heightArr[minIndex] += indivs[i].offsetHeight;
	    	}
	    }
    }
    // 封装成函数,避免代码重复
    fullImg();
    creatWaterFull();


//------------------如果只是简单的瀑布流不需要无限加载,那么到这里也就结束了----------------------



    //判断是否需要再次创建瀑布流  返回值是布尔值
    function isNeedCreat (){
    	//得到页面中的包裹图片的div元素
    	var indivs = document.getElementsByClassName('in');
    	//得到页面的卷动值 兼容高级浏览器和低版本IE
    	var scrollHeight = document.body.scrollTop || document.documentElement.scrollTop;
    	//得到div数组里的最后一个div的top值
    	var lastTop = indivs[indivs.length-1].offsetTop;
    	//得到视口的高度
    	var viewHeight = document.documentElement.clientHeight;
    	//判断 如果卷动了的高度加视口的高度大于了最后一个div的top值
    	//也就是最后一张图片刚刚出现的时候,开始加载下一批图片,返回一个true 代表开始创建
    	if(scrollHeight + viewHeight > lastTop){
    		return true;
    	}
    }
    // 当页面滚动时,判断是否需要创建 这就实现了无限加载
    document.onscroll = function (){
    	// 如果是true 代表需要创建瀑布流
    	if(isNeedCreat()){
    		//然后调用填充图片和构建瀑布流的函数
    		fullImg();
    		creatWaterFull();
    	}
    }
	</script>
</body>
</html>

二、前后端交互瀑布流

前端代码:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<style>
	    .container{  position: relative; margin: 0 auto;  }
	    .in{  float: left;  }
	    .in img{
	    	margin:10px;
	    	padding:10px;
	    	border: 1px solid pink;
	    	border-radius: 15px;
	    	box-shadow: 0 0 5px orange;
	    }
	</style>
</head>
<body>
	<div class="container"></div>
	<script src='yangjieAjax.js'></script>     //这里是引入了自己封装的ajax 参考‘jquery中的ajax、原生ajax和自封装ajax’
	<script>
    var outDiv = document.getElementsByClassName('container')[0];
    var imgArr;
    window.yangjieAjax({
    	type:'get',
    	url:'waterFull.php',
    	async:true,
    	data:{},
    	success:function (res){
    		imgArr = res.info;
                fullImg();
                creatWaterFull();
                document.onscroll = function (){
		    	if(isNeedCreat()){
		    		fullImg();
		    		creatWaterFull();
		    	}
		}
    	}
    })

    function fullImg (){
    	for(var i=0; i<imgArr.length; i++){
	    	var div = document.createElement('div');
	    	div.className = 'in';
	    	div.innerHTML = '<img src="images/pblimg/i'+imgArr[i]+'.jpg" alt="">';
	    	outDiv.append(div);
        }
    }
    function creatWaterFull (){
    	var indivs = document.getElementsByClassName('in');
	    var num = Math.floor(document.documentElement.clientWidth/indivs[0].offsetWidth);
	    outDiv.style.width = num * indivs[0].offsetWidth + 'px';
	    var heightArr = [];
	    for(var i=0; i<indivs.length; i++){
	    	if(i<num){
	    		heightArr.push(indivs[i].offsetHeight);
	    	}else{
	    		indivs[i].style.position = 'absolute';
	    		var minHeight = Math.min.apply(null,heightArr);
	    		var minIndex = heightArr.indexOf(minHeight);
	    		indivs[i].style.top = minHeight + 'px';
	    		indivs[i].style.left = indivs[minIndex].offsetLeft + 'px';
	    	    heightArr[minIndex] += indivs[i].offsetHeight;
	    	}
	    }
    }
    
    function isNeedCreat (){
    	var indivs = document.getElementsByClassName('in');
    	var scrollHeight = document.body.scrollTop || document.documentElement.scrollTop;
    	var lastTop = indivs[indivs.length-1].offsetTop;
    	var viewHeight = document.documentElement.clientHeight;
    	if(scrollHeight + viewHeight > lastTop){
    		return true;
    	}
    }
	</script>
</body>
</html>

后台php代码:

<?php

$imgArr = ['1','2','3','4','5','6','7','8','9','10','11','12','13','14','15'];
$success = array('msg' => 'ok','info' => $imgArr);
echo json_encode($success);

?>

三、连接数据库(运用原生方式) 把数据放到数据库中,前端代码不变 更换php代码

<?php

$success = array('msg' => 'ok');
//连接数据库
$con = mysqli_connect('localhost','root','','imgdb');
//判断是否成功连接数据库(也就是加个保险)
if($con){
	//避免乱码
	mysqli_query($con,'set names utf8');
	mysqli_query($con,'set character_set_client=utf8');
	mysqli_query($con,'set character_set_results=utf8');
	//执行查询语句  结果存放在一个变量里
	$result = $con->query('select * from imglist where 1');
	//定义空数组存放从数据库遍历出来的数据
	$info = [];
	//遍历查询出来的结果
	for($i=0; $row=$result->fetch_assoc(); $i++){
		$info[$i] = $row;
	}
	// 遍历$info数组 存放在$imgArr数组中,返回给前端
	for($j=0; $j<count($info); $j++){
		$imgArr[$j]=$info[$j]['src'];
	}
	//作为$success的属性返还给前端
	$success['info'] = $imgArr;
}else{
	'数据库连接失败';
}

echo json_encode($success);

?>

四、连接数据库(运用pdo方式)

<?php
//运用pdo方式连接数据库

class singleTonPdo{
	private static $pdo = null;
	public static function getPdo(){
		if(self::$pdo==null){
			try{
				self::$pdo = new PDO('mysql:host=localhost;dbname=imgdb','root','');
	            self::$pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
			}catch(PDOException $e){
				echo $e->getMessage();
			}
		}
		return self::$pdo;
	}
}
$success = array('msg'=>'ok');
$pdo = singleTonPdo::getpdo();
$pdo->query('set names utf8');
$pdo->exec('set names utf8');
try{
	$pdo->beginTransaction();
	$pdoso = $pdo->prepare('select * from imglist where 1');
	$pdoso->execute();
	$pdoso->bindColumn(1,$src);
	$info = [];
	for($i=0; $pdoso->fetch(PDO::FETCH_ASSOC); $i++){
		$info[$i] = ['lujing'=>$src];
	}
    for($j=0; $j<count($info); $j++){
    	$imgArr[$j] = $info[$j]['lujing'];
    }
    $success['info']=$imgArr;
	$pdo->commit();
}catch(PDOException $e){
	$pdo->rollBack();
	echo '失败' ;
}

echo json_encode($success);
?>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值