写在开头
上期代码主要实现视频网站中顶部推荐模块,本期就来实现PC端电商平台商品详情页图片放大镜效果开发久了很多功能都是通过框架组件库来完成,但是如果组件满足不了开发需求,还需要开发人员手动封装组件,专门出这样一期文章,通过原生js实现一些特定功能,功能也比较简单,也是想借助这样一个简单的功能,然后来帮助大家了解我们JavaScript,在前端中的作用,另外也培养下我们的代码思维,那我们本次就通过由简单到复杂循序渐进,这份专栏中我们会带领大家用前端实现积分抽奖、拼图、无缝轮播图、图片瀑布流、读心术小游戏等等有趣的小功能,纯前端语言实现,都会陆续带给大家。
实现效果
PC端电商平台商品图片放大镜效果,参考京东商品图片放大镜效果
页面创建
javascript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./index.css">
</head>
<body>
<!--最外层容器 -->
<div class="container">
<!-- 左侧原图 -->
<div class="left-img">
<!-- 遮罩层 -->
<div class="mask"></div>
</div>
<!-- 右侧放大图片 -->
<div class="right-img"></div>
<!-- 缩略图集合 -->
<div class="img-list-wrapper">
<ul class="img-list">
</ul>
</div>
</div>
<script src="./index.js"></script>
</body>
</html>
样式搭建
javascript
* {
margin: 0;
padding: 0;
list-style: none;
}
.container {
width: 1000px;
height: 600px;
margin: 50px auto;
font-size: 0;
}
.left-img {
width: 490px;
height: 510px;
margin-right: 16px;
border: 1px solid #eee;
display: inline-block;
/* 图片 */
background-image: url(./images/imgA_2.jpg);
background-repeat: no-repeat;
background-position: center;
background-size: cover;
/* 遮罩层相对我进行定位 */
position: relative;
}
.mask {
width: 230px;
height: 230px;
background-image: url(./images/bg.png);
position: absolute;
top: 0;
left: 0;
opacity: 0;
}
.right-img {
width: 490px;
height: 510px;
border: 1px solid #eee;
display: inline-block;
background-image: url(./images/imgA_3.jpg);
background-repeat: no-repeat;
opacity: 0;
}
.img-list-wrapper {
width: 490px;
text-align: center;
margin-top: 10px;
}
.img-list {
display: inline-block;
}
.img-list li {
display: inline-block;
width: 60px;
height: 60px;
margin: 0 5px;
cursor: pointer;
/* background-image: url(./images/imgA_1.jpg); */
background-repeat: no-repeat;
/* border: 2px solid #000; */
border: 1px solid #eee;
}
逻辑实现
javascript
// 封装一个获取DOM元素的方法
// 单一元素
function $(selector) {
return document.querySelector(selector);
}
// 多个元素
function $$(selector) {
return document.querySelectorAll(selector);
}
// 初始化数据图片
var imgs = {
// 小图
small: ['imgA_1.jpg', 'imgB_1.jpg', 'imgC_1.jpg'],
// 中图
middle: ['imgA_2.jpg', 'imgB_2.jpg', 'imgC_2.jpg'],
// 大图
large: ['imgA_3.jpg', 'imgB_3.jpg', 'imgC_3.jpg']
}
// 获取一些将要使用的dom元素
// document.getElementsByClassName('container')[0]
// document.querySelector('.container');
var container = $('.container');
var largeImg = $('.right-img');
var midImg = $('.left-img');
var smallImg = $('.img-list');
var mask = $('.mask');
// b. 绑定事件
// 两大类事件类型, 点击, 鼠标移入移出
// 1. 点击事件, 事件委托
smallImg.onclick = function (e) {
// 判断我点击的元素是li元素
if (e.target.tagName == 'LI') {
// 让所有li元素取消border
var lis = $$('li');
for (var i = 0; i < lis.length; i++) {
lis[i].style.border = 'none';
}
// 让选中的li元素添加border
e.target.style.border = '2px solid #000';
// 点击缩略图后,原图和大图也需要跟着变换,
// 点的是第几个元素, 获取元素索引
// [1,2,3].indexOf(3) == 2
var index = [].indexOf.call(lis, e.target);
midImg.style.backgroundImage = 'url(./images/' + imgs.middle[index] + ')';
largeImg.style.backgroundImage = 'url(./images/' + imgs.large[index] + ')';
}
}
// 函数封装,一键启动
// 函数本质:若干步骤的集合
// 初始化页面函数
function initPage() {
var str = '';
for (var i = 0; i < imgs.small.length; i++) {
str += '<li style="background-image: url(./images/' + imgs.small[i] + ');"></li>'
}
smallImg.innerHTML = str;
// 2. 默认选中第一个缩略图
$('.img-list li').style.border = '2px solid #000';
}
// 绑定事件
function bindEvent() {
midImg.onmousemove = function (e) {
// 让遮罩层和大图展示
mask.style.opacity = 1;
largeImg.style.opacity = 1;
// 根据鼠标位置计算遮罩层的位置
var left = e.clientX - midImg.offsetLeft - mask.offsetWidth / 2;
// 同理
var top = e.clientY - midImg.offsetTop - mask.offsetHeight / 2;
// 边界条件
if (left <= 0) {
left = 0;
}
if (top <= 0) {
top = 0;
}
if (left >= midImg.offsetWidth - mask.offsetWidth) {
left = midImg.offsetWidth - mask.offsetWidth
}
if (top >= midImg.offsetHeight - mask.offsetHeight) {
top = midImg.offsetHeight - mask.offsetHeight
}
// 根据top和left调整mask的位置
mask.style.left = left + 'px';
mask.style.top = top + 'px';
// 根据top 和 left,修改大图的位置,background-position-x
largeImg.style.backgroundPositionX = -left + 'px';
largeImg.style.backgroundPositionY = -top + 'px';
}
// 2. 移出
midImg.onmouseleave = function (e) {
// 让遮罩层和大图消失
mask.style.opacity = 0;
largeImg.style.opacity = 0;
}
}
// 一键启动,执行一个函数
function main() {
initPage();
bindEvent();
}
main();
结尾总结
页面样式画起来都很容易,就是封装函数难呀
总结:菜就多练!