Native js implementation of magnifying glass component

Native js implementation of magnifying glass component

This article example shares the specific code for js to develop a magnifying glass component for your reference. The specific content is as follows

Functional requirements:

1. Create an icon list based on the picture array;
2. When the mouse moves over an icon, a red border is added to the current icon;
3. When the mouse moves over the icon, the corresponding image will be displayed in the upper image area, and the enlarged image content will be displayed on the right;
4. When the mouse moves in the picture area, the zoom effect is achieved on the right side;
5. In the icon list below, click the left and right buttons to turn the pages;
6. When the icon content is not enough for one page, it only moves to the position of the last icon;

Take JD.com’s details page as an example to see the effect:

The magnifying glass content is written in the Zoom.js file, and the icon list content below is written in the IconList.js file. When the mouse hovers over the icon below, the background image of the div in the magnifying glass needs to be changed. Event throwing is used here.

The code is attached below:

HTML structure:

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>zoom</title>
</head>
<body>
 <script type="module">
  import Zoom from './js/Zoom.js';
  //icon array let list=["a_icon.jpg","e_icon.jpg","f_icon.jpg","g_icon.jpg","h_icon.jpg","i_icon.jpg","j_icon.jpg",];
  init();
  function init(){
   let zoom = new Zoom(list,"./img/");
   zoom.appendTo("body");
  }
 </script>
</body>
</html>

Zoom.js file, create a magnifying glass component:

import Utils from "./Utils.js";
import IconList from './IconList.js';
export default class Zoom{
 static styles=false;
 static small_width=450;
 static mask_width=303.75;
 static zoom_width=540;
 static SET_BG_IMG="set_bg_img";
 constructor(_list,_basePath){
  if(_basePath) _list=_list.map(item=>_basePath+item);
  //Create the outer div container this.elem=this.createE();
  //Listen for events and change the background image of zoomSmall document.addEventListener(Zoom.SET_BG_IMG, e=>this.setBgImg(e));
  //Create the icon list below this.createIconList(_list,this.elem);
 }
 createE(){
  //Create an outer div container let div=Utils.createE("div");
  div.className="zoomContainer";
  div.innerHTML=`<div class="zoomSmall" id="zoomSmall"><div class="zoomMask" id="zoomMask"></div></div>
  <div class="zoomContent" id="zoomCont"></div>`;
  //Set the styleZoom.setStyle();
  //Get the style Utils.getIdElem(div,this);
  //Listen for mouse entry events this.zoomSmall.addEventListener("mouseenter",e=>this.mouseHandler(e));
  return div;
 }
 appendTo(parent){
  Utils.appendTo(this.elem,parent);
 }
 setBgImg(e){
  //Set the background image this.zoomSmall.style.backgroundImage=`url(${e.src})`;
  this.zoomCont.style.backgroundImage=`url(${e.src})`;
 }
 createIconList(list,parent){
  //Create the icon list below let iconList=new IconList(list);
  Utils.appendTo(iconList.elem,parent);
 }
 mouseHandler(e){
  switch (e.type) {
   case "mouseenter":
    //After the mouse slides in, the mask and the large image on the right are displayed this.zoomMask.style.display="block";
    this.zoomCont.style.display="block";
    //Listen for mouse movement and slide-out events this.mouseHandlers=e=>this.mouseHandler(e);
    this.zoomSmall.addEventListener("mousemove",this.mouseHandlers);
    this.zoomSmall.addEventListener("mouseleave",this.mouseHandlers);
    break;
   case "mousemove":
    //Mask movement this.zoomMaskMove(e);
    break;
   case "mouseleave":
    //After the mouse moves out, the mask and the large image on the right are displayed this.zoomMask.style.display="none";
    this.zoomCont.style.display="none";
    //Remove mouse move and slide out events this.zoomSmall.removeEventListener("mousemove",this.mouseHandlers);
    this.zoomSmall.removeEventListener("mouseleave",this.mouseHandlers);
    break;
  }
 }
 zoomMaskMove(e){
  //Mask movement let rect = this.elem.getBoundingClientRect();
  //Calculate the values ​​of let and top, which are equal to the mouse coordinates - the left value of the parent container - half the width of the mask let x=e.clientX-rect.x-Zoom.mask_width/2;
  let y = e.clientY-rect.y-Zoom.mask_width/2;
  //Judge the range of left and top if(x<0) x=0;
  if(x>Zoom.small_width-Zoom.mask_width) x=Zoom.small_width-Zoom.mask_width;
  if(y<0) y=0;
  if(y>Zoom.small_width-Zoom.mask_width) y=Zoom.small_width-Zoom.mask_width;
  this.zoomMask.style.left=x+"px";
  this.zoomMask.style.top=y+"px";
  //Move the big picture this.zoomContMove(x,y);
 }
 zoomContMove(_x,_y){
  //Calculate the background positioning of the large image, formula: zoom width/mask width=zoom background left value/mask left value let x=-Zoom.zoom_width/Zoom.mask_width*_x;
  let y = -Zoom.zoom_width / Zoom.mask_width * _y;
  this.zoomCont.style.backgroundPosition=x+"px "+y+"px";
 }
 static setStyle(){
  //Set style if(Zoom.styles) return;
  Zoom.styles=true;
  Utils.insertCss(".zoomContainer",{
   width:Zoom.small_width+"px",
   height:Zoom.small_width+"px",
   position:"relative"
  })
  Utils.insertCss(".zoomSmall",{
   width:Zoom.small_width+"px",
   height:Zoom.small_width+"px",
   border: "1px solid #000",
   backgroundSize: "100% 100%",
   position:"absolute",
   left:"0px",
   top:"0px"
  })
  Utils.insertCss(".zoomMask",{
   width: this.mask_width + "px",
   height: this.mask_width + "px",
   backgroundColor: "rgba(200,170,0,0.3)",
   position: "absolute",
   left: "0px",
   top: "0px",
   display: "none"
  })
  Utils.insertCss(".zoomContent",{
   width: this.zoom_width + "px",
   height: this.zoom_width + "px",
   border: "1px solid #ccc",
   position: "absolute",
   left: (this.small_width + 2) + "px",
   top: "0px",
   display: "none"
  })
 }
}

