javascript实现商品图片放大镜


Posted in Javascript onNovember 28, 2019

优化原因

现在的电商商城项目解决的主要是购买商品的问题,那么购买商品主要要看清楚商品表面外形的主要特征和细节,如果图片处理过小,或者细节过于模糊,就需要做一个商品高清图片放大局部的功能。

技术关键点

1.左侧和上侧距离,在一个水平位置和垂直位置中有我们可以挪动的区域,就是原图片区域,鼠标挪动位置是一个块状位置,他的左侧和上侧距离浏览器上侧和左侧分别有一个长度,我们叫它们 ClientX 和 ClientY,而左上侧鼠标没有略过的位置实际上是一个点,我们拖动放大块时,它会由一个点变成一个方块,这个放大镜左上边的点所控制的这一点距离屏幕上侧和左侧的 ClientY 和 ClientX 会随着鼠标的移动而变大变小,那么要计算放大块左侧距离原点和上侧原点就要减去原图距离屏幕的上边高度和左边高度。在一个水平位置和垂直位置中有我们可以挪动的区域,就是原图片区域,鼠标挪动位置是一个块状位置,他的左侧和上侧距离浏览器上侧和左侧分别有一个长度,我们叫它们 ClientX 和 ClientY,而左上侧鼠标没有略过的位置实际上是一个点,我们拖动放大块时,它会由一个点变成一个方块,这个放大镜左上边的点所控制的这一点距离屏幕上侧和左侧的 ClientY 和 ClientX 会随着鼠标的移动而变大变小,那么要计算放大块左侧距离原点和上侧原点就要减去原图距离屏幕的上边高度和左边高度。

计算方式

x = 事件对象.clientX - 外侧盒子.offsetLeft;
Y = 事件对象.clientY - 外侧盒子.offsetTop;

javascript实现商品图片放大镜

javascript实现商品图片放大镜

2.解决如何鼠标在黄块内居中的问题,横纵位移分别加上放大黄块一半的长度和宽度。

计算方式

x = 事件对象.clientX - 外侧盒子.offsetLeft - 小黄.offsetWidth/2;
Y = 事件对象.clientY - 外侧盒子.offsetTop - 小黄.offsetHeight/2;
// 事件对象的 offsetX 和 offsetY
// 归属于事件对象
// 作用:关注的鼠标的坐标(鼠标相对于当前元素的坐标)
// 元素的 offsetLeft 和 offsetTop
// 归属于元素
// 作用:关注的元素的坐标(相对于offsetParent的坐标)

javascript实现商品图片放大镜

3. 小黄块的最大距离

javascript实现商品图片放大镜

4.用preventDefault阻止事件冒泡

简易实现代码

<!DOCTYPE html>
<html>
<head lang="en">
 <meta charset="UTF-8">
 <title></title>
 <link rel="stylesheet" href="base.css" rel="external nofollow" />
</head>
<body>
 <div class="w">
 <div class="fdj">
 <!-- 左侧 -->
 <div class="leftBox" id="_leftBox">
 <!-- 小图 -->
 <img src="img/m.jpg" alt=""/>
 <!-- 小黄盒子 -->
 <div class="tool" id="_tool"></div>
 </div>
 <!-- 右侧 -->
 <div class="rightBox" id="_rightBox">
 <img id="_bImg" src="img/b.jpg" alt=""/>
 </div>
 </div>
 </div>
 <!-- 引入的外部js程序文件 -->
 <script src="index.js"></script>
</body>
</html>
* {
 margin:0;
 padding:0;
}

.w {
 width: 1190px;
 margin: 0 auto;

}
.fdj {
 margin-top: 20px;
}

.fdj .leftBox {
 width: 400px;
 height: 400px;
 border: 1px solid #ccc;
 float: left;
 position: relative;
 overflow: hidden;
}

