手撸原生js放大镜效果

普及知识:放大镜特效涉及到的几个值
offsetWidth    获取元素的宽度
offsetHeight  获取元素的高度
offsetLeft父元素没有定位时,获取元素距离页面的左边距,父元素有定位时,获取元素距离父元素的左边距
offsetTop父元素没有定位时,获取元素距离页面的上边距,父元素有定位时,获取元素距离父元素的上边距
clientX  离视口左边的距离
clientY  离视口上边的距离
onmousemove  鼠标移动事件
onmouseover  鼠标划过事件

主要思路:

    1.点击缩略图,中图和大图一块切换
    2.鼠标移动到中图时显示大图,并显示放大镜阴影部分
    3.当在中图上移动时 阴影部分的放大镜跟着移动,大图也跟着移动
    4.鼠标从中图移除时,大图隐藏   阴影部分的放大镜也隐藏。
    5.处理边界值

* {
  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;
}
.img-list li.active{
  border: 1px solid #000;
}

 

//数据逻辑  界面逻辑 事件逻辑
// 单一元素
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']
}
var smallImge = $('.img-list');
var minddleImage = $('.left-img');
var bigImage = $('.right-img');
var mask = $('.mask');
function initSmall(){
  var html='';
  for(var i = 0;i<imgs.small.length;i++){
    html+='<li style="background-image:url(./images/'+imgs.small[i]+') "></li>';
  }
  smallImge.innerHTML=html;
  //默认选中第一个
  $('.img-list li').className = 'active';
}

function init(){
  initSmall();
  bindEvent();
}
var bindEvent = function(){
  //事件委托绑定事件 其原理是用事件的冒泡实现的
  //小图切换大图事件
  smallImge.addEventListener('click', smallImgeHandle);
  //放大镜事件
  //鼠标移动 和 鼠标 离开
  minddleImage.addEventListener('mousemove', mouseHandle);
  minddleImage.addEventListener('mouseleave',leaveHandle)
}
var smallImgeHandle = function(e){
  console.dir(e.target.tagName)
  if(e.target.tagName === 'LI'){
    //将之前选中的项的状态取消掉
    var selected = $('.img-list .active');
    if(selected){
      selected.className = '';
    }
    e.target.className = 'active';

    //切换中图和大图
    //先取到 目标元素在列表中的下标
    var lis = smallImge.querySelectorAll('li');
    var index = [].indexOf.call(lis,e.target);
    minddleImage.style.backgroundImage = 'url(./images/'+imgs.middle[index]+')';
    bigImage.style.backgroundImage = 'url(./images/'+imgs.large[index]+')';
  }
}
var mouseHandle = function(e){
  console.log(123);
  mask.style.opacity = 1;
  bigImage.style.opacity = 1;
  var cx = e.clientX;//鼠标点离视口的左边距离
  var cy = e.clientY;//鼠标点离视口的上边距离
  var mcx = minddleImage.offsetLeft;//中图的容器离视口的左边距离
  var mcy = minddleImage.offsetTop;//中图的容器离视口的上边距离
  var left = cx - mcx - mask.offsetWidth / 2; //mask离中图的容器的左边距离
  var top = cy - mcy - mask.offsetHeight / 2;//mask离中图的容器的上边距离
  // 注意点:设置元素的尺寸和位置会导致浏览器reflow 浏览器为了优化性能不会立马reflow 会等到最后都设置完之后 会进行一次reflow
  var maxLeft = minddleImage.offsetWidth - mask.offsetWidth;//最大左侧偏移量
  var maxTop = minddleImage.offsetHeight - mask.offsetHeight;//最大头部偏移量
  console.log('left:'+left)
  console.log('top:'+top)

  //处理边界条件
  if(left<=0){
    left = 0;
  }
  if(top<=0){
    top = 0;
  }
  if(left>=maxLeft){
    left = maxLeft;
  }
  if(top>=maxTop){
    top = maxTop;
  }
  mask.style.left = left + 'px';
  mask.style.top = top + 'px';
  //移动大图的偏移量
  bigImage.style.backgroundPositionX = -left + 'px';
  bigImage.style.backgroundPositionY = -top + 'px';
}
var leaveHandle = function(){
  mask.style.opacity = 0;
  bigImage.style.opacity = 0;
}
init();

 

posted @ 2024-09-29 15:12  飞奔的龟龟  阅读(41)  评论(0编辑  收藏  举报