综合案例

星星评分

  主要思想:鼠标移到某个小星星上,该小星星及它左边的小星星被点亮;如果没有星星被点击,鼠标移出时,所有的小星星变灰,如果有星星被点亮,移出时,点击的小星星及它左边的小星星被点亮;鼠标点击某个小星星时,确定索引值及改变flag的值。
1、HTML结构

<!-- 设置五个li,背景图片为小星星 -->
<ul id="starLists">
	<li></li>
	<li></li>
	<li></li>
	<li></li>
	<li></li>
</ul>
<!-- 提示信息区域 -->
<div id="info"></div>

2、CSS样式

<style type="text/css">
	ul,li{list-style: none;}
	ul li{float: left;width: 27px;height: 28px;
		background: url(star.gif) no-repeat 0 0;}
</style>

3、JS代码

<script type="text/javascript">
	var starLists = document.getElementById("starLists");
	var aStarLi = starLists.children;
	var flag = false; // 初始值为false,即默认没有被点击
	var info = document.getElementById("info");
	var arrInfo = ["一颗星","两颗星","三颗星","四颗星","五颗星"];
	for(let i=0 ; i<aStarLi.length ; i++){
		// 鼠标移入事件
		aStarLi[i].onmouseover = function(){
			// 先清
			for(let j=0 ; j<aStarLi.length ; j++){
				aStarLi[j].style.backgroundPosition = "0 0";
			}
			// 再加,移入的i之前的星星都被点亮
			for(let j=0 ; j<=i ; j++){
				aStarLi[j].style.backgroundPosition = "0 -29px";
			}
			// 设置提示信息为对应数组中的信息
			info.innerText = arrInfo[i];
		}
		// 鼠标移出事件
		aStarLi[i].onmouseout = function(){
			// 先清,无论是否被点击,移出时先清除所有
			for(let j=0 ; j<aStarLi.length ; j++){
				aStarLi[j].style.backgroundPosition = "0 0";
			}
			
			if(flag){
				// 如果被点击,再加,curIndex之前星星点亮
				for(let j=0 ; j<=curIndex ; j++){
					aStarLi[j].style.backgroundPosition = "0 -29px";
				}
				info.innerText = arrInfo[curIndex];
			}else{
				// 没有被点击,提示信息清空
				info.innerText = "";
			}
					
		}
		// 鼠标点击事件
		// 点击之后,设置flag值为true,curIndex确定当前星星的位置
		aStarLi[i].onclick = function(){
			flag = true;
			curIndex = i;
	
		}
	}
</script>

产品放大镜

  主要思想:鼠标移入中图区域时,阴影区域和大图区域显示;鼠标移出时,阴影区域和大图区域隐藏;鼠标移动时,阴影部分跟着鼠标移动,并进行边界值判断,大图位置也对应等比例移动。
1、HTML结构

<!-- 外层盒子,位置为400*500大小 -->
<div id="outer">
	<div id="midArea">
		<!-- 中图 -->
		<img src="img/m01.jpg" >
		<!-- 放大镜 -->
		<div id="zoom"></div>
	</div>
		
	<div id="bigArea">
		<img src="img/m01.jpg" >
	</div>
		
	<ul id="smallArea">
		<li><img src="img/m01.jpg" ></li>
		<li><img src="img/m02.jpg" ></li>
		<li><img src="img/m03.jpg" ></li>
	</ul>
</div>

2、CSS样式

<style type="text/css">
	div,ul,li{margin: 0;padding: 0;}
	img{display: block;}
	ul,li{list-style: none;}
	#outer{width: 400px;height: 500px;border: 1px solid #CECECE;
		position: relative;}
			
	/* 设置中等视图,宽高400 relative定位*/
	#midArea{width: 400px;height: 400px;position: relative;
		overflow: hidden;cursor: move;
		border-bottom: 1px solid #CECECE;}
	#midArea img{width: 400px;height: 400px;}
	#midArea #zoom{position: absolute;top: 0;left: 0;
		width: 200px;height: 200px;background: yellow;opacity: .3;
		display: none;}
			
	/* 设置大区域,宽高400,图片宽高800 */
	#bigArea{width: 400px;height: 400px;
		position: absolute;top: -1px;left: 400px;
		overflow: hidden;display: none;
		border: 1px solid #CECECE;}
	#bigArea img{width: 800px;height: 800px;position: absolute;}
			
	/* 设置小图区域 */
	#smallArea li{width: 80px;height: 80px;float: left;margin: 9px;}
	#smallArea li img{width: 80px;height: 80px;}
