综合案例
程序员文章站
2022-07-04 16:26:25
...
星星评分
主要思想:鼠标移到某个小星星上,该小星星及它左边的小星星被点亮;如果没有星星被点击,鼠标移出时,所有的小星星变灰,如果有星星被点亮,移出时,点击的小星星及它左边的小星星被点亮;鼠标点击某个小星星时,确定索引值及改变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);
}
}
}