.fdj .tool {
 width: 250px;
 height: 250px;
 background:gold;
 opacity:.5;
 filter:alpha(opacity=50);
 position: absolute;
 top:0;
 left: 0;
 cursor: move;
 /* 默认隐藏 */
 display: none;

}
/* 给小黄加上active 就会显示 */
.fdj .tool.active {
 display: block;
}

.fdj .rightBox {
 width: 500px;
 height: 500px;
 border:1px solid #ccc;
 float: left;
 overflow: hidden;
 /* 隐藏 */
 display: none;
 position: relative;
}
/* 加上active表示显示 */
.fdj .rightBox.active {
 display: block;
}

.fdj .rightBox img {
 position: absolute;
}
//【准备:获取要操作的元素】
var _leftBox = document.querySelector('#_leftBox'); // 左侧盒子
var _tool = document.querySelector('#_tool'); // 小黄盒子
var _rightBox = document.querySelector('#_rightBox'); // 右侧盒子
var _bImg = document.querySelector('#_bImg'); // 右侧盒子中的大图片


//【功能1:鼠标进入/离开左侧盒子显示/隐藏小黄和右侧盒子】
// 1. 给_leftBox注册鼠标进入事件 onmouseenter
_leftBox.onmouseenter = function () {
 // 1.1 显示小黄盒子,给小黄盒子添加类名 active
 _tool.className = 'tool active';
 // 1.2 显示右侧盒子,给右侧盒子添加类名 active 
 _rightBox.className = 'rightBox active';

}

// 2. 给_leftBox注册鼠标离开事件 onmouseleave
_leftBox.onmouseleave = function () {
 // 2.1 显示小黄盒子,给小黄盒子去除类名 active
 _tool.className = 'tool';
 // 2.2 显示右侧盒子,给右侧盒子去除类名 active
 _rightBox.className = 'rightBox';
}