IconList.js file, create the icon list below, and complete the page turning effect:

import Utils from "./Utils.js";
import Zoom from "./Zoom.js";
export default class IconList{
 static styles=false;
 static num=5;//Number of icons displayed per page static gap=0;//Indicates the left and right spacing of li position=0;//Which page is the icon currently displayed x=0;//Left value of the list prepIcon;//The last clicked icon static SET_BG_IMG="set_bg_img";
 constructor(list){
  this.list=list;
  this.elem=this.createE();
 }
 createE(){
  //Create an outer container let div=Utils.createE("div");
  div.className="iconContainer";
  div.innerHTML=`<img class="prevBtn" src="./img/prev.png"><div class="iconListCont">${this.createIcon()}</div><img class="nextBtn" src="./img/next.png">`;
  //Set css style IconList.setStyles(this.list);
  //Get the element Utils.getIdElem(div,this);
  //Outer container listens for click events div.addEventListener("click",e=>this.clickHandler(e));
  //The icon list monitors the mouse over event this.iconList.addEventListener("mouseover",e=>this.mouseHandler(e));
  //By default, the border of the first icon is displayed this.setIconState(this.iconList.firstElementChild);
  //The first picture is displayed by default this.setBgImg(this.iconList.firstElementChild.firstElementChild);
  return div;
 }
 createIcon(){
  //Create an icon list let str=`<ul class="iconList clearfix" id="iconList">`;
  this.list.forEach(item=>{
   str+=`<li><img src="${item}"></li>`;
  })
  str+="</ul>";
  return str;
 }
 clickHandler(e){
  let src = e.target.src;
  //If the button clicked is not the left or right button, jump out directly if(!/prev/.test(src)&&!/next/.test(src)) return;
  //The actual width of each li, width+border+margin
  let liWidth=54+4+IconList.gap;
  //page is the total number of integer pages let page=Math.floor(this.list.length/IconList.num)-1;
  //remainder is the number of remaining icons that are not enough for one page let remainder=this.list.length%IconList.num;
  if(/prev/.test(src)){
   //If the previous page button is clicked if(this.x===0) return;
   //Move to the last page if(this.position===0&&remainder>0){
    //The moving distance plus the remaining icons is equal to li width * this.x+=liWidth*remainder;
   }
   else if(this.position<=page){
    this.position--;
    //The distance moved plus the width of li * the number of icons displayed per page (5)
    this.x+=liWidth*IconList.num;
   }
  }else if(/next/.test(src)){
   //If the next page button is clicked if(this.x===-(this.list.length-IconList.num)*liWidth) return;
   if(this.position===page&&remainder>0){
    //The distance moved minus the width of li * the number of remaining icons this.x-=liWidth*remainder;
   }
   else if(this.position<page){
    this.position++;
    //The distance moved minus the width of li * the number of icons displayed per page (5)
    this.x-=liWidth*IconList.num;
   }
  }
  //Set the left value of the icon list this.iconList.style.left=this.x+"px";
 }
 mouseHandler(e){
  //If the tag you slide over is not an Img tag, just exit if(e.target.constructor!==HTMLImageElement) return;
  //Set the background image this.setBgImg(e.target);
  //Set the style of the current sliding icon this.setIconState(e.target.parentElement);
 }
 setIconState(target){
  //Remove the active style of the previous scroll icon if(this.prepIcon) Utils.removeClass(this.prepIcon,"active");
  //Assign the current sliding object to this.prepIcon
  this.prepIcon=target;
  //Add active style to the current sliding icon Utils.addClass(this.prepIcon,"active");
 }
 setBgImg(target){
  //Throw event and pass the src of the current image let src=target.src.replace("_icon","");
  let evt = new Event (IconList.SET_BG_IMG);
  evt.src=src;
  document.dispatchEvent(evt);
 }
 static setStyles(list){
  //Set style if(IconList.styles) return;
  IconList.styles=true;
  Utils.insertCss(".iconContainer",{
   width:Zoom.small_width+2+"px",
   height: "58px",
   position: "absolute",
   top: Zoom.small_width+2+"px",
   left: "0px",
  })
  Utils.insertCss(".iconContainer>img",{
   width:"22px",
   height:"32px",
   cursor:"pointer",
   position:"absolute",
   top:"13px",
  })
  Utils.insertCss(".prevBtn",{
   left:"8px"
  })
  Utils.insertCss(".nextBtn",{
   right:"8px"
  })
  Utils.insertCss(".iconListCont",{
   width:Zoom.small_width-30*2+"px",
   height:"58px",
   position:"relative",
   left:"30px",
   overflow:"hidden"
  })
  IconList.gap=((Zoom.small_width-30*2)-(54+4)*IconList.num)/IconList.num;
  Utils.insertCss(".iconList",{
   width:(54+4+IconList.gap)*list.length+"px",
   listStyle:"none",
   padding:"0px",
   margin:"0px",
   position:"absolute",
   left:"0px",
   top:"0px",
   transition:"all .3s"
  })
  Utils.insertCss(".iconList li",{
   float:"left",
   width:"54px",
   height:"54px",
   margin:"0px "+IconList.gap/2+"px",
   cursor:"pointer",
   border:"2px solid transparent"
  })
  Utils.insertCss(".iconList li.active",{
   borderColor:"#f00"
  })
  Utils.insertCss(".iconList li>img",{
   width:"54px",
   height:"54px"
  })
  Utils.insertCss(".clearfix::after",{
   content:"\".\"",
   display:"block",
   height:"0px",
   clear:"both",
   overflow:"hidden",
   visibility:"hidden"
  })
 }
}

