手撸原生js放大镜效果
普及知识:放大镜特效涉及到的几个值
offsetWidth 获取元素的宽度
offsetHeight 获取元素的高度
offsetLeft父元素没有定位时,获取元素距离页面的左边距,父元素有定位时,获取元素距离父元素的左边距
offsetTop父元素没有定位时,获取元素距离页面的上边距,父元素有定位时,获取元素距离父元素的上边距
clientX 离视口左边的距离
clientY 离视口上边的距离
onmousemove 鼠标移动事件
onmouseover 鼠标划过事件
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();