乐趣区

js原生仿淘宝放大镜效果

js 原生仿淘宝放大镜效果

该效果主要模仿淘宝购物时的,当鼠标悬停于图片上端时,出现对应的放大模块,并且在附近区域显示对应的图片信息,主要运用到了 js 的监听鼠标在对应区域内的监听函数:

  • onmouseenter 事件在鼠标指针移动到元素上时触发。
  • onmouseover 事件会在鼠标指针移动到指定的元素上时发生。
  • onmouseleave 事件在鼠标移除元素时触发
  • onmousemove 事件会在鼠标指针移动时发生

制作过程

1. 定义对象

  var biger = document.getElementById('biger');
  var main = document.getElementById('main');
  var smaller = document.getElementById('smaller');
  var mask = document.getElementById('mask');
  var wrap = biger.parentNode;
  var imgArr = [{"path":"./images/banner1.jpg"},
      {"path":"./images/banner2.jpg"},
      {"path":"./images/banner3.jpg"},
      {"path":"./images/banner4.jpg"},
      {"path":"./images/banner5.jpg"}
  ];
  var imgSum = imgArr.length;
  if(imgSum > 5){imgSum = 5;}

2. 生成 Dom 元素,显示图片信息

insertBefore(_newnode,_existingnode)

  • insertBefore(_newnode,_existingnode) 方法在您指定的已有子节点之前插入新的子节点
  • 提示:如果您希望创建包含文本的新列表项,请记得创建文本节点形式的文本,以便追加到 LI 元素中,然后向列表插入这个 LI。
  • _newnode:必需。需要插入的节点对象。
  • _existingnode: 可选。在其之前插入新节点的子节点。如果未规定,则 insertBefore 方法会在结尾插入 newnode。

您也可以使用 insertBefore 方法插入 / 移动已有元素。

for (var i = 0; i<imgSum; i++){var  lis = document.createElement('li');
      var  imgs = document.createElement('img');
      imgs.src = imgArr[i].path;
      lis.appendChild(imgs);
      smaller.appendChild(lis);
  }
  var mainImg = document.createElement('img');
  var bigImg = document.createElement('img');
  var liArr = smaller.children;
  bigImg.src = mainImg.src = liArr[0].children[0].src;
  main.insertBefore(mainImg,mask);
  biger.appendChild(bigImg);

3. 点击事件,切换图片信息

removeAttribute()

  • removeAttribute() 方法删除指定的属性。
  • 此方法与 removeAttributeNode() 方法的差异是:removeAttributeNode() 方法删除指定的 Attr 对象,而此方法删除具有指定名称的属性。结果是相同的。同时此方法不返回值,而 removeAttributeNode() 方法返回被删除的属性,以 Attr 对象的形式。
 var bigPic = biger.children[0];
  liArr[0].className = 'current';
  for (var i=0; i<liArr.length;i++){liArr[i].index = i;
      liArr[i].onclick = function () {
          this.className = 'current';
          bigPic.src = main.children[0].src = this.children[0].src;
          for (var j = 0; j < liArr.length; j++) {if(this!=liArr[j]){liArr[j].removeAttribute('class');
                  liArr[j].removeAttribute('className');
              }
          }
      }
  }

4. 监听鼠标移动,显示放大效果

  main.onmouseenter = function () {
      mask.style.display = 'block';
      biger.style.display = 'block';
  }
    main.onmouseleave=function(){
        mask.style.display='none';
        biger.style.display='none';
    }
  main.onmousemove = function (e) {
      var e = e || window.event;
      var pagex = e.pageX || scroll().left + e.clientX;
      var pagey = e.pageY || scroll().top + e.clientY;
      pagex = pagex - wrap.offsetLeft - mask.offsetWidth / 2;
      pagey = pagey - wrap.offsetTop - mask.offsetHeight / 2 ;
      if(pagex<0){pagex=0;}
      if(pagey<0){pagey=0;}
      if(pagex>main.offsetWidth-mask.offsetWidth){pagex=main.offsetWidth-mask.offsetWidth;}
      if(pagey>main.offsetHeight-mask.offsetHeight){pagey=main.offsetHeight-mask.offsetHeight;}
      mask.style.left=pagex+'px';
      mask.style.top=pagey+'px';
      var scale=(bigPic.offsetWidth-biger.offsetWidth)/(main.offsetWidth-mask.offsetWidth);
      var xx=pagex*scale;
      var yy=pagey*scale;
      bigPic.style.left=-xx+'px';
      bigPic.style.top=-yy+'px';
  }

