一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

node.js|vue.js|jquery|angularjs|React|json|js教程|

服務(wù)器之家 - 編程語言 - JavaScript - js教程 - 原生js實(shí)現(xiàn)放大鏡組件

原生js實(shí)現(xiàn)放大鏡組件

2022-01-06 15:08蒲公英芽 js教程

這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)放大鏡組件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了js實(shí)現(xiàn)放大鏡組件開發(fā)的具體代碼,供大家參考,具體內(nèi)容如下

功能需求:

1、根據(jù)圖片數(shù)組創(chuàng)建圖標(biāo)列表;
2、鼠標(biāo)滑過圖標(biāo)時(shí),當(dāng)前圖標(biāo)增加紅色邊框;
3、鼠標(biāo)滑過圖標(biāo)時(shí),上方圖片區(qū)域顯示對(duì)應(yīng)的圖片,右側(cè)顯示放大后的圖片內(nèi)容;
4、鼠標(biāo)在圖片區(qū)域移動(dòng)時(shí),在右側(cè)實(shí)現(xiàn)放大效果;
5、下方圖標(biāo)列表,點(diǎn)擊左右按鈕,實(shí)現(xiàn)翻頁效果;
6、當(dāng)圖標(biāo)內(nèi)容不夠一頁時(shí),只移動(dòng)到最后一個(gè)圖標(biāo)的位置;

以京東的詳情頁為例,看一下效果:

原生js實(shí)現(xiàn)放大鏡組件

放大鏡內(nèi)容寫在 Zoom.js 文件里,下方的圖標(biāo)列表內(nèi)容寫在 IconList.js 文件里,當(dāng)鼠標(biāo)滑過下面的圖標(biāo)時(shí),需要更改放大鏡里div的背景圖片,這里用到了事件拋發(fā)。

下面附上代碼:

