html部分
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1,minimum-scale=1, user-scalable=no" />
<title>js手风琴</title>
<link rel="shortcut icon" href="./img/logo.png" type="image/x-icon" />
<link rel="stylesheet" href="./css/index.css" />
</head>
<body>
<div id="app">
<div><img src="./img/image1.jpg" alt="" /></div>
<div>
<img src="./img/image2.jpg" alt="" />
<div class="text">
<p>some text here</p>
</div>
</div>
<div><img src="./img/image3.jpg" alt="" /></div>
<div><img src="./img/image4.jpg" alt="" /></div>
<div><img src="./img/image5.jpg" alt="" /></div>
<div>
<img src="./img/image6.jpg" alt="" />
<div class="text">
<h1>this is a big title</h1>
<p>Laborum anim quis non sint qui. Non deserunt laboris nulla proident tempor in occaecat. Excepteur proident ex veniam labore. Magna dolor sunt pariatur nisi nulla. Est pariatur amet cillum sint nostrud. Proident mollit occaecat exercitation minim nisi labore ullamco nulla mollit pariatur. Commodo aute est culpa pariatur velit tempor enim ipsum deserunt id non tempor.</p>
</div>
</div>
<div><img src="./img/image7.jpg" alt="" /></div>
<div><img src="./img/image8.jpg" alt="" /></div>
<div><img src="./img/image9.jpg" alt="" /></div>
<div><img src="./img/image10.jpg" alt="" /></div>
<div><img src="./img/image11.jpg" alt="" /></div>
<div><img src="./img/image12.jpg" alt="" /></div>
<div><img src="./img/image13.jpg" alt="" /></div>
<div><img src="./img/image14.jpg" alt="" /></div>
<div><img src="./img/image15.jpg" alt="" /></div>
<div><img src="./img/image16.jpg" alt="" /></div>
<div><img src="./img/image17.jpg" alt="" /></div>
<div><img src="./img/image18.jpg" alt="" /></div>
<div><img src="./img/image19.jpg" alt="" /></div>
<div><img src="./img/image20.jpg" alt="" /></div>
</div>
<script src="./js/index.js"></script>
<script>
let { active } = new Gellary('app', { width: 5, height: 4 })
</script>
</body>
</html>
CSS部分
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
#app {
overflow: hidden;
width: 500px;
}
/* 使用浮动实现对元素的布局 */
.gellary > div {
float: left;
width: 100px;
height: 100px;
overflow: hidden;
border-right: 1px solid #ddd;
border-bottom: 1px solid #ddd;
position: relative;
transition: all 0.3s;
}
.gellary > div:hover {
cursor: pointer;
}
/* 设置div中的图片垂直水平居中 */
#app > div > img {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
/* 设置div中的文本隐藏状态 */
#app > div > .text {
position: absolute;
bottom: 0;
left: 0;
width: 340px;
transform: translateY(100%);
z-index: 1;
background-color: rgba(255, 255, 255, 0.8);
opacity: 0;
transition: all 0.3s;
}
/* 激活状态的文本的样式 */
#app > div.active > .text {
/* 从隐藏的状态,转换为显示状态 */
transform: translateY(0%);
opacity: 1;
js部分
function Gellary(id, option) {
//找到容器
let container = document.getElementById(id)
let ct = container.children
//设置类样式
if (container.className.indexOf('gellary') === -1) {
container.className += ' gellary'
}
//判断矩阵的个数和元素的个数是否相等
let flag = option.width && option.height && option.width * option.height !== ct.length
if (flag) {
throw 'width and height does not match children length'
}
//准备参数
let defaulteOption = {
defaultWidth: 130,
defaultHeight: 40,
activeHeight: 400,
activeWidth: 340,
animateDuration: 300,
}
//合并参数给option
option = Object.assign({}, defaulteOption, option)
//动态设置容器的宽度
container.style.width = (option.width - 1) * option.defaultWidth + option.activeWidth + 'px'
//声明时间的起点
let lastRuntime = new Date(0)
let runId = 0
//声明激活图片的函数
let activePicture = function (index) {
/**
* 此处控制激活图片的动作是在transition过渡结束后开始执行
* 避免出现,图片卡顿现象
*/
if (runId) {
clearTimeout(runId)
}
let currentTime = new Date()
if (currentTime - lastRuntime < option.animateDuration) {
runId = setTimeout(function () {
activePicture(index)
}, option.animateDuration)
return
}
lastRuntime = currentTime
//转换当前激活的元素的下标为坐标
let cx = index % option.width
let cy = Math.floor(index / option.width)
console.log(cx, cy)
//遍历所有的坐标(x,y),把坐标转换成下标index
for (let x = 0, xl = option.width; x < xl; x++) {
for (let y = 0, yl = option.height; y < yl; y++) {
//把坐标转换成下标
let cindex = y * option.width + x
//遍历所有元素
let item = ct[cindex]
if (cx === x && cy === y) {
item.className = 'active'
item.style.width = option.activeWidth + 'px'
item.style.height = option.activeHeight + 'px'
} else if (cx === x) {
item.className = ''
//和当前激活元素在同列的其它元素的样式
item.style.width = option.activeWidth + 'px'
item.style.height = option.defaultHeight + 'px'
} else if (cy === y) {
item.className = ''
//和当前激活元素在同行的其它元素的样式
item.style.width = option.defaultWidth + 'px'
item.style.height = option.activeHeight + 'px'
} else {
item.className = ''
item.style.width = option.defaultWidth + 'px'
item.style.height = option.defaultHeight + 'px'
}
}
}
}
//初始化第一张图片激活
activePicture(0)
//给每个div绑定事件
for (let i = 0; i < ct.length; i++) {
ct[i].addEventListener('mouseenter', function () {
activePicture(i)
})
}
// Array.prototype.forEach.call(ct, function (item, index) {
// item.addEventListener('mouseenter', function () {
// activePicture(index)
// })
// })
return { active: activePicture }