获取鼠标的位移点位(x,y)

  var pagex = e.pageX || scroll().left + e.clientX;
      var pagey = e.pageY || scroll().top + e.clientY;
      pagex = pagex - wrap.offsetLeft - mask.offsetWidth / 2;
      pagey = pagey - wrap.offsetTop - mask.offsetHeight / 2 ;

设置移动范围,不允许超出图片部分

if(pagex<0){pagex=0;}
      if(pagey<0){pagey=0;}
      if(pagex>main.offsetWidth-mask.offsetWidth){pagex=main.offsetWidth-mask.offsetWidth;}
      if(pagey>main.offsetHeight-mask.offsetHeight){pagey=main.offsetHeight-mask.offsetHeight;}

设置放大区域:移动放大图片的位置(top,left)

  mask.style.left=pagex+'px';
      mask.style.top=pagey+'px';
      var scale=(bigPic.offsetWidth-biger.offsetWidth)/(main.offsetWidth-mask.offsetWidth);
      var xx=pagex*scale;
      var yy=pagey*scale;
      bigPic.style.left=-xx+'px';
      bigPic.style.top=-yy+'px';

js 源码

window.onload = function () {var biger = document.getElementById('biger');
  var main = document.getElementById('main');
  var smaller = document.getElementById('smaller');
  var mask = document.getElementById('mask');
  var wrap = biger.parentNode;
  var imgArr = [{"path":"./images/banner1.jpg"},
      {"path":"./images/banner2.jpg"},
      {"path":"./images/banner3.jpg"},
      {"path":"./images/banner4.jpg"},
      {"path":"./images/banner5.jpg"}
  ];
  var imgSum = imgArr.length;
  if(imgSum > 5){imgSum = 5;}
  for (var i = 0; i<imgSum; i++){var  lis = document.createElement('li');
      var  imgs = document.createElement('img');
      imgs.src = imgArr[i].path;
      lis.appendChild(imgs);
      smaller.appendChild(lis);
  }
  var mainImg = document.createElement('img');
  var bigImg = document.createElement('img');
  var liArr = smaller.children;
  bigImg.src = mainImg.src = liArr[0].children[0].src;
  main.insertBefore(mainImg,mask);
  biger.appendChild(bigImg);
  var bigPic = biger.children[0];
  liArr[0].className = 'current';
  for (var i=0; i<liArr.length;i++){liArr[i].index = i;
      liArr[i].onclick = function () {
          this.className = 'current';
          bigPic.src = main.children[0].src = this.children[0].src;
          for (var j = 0; j < liArr.length; j++) {if(this!=liArr[j]){liArr[j].removeAttribute('class');
                  liArr[j].removeAttribute('className');
              }
          }
      }
  }
  main.onmouseenter = function () {
      mask.style.display = 'block';
      biger.style.display = 'block';
  }
    main.onmouseleave=function(){
        mask.style.display='none';
        biger.style.display='none';
    }
  main.onmousemove = function (e) {
      var e = e || window.event;
      var pagex = e.pageX || scroll().left + e.clientX;
      var pagey = e.pageY || scroll().top + e.clientY;
      pagex = pagex - wrap.offsetLeft - mask.offsetWidth / 2;
      pagey = pagey - wrap.offsetTop - mask.offsetHeight / 2 ;
      if(pagex<0){pagex=0;}
      if(pagey<0){pagey=0;}
      if(pagex>main.offsetWidth-mask.offsetWidth){pagex=main.offsetWidth-mask.offsetWidth;}
      if(pagey>main.offsetHeight-mask.offsetHeight){pagey=main.offsetHeight-mask.offsetHeight;}
      mask.style.left=pagex+'px';
      mask.style.top=pagey+'px';
      var scale=(bigPic.offsetWidth-biger.offsetWidth)/(main.offsetWidth-mask.offsetWidth);
      var xx=pagex*scale;
      var yy=pagey*scale;
      bigPic.style.left=-xx+'px';
      bigPic.style.top=-yy+'px';
  }
};

该文章主要是在淘宝上看到页面效果后,进行模拟开发的,主要的点在于鼠标的监听事件以及显示模块位置的设置,希望这篇文章对大家会有帮助,并且多多点赞,感谢!github 地址

退出移动版