</style>

3、JS代码
HTML页面

<!-- 引入zoom.js代码 -->
<script src="zoom.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
	// 创建一个Zoom实例的对象
	let zoom = new Zoom();
</script>

zoom.js文件

function $(id){
	return document.getElementById(id);
}

function Zoom(){
	this.outer = $("outer");
	this.midArea = $("midArea");
	this.midImg = this.midArea.children[0];
	this.zoom = $("zoom");
	this.bigArea = $("bigArea");
	this.bigImg = this.bigArea.children[0];
	this.smallArea = $("smallArea");
	this.smallImgs = this.smallArea.querySelectorAll("img");
	
	// 鼠标移入中图时,阴影zoom和大图区域显示
	this.midArea.onmouseover = ()=>{
		this.zoom.style.display = "block";
		this.bigArea.style.display = "block";
	}
	// 鼠标移出时,阴影zoom和大图区域隐藏
	this.midArea.onmouseout = ()=>{
		this.zoom.style.display = "none";
		this.bigArea.style.display = "none";
	}
	
	this.midArea.onmousemove = (e)=>{
		var evt = e || event;
		
		// clientWidth为不带边框的宽,offsetWidth为带边框的宽
		var maxLeft = this.midArea.clientWidth - this.zoom.offsetWidth;
		var maxTop = this.midArea.clientHeight - this.zoom.offsetHeight;
		
		// 阴影部分随着鼠标的移动而移动
		// evt.pageX为鼠标到页面的左边距距离
		// this.outer.offsetLeft为outer盒子到页面左边距距离
		// this.zoom.offsetWidth/2 为盒子宽度的一半
		_left = evt.pageX - this.outer.offsetLeft - this.zoom.offsetWidth/2;
		_top = evt.pageY - this.outer.offsetTop - this.zoom.offsetHeight/2;
		
		// 临界值判断
		_left = _left <= 0 ? 0 : _left >= maxLeft ? maxLeft : _left;
		_top = _top <= 0 ? 0 : _top >= maxTop ? maxTop : _top;
		
		// 设置阴影区域跟随鼠标移动
		this.zoom.style.left = _left + "px";
		this.zoom.style.top = _top + "px";
		
		// 设置大图等比例显示
		// 阴影部分越向左上,大图图片越向左下
		this.bigImg.style.left = -this.zoom.offsetLeft/this.midArea.offsetWidth*this.bigImg.offsetWidth + "px";
		this.bigImg.style.top = -this.zoom.offsetTop/this.midArea.offsetHeight*this.bigImg.offsetHeight + "px";
	}
	
	// 给小图添加点击事件,中图和大图都切换该小图的图片路径
	for(let i=0 ; i<this.smallImgs.length ; i++){
		// for循环遍历,给所有的小图都添加点击事件
		this.smallImgs[i].onclick = ()=>{
			this.midImg.src = this.smallImgs[i].src;
			this.bigImg.src = this.smallImgs[i].src;
		}
	}
}

瀑布流

  主要思想:设置外部box为relative,里面内部div为absolute,设置每个内部div的left值和top。设置的规则为:先根据box的宽和内部div的宽,判断能显示多少列;前列数个div先设置,top为0,left为对应宽度*i的值;之后的按个依次设置,设置到高度最小的列下面,再更新列高度的数组。
1、HTML结构