Utils.js file is a toolkit:

export default class Utils{
 static createE(elem,style,prep){
  elem = document.createElement(elem);
  if(style) for(let prop in style) elem.style[prop]=style[prop];
  if(prep) for(let prop in prep) elem[prop]=prep[prop];
  return elem;
 }
 static appendTo(elem,parent){
  if (parent.constructor === String) parent = document.querySelector(parent);
  parent.appendChild(elem);
 }
 static insertBefore(elem,parent){
  if(parent.constructor === String) parent=document.querySelector(parent);
  parent.insertBefore(elem,parent.firstElementChild);
 }
 static randomNum(min,max){
  return Math.floor(Math.random*(max-min)+min);
 }
 static randomColor(alpha){
  alpha=alpha||Math.random().toFixed(1);
  if(isNaN(alpha)) alpha=1;
  if(alpha>1) alpha=1;
  if(alpha<0) alpha=0;
  let col="rgba(";
  for(let i=0;i<3;i++){
   col+=Utils.randomNum(0,256)+",";
  }
  col+=alpha+")";
  return col;
 }
 static insertCss(select,styles){
  if(document.styleSheets.length===0){
   let styleS = Utils.createE("style");
   Utils.appendTo(styleS,document.head);
  }
  let styleSheet = document.styleSheets[document.styleSheets.length-1];
  let str=select+"{";
  for(var prop in styles){
   str+=prop.replace(/[AZ]/g,function(item){
    return "-"+item.toLocaleLowerCase();
   })+":"+styles[prop]+";";
  }
  str+="}"
  styleSheet.insertRule(str,styleSheet.cssRules.length);
 }
 static getIdElem(elem,obj){
  if(elem.id) obj[elem.id]=elem;
  if(elem.children.length===0) return obj;
  for(let i=0;i<elem.children.length;i++){
   Utils.getIdElem(elem.children[i],obj);
  }
 }
 static addClass(elem,className){
  let arr=(elem.className+" "+className).match(/\S+/g);
  arr = arr.filter((item,index)=>arr.indexOf(item,index+1)<0)
  elem.className=arr.join(" ");
 }
 static removeClass(elem,className){
  if(!elem.className) return;
  let arr = elem.className.match(/\S+/g);
  let arr1=className.match(/\S+/g);
  arr1.forEach(item=>{
   arr = arr.filter(t=>t!==item)
  })
  elem.className=arr.join(" ");
 }
 static hasClass(elem,className){
  if(!elem.className) return false;
  let arr = elem.className.match(/\S+/g);
  let arr1=className.match(/\S+/g);
  let res;
  arr1.forEach(item=>{
   res = arr.some(it=>it===item)
  })
  return res;
 }
 static loadImg({list,basePath,callback}){
  if(!list || list.length===0) return;
  if(basePath) list=list.map(item=>basePath+item);
  let img = Utils.createE("img");
  img.data={
   list:list,
   callback:callback,
   resultList:[],
   num:0
  }
  img.addEventListener("load",Utils.loadImgHandler);
  img.src=list[img.data.num];
 }
 static loadImgHandler(e){
  let data=e.currentTarget.data;
  data.resultList.push(e.currentTarget.cloneNode(false));
  data.num++;
  if(data.num>data.list.length-1){
   e.currentTarget.removeEventListener("load",Utils.loadImgHandler);
   data.callback(data.resultList);
   data=null;
   return;
  }
  e.currentTarget.src=data.list[data.num];
 }
}