html結(jié)構(gòu) :

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!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';
  //圖標(biāo)數(shù)組
  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文件,創(chuàng)建放大鏡組件:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
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);
  //創(chuàng)建外層的div容器
  this.elem=this.createE();
  //監(jiān)聽事件,改變zoomSmall的背景圖
  document.addEventListener(Zoom.SET_BG_IMG,e=>this.setBgImg(e));
  //創(chuàng)建下方的icon列表
  this.createIconList(_list,this.elem);
 }
 createE(){
  //創(chuàng)建外層div容器
  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>`;
  //設(shè)置樣式
  Zoom.setStyle();
  //獲取樣式
  Utils.getIdElem(div,this);
  //監(jiān)聽鼠標(biāo)滑入事件
  this.zoomSmall.addEventListener("mouseenter",e=>this.mouseHandler(e));
  return div;
 }
 appendTo(parent){
  Utils.appendTo(this.elem,parent);
 }
 setBgImg(e){
  //設(shè)置背景圖片
  this.zoomSmall.style.backgroundImage=`url(${e.src})`;
  this.zoomCont.style.backgroundImage=`url(${e.src})`;
 }
 createIconList(list,parent){
  //創(chuàng)建下方icon圖標(biāo)列表
  let iconList=new IconList(list);
  Utils.appendTo(iconList.elem,parent);
 }
 mouseHandler(e){
  switch (e.type) {
   case "mouseenter":
    //鼠標(biāo)滑入后,顯示遮罩和右側(cè)大圖片
    this.zoomMask.style.display="block";
    this.zoomCont.style.display="block";
    //監(jiān)聽鼠標(biāo)移動(dòng)和滑出事件
    this.mouseHandlers=e=>this.mouseHandler(e);
    this.zoomSmall.addEventListener("mousemove",this.mouseHandlers);
    this.zoomSmall.addEventListener("mouseleave",this.mouseHandlers);
    break;
   case "mousemove":
    //遮罩移動(dòng)
    this.zoomMaskMove(e);
    break;
   case "mouseleave":
    //鼠標(biāo)滑出后,顯示遮罩和右側(cè)大圖片
    this.zoomMask.style.display="none";
    this.zoomCont.style.display="none";
    //移除鼠標(biāo)移動(dòng)和滑出事件
    this.zoomSmall.removeEventListener("mousemove",this.mouseHandlers);
    this.zoomSmall.removeEventListener("mouseleave",this.mouseHandlers);
    break;
  }
 }
 zoomMaskMove(e){
  //遮罩移動(dòng)
  let rect=this.elem.getBoundingClientRect();
  //計(jì)算let和top的值,等于鼠標(biāo)的坐標(biāo)-父容器的left值-遮罩的一半寬
  let x=e.clientX-rect.x-Zoom.mask_width/2;
  let y=e.clientY-rect.y-Zoom.mask_width/2;
  //判斷l(xiāng)eft和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";
  //大圖片移動(dòng)
  this.zoomContMove(x,y);
 }
 zoomContMove(_x,_y){
  //計(jì)算大圖片的背景定位,公式:zoom的寬/mask的寬=zoom的背景l(fā)eft值/mask的left值
  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(){
  //設(shè)置樣式
  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文件,創(chuàng)建下方圖標(biāo)列表,并完成翻頁效果:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
import Utils from "./Utils.js";
import Zoom from "./Zoom.js";
export default class IconList{
 static styles=false;
 static num=5;//每頁顯示的圖標(biāo)數(shù)
 static gap=0;//表示li的左右間距
 position=0;//當(dāng)前顯示的圖標(biāo)為第幾頁
 x=0;//列表的left值
 prepIcon;//上一個(gè)點(diǎn)擊的圖標(biāo)
 static SET_BG_IMG="set_bg_img";
 constructor(list){
  this.list=list;
  this.elem=this.createE();
 }
 createE(){
  //創(chuàng)建外層容器
  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">`;
  //設(shè)置css樣式
  IconList.setStyles(this.list);
  //獲取元素
  Utils.getIdElem(div,this);
  //外層容器監(jiān)聽點(diǎn)擊事件
  div.addEventListener("click",e=>this.clickHandler(e));
  //圖標(biāo)列表監(jiān)聽鼠標(biāo)滑過事件
  this.iconList.addEventListener("mouseover",e=>this.mouseHandler(e));
  //默認(rèn)顯示第一個(gè)圖標(biāo)的邊框
  this.setIconState(this.iconList.firstElementChild);
  //默認(rèn)顯示第一個(gè)圖片
  this.setBgImg(this.iconList.firstElementChild.firstElementChild);
  return div;
 }
 createIcon(){
  //創(chuàng)建圖標(biāo)列表
  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;
  //如果點(diǎn)擊的不是左右按鈕,直接跳出
  if(!/prev/.test(src)&&!/next/.test(src)) return;
  //每一個(gè)li的實(shí)際寬度,width+border+margin
  let liWidth=54+4+IconList.gap;
  //page為一共有幾個(gè)整數(shù)頁
  let page=Math.floor(this.list.length/IconList.num)-1;
  //remainder為最后不夠一頁的剩余圖標(biāo)數(shù)
  let remainder=this.list.length%IconList.num;
  if(/prev/.test(src)){
   //如果點(diǎn)擊的是上一頁按鈕
   if(this.x===0) return;
   //移動(dòng)到最后一頁時(shí)
   if(this.position===0&&remainder>0){
    //移動(dòng)的距離加等于li寬度*剩余圖標(biāo)數(shù)
    this.x+=liWidth*remainder;
   }
   else if(this.position<=page){
    this.position--;
    //移動(dòng)的距離加等于li的寬度*每頁顯示的圖標(biāo)數(shù)(5個(gè))
    this.x+=liWidth*IconList.num;
   }
  }else if(/next/.test(src)){
   //如果點(diǎn)擊的是下一頁按鈕
   if(this.x===-(this.list.length-IconList.num)*liWidth) return;
   if(this.position===page&&remainder>0){
    //移動(dòng)的距離減等于li寬度*剩余圖標(biāo)數(shù)
    this.x-=liWidth*remainder;
   }
   else if(this.position<page){
    this.position++;
    //移動(dòng)的距離減等于li的寬度*每頁顯示的圖標(biāo)數(shù)(5個(gè))
    this.x-=liWidth*IconList.num;
   }
  }
  //設(shè)置圖標(biāo)列表的left值
  this.iconList.style.left=this.x+"px";
 }
 mouseHandler(e){
  //如果滑過的不是Img標(biāo)簽,直接跳出
  if(e.target.constructor!==HTMLImageElement) return;
  //設(shè)置背景圖片
  this.setBgImg(e.target);
  //設(shè)置當(dāng)前滑過圖標(biāo)的樣式
  this.setIconState(e.target.parentElement);
 }
 setIconState(target){
  //移除上一個(gè)滑過圖標(biāo)的active樣式
  if(this.prepIcon) Utils.removeClass(this.prepIcon,"active");
  //將當(dāng)前滑過的對(duì)象賦值給this.prepIcon
  this.prepIcon=target;
  //給當(dāng)前滑過圖標(biāo)增加active樣式
  Utils.addClass(this.prepIcon,"active");
 }
 setBgImg(target){
  //拋發(fā)事件,將當(dāng)前圖片的src傳過去
  let src=target.src.replace("_icon","");
  let evt=new Event(IconList.SET_BG_IMG);
  evt.src=src;
  document.dispatchEvent(evt);
 }
 static setStyles(list){
  //設(shè)置樣式
  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文件,是一個(gè)工具包:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
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(/[A-Z]/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];
 }
}

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:https://blog.csdn.net/Charissa2017/article/details/104159002

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 娇妻与公陈峰姚瑶小说在线阅读 | 欧美一区二区三区四区在线观看 | 亚洲天堂影院在线观看 | 91精品国产9l久久久久 | 特级毛片全部免费播放器 | 国产91第一页 | 久久精品国产色蜜蜜麻豆国语版 | 护士被多人调教到失禁h | 国产99视频精品免视看7 | 国产99视频精品免视看7 | 日韩一区二区三区不卡视频 | 9丨精品国产高清自在线看 9久热这里只有精品免费 | 亚洲香蕉综合在人在线视看 | 小鸟酱视频在线观看 | 高清视频在线播放ww | 91美女在线| 饭冈加奈子在线播放观看 | 色哟哟精品 | 涩涩五月天 | 好看的亚洲视频 | 亚洲欧美另类综合 | 青青草人人 | bt天堂在线最新版在线 | 国产1区精品| 亚洲欧美日韩中文高清一 | 国产成人综合久久精品红 | 俄罗斯15一16处交 | 亚洲丁香网 | 四虎成人影院 | 无人区在线观看免费视频国语 | 冰雪奇缘1完整版免费观看 变形金刚第一部 | 处女摘花 | 国产一卡2卡3卡4卡公司科普 | 四虎国产欧美成人影院 | 国产精品久久久久久久久免费 | 我在厨房摸岳的乳HD在线观看 | 欧美成人免费观看久久 | 国产自拍视频一区 | 男人最爱看的网站 | 好涨好大我快受不了了视频网 | 外国黄色软件 |