<div id="box">
	<div><img src="img2/1.jpg" ></div>
	<div><img src="img2/2.jpg" ></div>
	<div><img src="img2/3.jpg" ></div>
	<div><img src="img2/4.jpg" ></div>
	<div><img src="img2/5.jpg" ></div>
	<div><img src="img2/6.jpg" ></div>
	<div><img src="img2/7.jpg" ></div>
	<div><img src="img2/8.jpg" ></div>
	<div><img src="img2/9.jpg" ></div>	
</div>

2、CSS样式

<style type="text/css">
	img{display: block;}
	#box{position: relative;}
	#box div{position: absolute;width: 300px;border: 1px solid #CECECE;}
	#box img{width: 300px;}
</style>

3、JS代码
HTML页面

<!-- 引入waterFall.js代码 -->
<script src="waterFall.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
	// 加载所有图片资源之后,避免图片还没有加载,获取宽高不准确
	window.onresize = window.onload = function(){
		let waterFall = new WaterFall();
	}
</script>

waterFall.js文件

function WaterFall(){
	// 得到box
	this.box = document.getElementById("box");
	// 得到box下的img
	this.items = this.box.children;
	// 左右间隔和上下间隔
	this.ml = this.mt = 10;
	
	// 数组,存放每一列的高度
	this.arrHei = [];
	
	// 初始化,把每一列的第一个先排列开
	this.init = function(){
		
		// 得到总宽度
		let totalWidth = this.box.offsetWidth;
		// 得到item的宽度(统一的),直接取第一个。再加上左右的间隔
		let perWidth = this.items[0].offsetWidth + this.ml;
		
		// 由总宽度和每个item的宽度,得到列数cols
		this.cols = Math.floor(totalWidth/perWidth);
		
		for(let i=0 ; i<this.cols ; i++){
			// 每列的第一个top值为0,在最顶上
			this.items[i].style.top = 0;
			this.items[i].style.left = perWidth*i + "px";
			this.arrHei.push(this.items[i].offsetHeight);
		}
	}
	
	// 调用初始化函数
	this.init();
	this.conPos(this.cols);
	this.appendItems();
}

// arrHei数组,得到最小值,最小索引
WaterFall.prototype.minSort = function(){
	this.minVal = Math.min.apply(null,this.arrHei);
	this.minIndex = this.arrHei.indexOf(this.minVal);
	return [this.minVal,this.minIndex];
}

// 从索引为numIndex时的图片,直到最后,依次设置left,top值
WaterFall.prototype.conPos = function(numIndex){
	// 从索引为numIndex循环到所有的items
	for(let i=numIndex ; i<this.items.length ; i++){
		
		// 新设置图片left为 高度最小的left,即放到每次高度最小的一列
		this.items[i].style.left = this.items[this.minSort()[1]].style.left;
		// 新设置的图片top为 高度最小那一列的高度+高度间隔
		this.items[i].style.top = this.minSort()[0] + this.mt + "px";
		// 替换高度最小的数组值,加上新增的图片高度和距离上方的间隔值
		this.arrHei[this.minSort()[1]] += this.mt + this.items[i].offsetHeight;
	}
}

// 如果滚动条的高度,滚动到最小那一列的高度值减去可视区域的高度时,加载更多
WaterFall.prototype.appendItems = function(){
	let data = ["img2/1.jpg","img2/2.jpg","img2/3.jpg"];
	// 得到HTML的可视区域高度
	let ch = document.documentElement.clientHeight;
	// 监听window的滚动条滚动事件
	window.onscroll = ()=>{
		// 得到滚动条的高度
		let st = document.documentElement.scrollTop || document.body.scrollTop;
		// 得到所有列中最小的高度值
		
		// let minHei = this.arrHei[this.minIndex];
		let minHei = this.minSort()[0];
		console.log(minHei);
		if( st >= minHei - ch ){
			// 加载新的数据
			for(let i=0 ; i<data.length ; i++){
				let oDiv = document.createElement("div");
				oDiv.innerHTML = `<img src="${data[i]}" >`;
				this.box.appendChild(oDiv);
			}
			// 把重新加载的图片再进行定位
			this.conPos(this.items.length - data.length);
			
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值