//【功能2:鼠标在左侧区域移动时,控制小黄和右侧盒子中图片的位置】
// 1. 给左侧盒子注册鼠标移动事件 onmosuemove
_leftBox.onmousemove = function (e) {
 // 2. 通过事件对象获取鼠标相对元素的位置(x,y)
 var x = e.clientX - _leftBox.offsetLeft- _tool.offsetWidth/2;
 var y = e.clientY - _leftBox.offsetTop - _tool.offsetHeight/2;

 // 这里给x和y赋值时,不要用事件对象的offsetX和offsetY。
 // 原因:因为【事件冒泡】,鼠标在移动时,有时会移动到小黄盒子上。若移动到小黄盒子上时,获取的值不是相对于左侧盒子元素,而是相对小黄盒子元素。所以当鼠标进入或离开小黄时,获取的坐标值时大时小,导致小黄盒子上下左右波动。
 // 解决方案:在小黄移动事件中,停止冒泡。但是鼠标在移动时,就没有效果了。
 // 最终解决方案:放弃使用事件对象offsetX/Y。 选择事件对象的clienX/Y 结合左侧盒子的位置计算出正确的位置。

 // 2.1 对x和y限制
 if (x < 0) {
 x = 0;
 }
 if (y < 0) {
 y = 0;
 }
 if (x > _leftBox.offsetWidth - _tool.offsetWidth) {
 x = _leftBox.offsetWidth - _tool.offsetWidth;
 }
 if (y > _leftBox.offsetHeight - _tool.offsetHeight) {
 y = _leftBox.offsetHeight - _tool.offsetHeight;
 }

 // 3. 把计算好的位置 赋值给小黄 
 _tool.style.left = x + 'px';
 _tool.style.top = y + 'px';

 // 4. 设定右侧大图片的位置(设置的方向是相反的,比例关系是1:2)
 _bImg.style.left = -2 * x + 'px';
 _bImg.style.top = -2 * y + 'px';
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
自适应高度框架 ----属个人收藏内容
Jan 22 Javascript
jQuery选择没有colspan属性的td的代码
Jul 06 Javascript
Js nodeType 属性全面解析
Nov 14 Javascript
jQuery实现动画效果的简单实例
Jan 27 Javascript
js获取指定的cookie的具体实现
Feb 20 Javascript
Bootstrap网格系统详解
Apr 26 Javascript
jQuery实现定位滚动条位置
Aug 05 Javascript
BOM系列第二篇之定时器requestAnimationFrame
Aug 17 Javascript
ThinkJS中如何使用MongoDB的CURD操作
Dec 13 Javascript
微信小程序云开发实现增删改查功能
May 17 Javascript
ECharts地图绘制和钻取简易接口详解
Jul 12 Javascript
JavaScript实现旋转木马轮播图
Mar 16 Javascript
javascript实现视频弹幕效果(两个版本)
Nov 28 #Javascript
javascript实现弹幕墙效果
Nov 28 #Javascript
jquery实现直播弹幕效果
Nov 28 #jQuery
jQuery实现简单弹幕效果
Nov 28 #jQuery
微信小程序事件流原理解析
Nov 27 #Javascript
JS实现简单省市二级联动
Nov 27 #Javascript
Angular value与ngValue区别详解
Nov 27 #Javascript
You might like
落伍首发 php+mysql 采用ajax技术的 省 市 地 3级联动无刷新菜单 源码
2006/12/16 PHP
PHP编程之设置apache虚拟目录
2016/07/08 PHP
利用php_imagick实现复古效果的方法
2016/10/18 PHP
PHP SESSION跨页面传递失败解决方案
2020/12/11 PHP
Tinymce+jQuery.Validation使用产生的BUG
2010/03/29 Javascript
在JavaScript并非所有的一切都是对象
2013/04/11 Javascript
jquery批量设置属性readonly和disabled的方法
2014/01/24 Javascript
jquery制作漂亮的弹出层提示消息特效
2014/12/23 Javascript
JS实用的动画弹出层效果实例
2015/05/05 Javascript
微信小程序 for 循环详解
2016/10/09 Javascript
JavaScript、C# URL编码、解码总结
2017/01/21 Javascript
浅谈js中同名函数和同名变量的执行问题
2017/02/12 Javascript
简单实现js点击展开二级菜单功能
2017/05/16 Javascript
Javascript 实现匿名递归的实例代码
2017/05/25 Javascript
JS按条件 serialize() 对应标签的使用方法
2017/07/24 Javascript
VUE实现一个分页组件的示例
2017/09/13 Javascript
Angular4.x Event (DOM事件和自定义事件详解)
2018/10/09 Javascript
vue中filters 传入两个参数 / 使用两个filters的实现方法
2019/07/15 Javascript
vue print.js打印支持Echarts图表操作
2020/11/13 Javascript
SpringBoot+Vue 前后端合并部署的配置方法
2020/12/30 Vue.js
python访问类中docstring注释的实现方法
2015/05/04 Python
Python实现将xml导入至excel
2015/11/20 Python
Python 实现链表实例代码
2017/04/07 Python
python中yaml配置文件模块的使用详解
2018/04/27 Python
Python使用POP3和SMTP协议收发邮件的示例代码
2019/04/16 Python
python通过文本在一个图中画多条线的实例
2020/02/21 Python
Python如何定义有可选参数的元类
2020/07/31 Python
波兰家具和室内装饰品购物网站:Vivre
2018/04/10 全球购物
蒙蒂塞罗商店:Monticello Shop
2018/11/25 全球购物
定义一结构体变量,用其表示点坐标,并输入两点坐标,求两点之间的距离
2015/08/17 面试题
信号量和自旋锁的区别?如何选择使用?
2015/09/08 面试题
毕业生的自我鉴定该怎么写
2013/12/02 职场文书
职工擅自离岗检讨书
2014/09/23 职场文书
团员个人年度总结
2015/02/26 职场文书
Python Pandas模块实现数据的统计分析的方法
2021/06/24 Python
详解在SQLPlus中实现上下键翻查历史命令的功能
2022/03/18 SQL Server