The above is the full content of this article. I hope it will be helpful for everyone’s study. I also hope that everyone will support 123WORDPRESS.COM.

You may also be interested in:
  • JavaScript implements the most complete code analysis of a simple magnifying glass (ES5)
  • js to achieve a simple magnifying glass effect
  • js realizes the magnifying glass function of shopping website
  • js to achieve simple magnifying glass effects
  • js magnifying glass magnifying picture effect
  • A simple example of using js to achieve the effect of a magnifying glass
  • A magical Javascript image magnifier
  • Magnifying glass effect written in native js
  • Image magnifier jquery.jqzoom.js usage example with magnifying glass icon
  • JS version of the picture magnifying glass effect

<<:  How to write configuration files and use MyBatis simply

>>:  Windows Server 2008 R2 Multi-User Remote Desktop Connection Licensing

Recommend

Detailed explanation of this pointing problem in JavaScript function

this keyword Which object calls the function, and...

Chinese and English font name comparison table (including Founder and Arphic)

In CSS files, we often see some font names become...

JavaScript implements changing the color of a web page through a slider

Hello everyone, today when I was looking at the H...

win2008 server security settings deployment document (recommended)

I had been working on the project before the New ...

js learning notes: class, super and extends keywords

Table of contents Preface 1. Create objects befor...

Several ways to clear arrays in Vue (summary)

Table of contents 1. Introduction 2. Several ways...

Vue implements the magnifying glass function of the product details page

This article shares the specific code of Vue to i...

Analysis of the process of simply deploying nginx in Docker container

1. Deploy nginx service in container The centos:7...

Token verification login in Vue project (front-end part)

This article example shares the specific code of ...

JavaScript to achieve simple tab bar switching case

This article shares the specific code for JavaScr...

A brief discussion on Vue3 father-son value transfer

Table of contents From father to son: 1. In the s...

Detailed explanation of the TARGET attribute of the HTML hyperlink tag A

The hyperlink <a> tag represents a link poin...

Vue+node realizes audio recording and playback function

Result: The main part is to implement the code lo...