案例素材可到这里领取, __提取码:ephx __
1. 商品展示案例
通过导航条滑动可不断看到后面的商品列表
- 主要难点在于导航条长度与导航条左边距离的理算,类似于之前的等比缩放,详情可参考注释里面的笔记推算
- 这里涉及几个鼠标事件,onmousedown、onmousemove以及onmouseup,方法中的return false格外需要注意, 如果没有的话在导航条移动过程中就会在两个鼠标事件中产生冲突
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
*{
margin: 0;
padding: 0;
list-style: none;
border:none;
}
#box{
width: 800px;
height: 200px;
border: 1px solid #ddd;
position: relative;
margin: 100px auto;
overflow: hidden;
}
#box ul{
width: 2600px;
position: absolute;
left: 0;
top: 20px;
}
#box ul li{
float: left;
}
#box_bottom{
position: absolute;
left: 0;
bottom: 0;
background-color: #e8e8e8;
width: 100%;
height: 25px;
}
.mask{
position: absolute;
left: 0;
top:0;
height: 25px;
background-color: orangered;
border-radius: 12px;
cursor: pointer;
}
</style>
</head>
<body>
<div id="box">
<ul id="box_top">
<li><img src="images/img1.jpg" alt=""></li>
<li><img src="images/img2.jpg" alt=""></li>
<li><img src="images/img3.jpg" alt=""></li>
<li><img src="images/img4.jpg" alt=""></li>
<li><img src="images/img5.jpg" alt=""></li>
<li><img src="images/img6.jpg" alt=""></li>
<li><img src="images/img7.jpg" alt=""></li>
<li><img src="images/img8.jpg" alt=""></li>
<li><img src="images/img1.jpg" alt=""></li>
<li><img src="images/img2.jpg" alt=""></li>
<li><img src="images/img1.jpg" alt=""></li>
<li><img src="images/img2.jpg" alt=""></li>
<li><img src="images/img3.jpg" alt=""></li>
<li><img src="images/img4.jpg" alt=""></li>
<li><img src="images/img5.jpg" alt=""></li>
<li><img src="images/img6.jpg" alt=""></li>
<li><img src="images/img7.jpg" alt=""></li>
<li><img src="images/img8.jpg" alt=""></li>
<li><img src="images/img1.jpg" alt=""></li>
<li><img src="images/img2.jpg" alt=""></li>
</ul>
<div id="box_bottom">
<span class="mask"></span>
</div>
</div>
<script>
window.onload = function () {
// 1. 获取需要的标签
var box = document.getElementById("box");
var box_top = document.getElementById("box_top");
var box_bottom = document.getElementById("box_bottom");
var mask = box_bottom.children[0];
// 2. 设置滚动条的长度
// 滚动条长度 = ( 盒子的宽度 / 内容的宽度) * 盒子的宽度
var mask_len = (box.offsetWidth / box_top.offsetWidth) * box.offsetWidth;
mask.style.width = mask_len + 'px';
// 3. 鼠标操作
mask.onmousedown = function (event) {
var e = event || window.event;
// 3.1 求出初始值
var beginX = e.clientX - mask.offsetLeft;
// 3.2 移动
document.onmousemove = function (event) {
var e = event || window.event;
// 3.3 求出移动的距离
var endX = event.clientX - beginX;
// 边界值
if(endX < 0){
endX = 0;
}else if(endX >= box.offsetWidth - mask.offsetWidth){
endX = box.offsetWidth - mask.offsetWidth;
}
// 3.4 动起来
mask.style.left = endX + 'px';
// 内容走的距离 = (内容的长度 - 盒子的长度) \/ (盒子长度 - 滚动条的长度) * 滚动条走的距离
var content_len = (box_top.offsetWidth - box.offsetWidth) / (box.offsetWidth - mask.offsetWidth) * endX;
box_top.style.left = -content_len + 'px';
return false;
};
document.onmouseup = function () {
document.onmousemove = null;
}
}
}
</script>
</body>
</html>
2. 瀑布流图片布局案例
按照瀑布流对图片进行布局展示,往下移动会自动生成图片持续展示
- 难点在于对于图片大小以及屏幕宽度的把握
- 对于每一排的图片,要计算出高度最低的盒子将下一排第一个盒子插入此处,并对最低高度进行更新,其他的按照这种模式循环处理
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>瀑布流布局</title>
<link rel="stylesheet" href="css/index.css">
</head>
<body>
<div id="main">
<div class="box"><div class="pic"><img src="images/img01.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img02.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img03.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img04.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img05.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img06.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img07.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img08.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img09.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img10.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img11.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img12.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img13.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img14.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img15.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img16.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img17.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img18.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img19.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img20.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img21.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img22.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img23.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img24.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img25.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img26.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img27.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img28.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img29.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img30.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img31.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img32.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img33.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img34.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img35.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img36.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img37.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img38.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img39.jpg" alt=""></div></div>
<div class="box"><div class="pic"><img src="images/img40.jpg" alt=""></div></div>
</div>
<script src="js/Underscore-min.js"></script>
<script src="js/myFunc.js"></script>
<script src="js/index.js"></script>
</body>
</html>
index.js:
window.onload = function () {
// 1. 实现瀑布流布局
waterFull("main", "box");
// 2. 动态加载图片
window.onscroll = function () {
if(checkWillLoadImage()){
// 2.1 造数据
var dataArr = [
{"src": "img04.jpg"},
{"src": "img06.jpg"},
{"src": "img08.jpg"},
{"src": "img09.jpg"},
{"src": "img10.jpg"},
{"src": "img12.jpg"},
{"src": "img14.jpg"},
{"src": "img16.jpg"},
{"src": "img18.jpg"}
];
// 2.2 创建元素
for(var i=0; i<dataArr.length; i++){
var newBox = document.createElement("div");
newBox.className = "box";
$("main").appendChild(newBox);
var newPic = document.createElement("div");
newPic.className = "pic";
newBox.appendChild(newPic);
var newImg = document.createElement("img");
newImg.src = "images/" + dataArr[i].src;
newPic.appendChild(newImg);
}
// 2.3 重新布局
waterFull("main", "box");
}
}
};
/**
* 实现瀑布流布局
*/
function waterFull(parent, child) {
// 1. 父盒子居中
var allBox = $(parent).getElementsByClassName(child);// 1.1 获取所有的盒子
// 1.2 获取子盒子的宽度
var boxWidth = allBox[0].offsetWidth;
// 1.3 获取屏幕的宽度
var screenW = document.documentElement.clientWidth;
// 1.4 求出列数
var cols = parseInt(screenW / boxWidth);
// 1.5 父盒子居中
$(parent).style.width = cols * boxWidth + 'px';
$(parent).style.margin = "0 auto";
// 2. 子盒子的定位
// 2.1 定义高度数组
var heightArr = [], boxHeight = 0, minBoxHeight = 0, minBoxIndex = 0;
// 2.2 遍历子盒子
for (var i = 0; i < allBox.length; i++) {
// 2.2.1 求出每一个子盒子的高度
boxHeight = allBox[i].offsetHeight;
// 2.2.2 取出第一行盒子的高度放入高度数组
if (i < cols) { // 第一行
heightArr.push(boxHeight);
} else { // 剩余行
// 1. 取出最矮的盒子高度
minBoxHeight = _.min(heightArr);
// 2. 求出最矮盒子对应的索引
minBoxIndex = getMinBoxIndex(heightArr, minBoxHeight);
// 3. 子盒子定位
allBox[i].style.position = "absolute";
allBox[i].style.left = minBoxIndex * boxWidth + 'px';
allBox[i].style.top = minBoxHeight + 'px';
// 4. 更新数组中的高度
heightArr[minBoxIndex] += boxHeight;
}
}
console.log(heightArr, minBoxHeight, minBoxIndex);
}
/**
* 获取数组中最矮盒子高度的索引
* @param arr
* @param val
* @returns {number}
*/
function getMinBoxIndex(arr, val) {
for(var i=0; i<arr.length; i++){
if(arr[i] === val){
return i;
}
}
}
function $(id) {
return typeof id === "string" ? document.getElementById(id) : null;
}
/**
* 判断是否具备加载图片的条件
*/
function checkWillLoadImage() {
// 1. 获取最后一个盒子
var allBox = document.getElementsByClassName("box");
var lastBox = allBox[allBox.length - 1];
// 2. 求出最后一个盒子自身高度的一半 + offsetTop
var lastBoxDis = lastBox.offsetHeight * 0.5 + lastBox.offsetTop;
// 3. 求出屏幕的高度
var screenW = document.body.clientHeight || document.documentElement.clientHeight;
// 4. 求出页面偏离浏览器的高度
var scrollTop = scroll().top;
return lastBoxDis <= screenW + scrollTop;
}
myFunc.js里面是对scroll方法的封装,详情可参考上一节:
/**
* 获取滚动的头部距离和左边距离
* scroll().top scroll().left
* @returns {*}
*/
function scroll() {
if(window.pageYOffset !== null){
return {
top: window.pageYOffset,
left: window.pageXOffset
}
}else if(document.compatMode === "CSS1Compat"){ // W3C
return {
top: document.documentElement.scrollTop,
left: document.documentElement.scrollLeft
}
}
return {
top: document.body.scrollTop,
left: document.body.scrollLeft
}
}
参考:
网易云js课程
网友评论