jQuery自定义插件之商城图片放大镜效果

更多jQuery常用插件使用请访问:jQuery常用插件汇总


jQuery自定义插件之商城图片放大镜效果是网页中最常见不过的插件了,所以写一个自用插件,偷懒一下。

上源码,想用的直接复制走,保存在一个js文件即可使用。

效果插件源码

/*
 * @Author: JiaoShou 
 * @Date: 2020-07-09 16:46:34 
 * @Last Modified by: JiaoShou
 * @Last Modified time: 2020-07-10 18:18:46
 */
;(function(window,$,undefined){

  $.fn.extend({
    /**
     * 放大镜效果
     * @param {object} option  可选参数
     */
    'cloudzoom': function(option){
      var defaults = {
            smallEl: '.cloudzoom-small',      //存放缩略图的元素,不能省略jq获取元素时候的#、.
            bigWidth: 0,     //大图盒子可视窗口宽度,不带单位的number,传值不能转换成数字,会被强制改成默认值,不传参数,默认就是小图的尺寸
            bigHeight: 0,     //大图盒子可视窗口高度,不带单位的number,传值不能转换成数字,会被强制改成默认值,不传参数,默认就是小图的尺寸
            bigoffsetTop: 0,     //大图盒子的距离顶部偏移位置,不带单位的number,传值不能转换成数字,会被强制改成默认值
            bigoffsetLeft: 0,     //大图盒子的距离左侧偏移位置,不带单位的number,传值不能转换成数字,会被强制改成默认值
            scale: 2,       //设置小图放大倍数后的数值给大图用,不带单位的number,传值不能转换成数字,会被强制改成默认值
          },
          opts = $.extend({}, defaults, option);
      
      return this.each(function () {
        
        var cloudzoom = {
          $el: $(this), //事件对象
          defaults: defaults,      //插件默认值
          smallEl: opts.smallEl,      //存放缩略图的元素,不能省略jq获取元素时候的#、.
          bigWidth: opts.bigWidth,     //大图盒子的宽度,不带单位的number,传值不能转换成数字,会被强制改成默认值
          bigHeight: opts.bigHeight,     //大图盒子的高度,不带单位的number,传值不能转换成数字,会被强制改成默认值
          bigoffsetTop: opts.bigoffsetTop,     //大图盒子的距离顶部偏移位置,不带单位的number,传值不能转换成数字,会被强制改成默认值
          bigoffsetLeft: opts.bigoffsetLeft,     //大图盒子的距离左侧偏移位置,不带单位的number,传值不能转换成数字,会被强制改成默认值
          scale: opts.scale,       //设置小图放大倍数后的数值给大图用,不带单位的number,传值不能转换成数字,会被强制改成默认值
          $small: null,      //获取small对象
          $shadow: null,      //获取shadow对象
          $zoomIcon: null,      //获取zoomIcon对象
          $smallImg: null,      //获取smallImg对象
          $big: null,      //获取big对象
          $bigImg: null,      //获取bigImg对象
          smallImgWidth:0,       //小图width
          smallImgHeight:0,       //小图height
          smallImgSrc:'',       //小图src
          bigImgSrc:'',       //大图src
          // 初始化
          'init': function(){
            // 规范初始化参数
            this.initProp();
  
            // 创建shadow小图右下角放大镜icon
            this.createHtml();

            // 创建大图结构
            this.createBigHtml();
  
            // 调用small事件
            this.smallFn();
          },
          // 规范传入参数,如果不合规,恢复为插件默认值
          'initProp': function(){
            
            // 规范传入数字型参数,防止手残输入错误,输入错误则恢复成插件默认值
            this.bigWidth = Number(this.bigWidth) || this.defaults.bigWidth;
            this.bigHeight = Number(this.bigHeight) || this.defaults.bigHeight;
            this.bigoffsetTop = Number(this.bigoffsetTop) || this.defaults.bigoffsetTop;
            this.bigoffsetLeft = Number(this.bigoffsetLeft) || this.defaults.bigoffsetLeft;
            this.scale = Number(this.scale) || this.defaults.scale;
  
            // 获取小图选择器
            this.smallEl = $.trim(this.smallEl) ||  this.defaults.smallEl;
            // 获取小图jq对象
            this.$small = $(this.smallEl,this.$el);
            // 获取小图img jq对象
            this.$smallImg = this.$small.find('img');
            // 获取小图width
            this.smallImgWidth = this.$smallImg.width();
            // 获取小图height
            this.smallImgHeight = this.$smallImg.height();
            // 获取小图src
            this.smallImgSrc = this.$smallImg.attr('src');
            // 获取大图src
            this.bigImgSrc = this.$smallImg.attr('src');
            
            if (!this.bigWidth) {
              // 如果这个值是0,就用小图的尺寸
              // 大图可视窗口宽度
              this.bigWidth = this.$small.width();
            }
            if (!this.bigHeight) {
              // 如果这个值是0,就用小图的尺寸
              // 大图可视窗口高度
              this.bigHeight = this.$small.height();
            }
            if (!this.bigoffsetLeft) {
              // 如果这个值是0,就用小图的宽度+50
              // 大图可视窗口偏移量
              this.bigoffsetLeft = this.smallImgWidth + 50;
            }
          },
          // 创建shadow小图右下角放大镜icon
          'createHtml': function(){

            // 创建遮罩层和放大镜icon
            var str = '<span class="cloudzoom-shadow" ></span>'+
                      '<i class="cloudzoom-zoom-icon" ></i>';
            
            // 如果存在了,先把存在的删除掉,循环调用cloudzoom插件的时候会出现这个问题
            if ($('.cloudzoom-shadow',this.$el).length >=1 ) {
              $('.cloudzoom-shadow',this.$el).remove();
            }
            // 如果存在了,先把存在的删除掉,循环调用cloudzoom插件的时候会出现这个问题
            if ($('.cloudzoom-zoom-icon',this.$el).length >=1 ) {
              $('.cloudzoom-zoom-icon',this.$el).remove();
            }
            // 插入遮罩层和放大镜icon
            this.$small.append(str);
            
            // 获取shadow对象
            this.$shadow = $('.cloudzoom-shadow', this.$el);
            // 获取zoomIcon对象
            this.$zoomIcon = $('.cloudzoom-zoom-icon', this.$el);
            
          },
          // 创建大图结构
          'createBigHtml': function () {
            var smallImgWidth = this.smallImgWidth;
            var smallImgHeight = this.smallImgHeight;
            var scale = this.scale;
            var bigImgSrc = this.bigImgSrc;
            var bigoffsetTop = this.bigoffsetTop;
            var bigoffsetLeft = this.bigoffsetLeft;
            var bigWidth = this.bigWidth;
            var bigHeight = this.bigHeight;
            // 创建大图结构
            var str = '<div class="cloudzoom-big" +bigWidth+'px;height:'+bigHeight+'px;left:'+bigoffsetLeft+'px;top:'+bigoffsetTop+'px">'+
            '  <img src="'+bigImgSrc+'" + smallImgWidth * scale+'px;height:'+smallImgHeight * scale+'px;"/>'+
            '</div>';
  
            // 如果存在了,先把存在的删除掉,循环调用cloudzoom插件的时候会出现这个问题
            if ($('.cloudzoom-big',this.$el).length >=1 ) {
              $('.cloudzoom-big',this.$el).remove();
            }
            // 插入大图布局
            this.$el.append(str);
            this.$big = this.$el.find('.cloudzoom-big');
            this.$bigImg = this.$big.find('img');
          },
          // 显示元素
          'showEl': function(el) {
            el.css('display','block');
          },
          // 隐藏元素
          'hiddenEl': function(el) {
            el.css('display','none');
          },
          // 鼠标进入small
          'smallEnter': function(){
            // 绑定this指向
            var _this = this;
            // 鼠标移入小图
            this.$small.on('mouseenter', function(){
              // 显示shadow
              _this.showEl(_this.$shadow);
              // 显示big
              _this.showEl(_this.$big);
              // 隐藏zoomIcon
              _this.hiddenEl(_this.$zoomIcon);
            });
          },
          // 鼠标移出small
          'smallLeave': function(){
            // 绑定this指向
            var _this = this;
  
            // 鼠标移出小图
            this.$small.on('mouseleave', function(){
              // 显示zoomIcon
              _this.showEl(_this.$zoomIcon);
              // 隐藏shadow
              _this.hiddenEl(_this.$shadow);
              // 隐藏big
              _this.hiddenEl(_this.$big);
            });
          },
          // 鼠标在小图内移动
          'smallmove': function(){
            // 绑定this指向
            var _this = this;
  
            this.$small.on('mousemove',function(){
              var l = event.pageX - $(this).offset().left - _this.$shadow.width()/2;
              var t = event.pageY - $(this).offset().top - _this.$shadow.height()/2;
              var bigl = 0;
              var bigt = 0;
              // 防止遮罩超出左边,到0不继续偏移
              if(l<0){
                l=0;
              }
              // 防止遮罩超出右边,到可视区-遮罩宽度范围不继续偏移
              if(l>$(this).width() - _this.$shadow.width()){
                l=$(this).width() - _this.$shadow.width();
              }
              // 防止遮罩超出上边,到0不继续偏移
              if(t<0){
                t=0;
              }
              // 防止遮罩超出下边,到可视区-遮罩高度范围不继续偏移
              if(t>$(this).height() - _this.$shadow.height()){
                t=$(this).height() - _this.$shadow.height();
              }
        
              // 移动遮罩
              // _this.$shadow.css({left:l,top:t});
              _this.$shadow.css({transform: 'translate('+l+'px, '+t+'px)'});
              
        
              // 计算大图偏移量,用小图的偏移量比上小图的可视区宽度等于大图的偏移量比上大图尺寸,计算得出
              bigl = -l*(_this.$bigImg.width()-_this.$big.width())/(_this.$small.width()-_this.$shadow.width())+'px'
              bigt = -t*(_this.$bigImg.height()-_this.$big.height())/(_this.$small.height()-_this.$shadow.height())+'px';
        
              // 移动大图
              // _this.$bigImg.css({left:bigl,top:bigt});
              _this.$bigImg.css({transform: 'translate('+bigl+', '+bigt+')'});
        
            });
          },
          // small事件
          'smallFn': function () {
            // 绑定this指向
            var _this = this;
            // 调用鼠标移入小图函数
            this.smallEnter();
            
            // 调用鼠标移出小图函数
            this.smallLeave();
            
            // 调用鼠标在小图内移动函数
            this.smallmove();
          }
        };
        // 初始化插件
        cloudzoom.init();
      });
      
    }
  });
})(window,jQuery);

案例html布局

<!DOCTYPE html>
<html>
<head >
    <meta charset="UTF-8">
    <title></title>
    <style>    
      *{ margin:0; padding:0;}
      .contain{
          width:80%;
          height:500px;
          margin:0 auto;
      }
      .left{
          float:left;
      }
      .up{
          width:320px;
          height:200px;
          padding:30px;
      }
      /* .up{
          width:32em;
          height:20em;
          padding:3em;
      } */
      .down{
          padding:20px;
          padding-left:35px;
      }
      .down img{
          width:64px;
          height:40px;
          border:3px solid #ccc;
      }
      .down img.tab-active{
          width:64px;
          height:40px;
          border:3px solid #e60000;
      }

      .cloudzoom{
        position: relative;
      }
      .cloudzoom .cloudzoom-small{
        position: relative;
        cursor: move;
      }
      .cloudzoom .cloudzoom-small,.cloudzoom .cloudzoom-small img{
        width: 100%;
        height: 100%;
      }
      .cloudzoom .cloudzoom-small img{
        display: block;
      }
      .cloudzoom .cloudzoom-shadow{
        width: 200px;
        height: 200px;
        background: #ff0202;
        position: absolute;
        left:0;
        top:0;
        opacity: 0.4;
        filter:alpha(opacity:40);
        display: none;
      }
      .cloudzoom .cloudzoom-zoom-icon {
        height: 40px;
        width: 40px;
        color: #ccc;
        z-index: 2;
        position: absolute;
        right: 0;
        bottom: 0;
        text-align: center;
        cursor: default;
        background: url(./images/zoom-icon.png) center  no-repeat rgba(255, 255, 255, .3);
        background-size: 20px;
      }
    </style>
    <script src="./js/jquery-1.11.3.min.js"></script>
    <script src="./js/myjQuery/jquery.tab.js"></script>
    <script src="./js/jquery.cloudzoom.js"></script>
</head>
<body>
  <div class="contain tab1 tab">
    <div class="left">
      <div class="up">
        <div class="cloudzoom j-cloudzoom j-cloudzoom1">
          <div class="cloudzoom-small">
            <img src="./images/jd1.jpg" class="cloudzoom-small-img">
          </div>
        </div>
      </div>
      <div class="down">
          <img src="./images/jd1.jpg">
          <img src="./images/jd2.jpg">
          <img src="./images/jd3.jpg">
          <img src="./images/jd4.jpg">
      </div>
    </div>
  </div>
  <p>文字</p>
  
  <div class="contain tab2 tab">
    <div class="left">
      <div class="up">
        <div class="cloudzoom j-cloudzoom j-cloudzoom2">
          <div class="cloudzoom-small">
            <img src="./images/jd1.jpg" class="cloudzoom-small-img">
          </div>
        </div>
      </div>
      <div class="down">
          <img src="./images/jd5.jpg">
          <img src="./images/jd6.jpg">
          <img src="./images/jd3.jpg">
      </div>
    </div>
  </div>
  <script>

    $(function () {
      
      $('.tab').tab({'btn':'.down img',callback:function(){
        var str = $(this)[0].$tab.eq($(this)[0].index).attr('src');
        $(this)[0].$el.find('.cloudzoom-small-img').attr('src',str);
        $('.j-cloudzoom').cloudzoom();
      }});
      $('.j-cloudzoom').cloudzoom();
      // console.log($('.j-cloudzoom'));
      
    });

  </script>
</body>
</html>

插件使用方法

在页面中引入jquery和jquery.cloudzoom.js文件(根据项目目录引入必要文件)。


    <script src="./js/jquery-1.11.3.min.js"></script>
    <script src="./js/jquery.cloudzoom.js"></script>

HTML结构


<div class="cloudzoom j-cloudzoom j-cloudzoom1">
     <div class="cloudzoom-small">
         <img src="./images/jd1.jpg" class="cloudzoom-small-img">
     </div>
</div>

初始化插件

在页面DOM元素加载完毕之后,通过cloudzoom()方法来初始化该插件。

$('.j-cloudzoom').cloudzoom();

插件配置参数

  • smallEl : 存放缩略图的元素,不能省略jq获取元素时候的#、. ,默认值:.cloudzoom-small
  • bigWidth : 大图盒子可视窗口宽度,不带单位的number,传值不能转换成数字,会被强制改成默认值,不传参数,默认就是小图的尺寸,默认值: 0
  • bigHeight : 大图盒子可视窗口高度,不带单位的number,传值不能转换成数字,会被强制改成默认值,不传参数,默认就是小图的尺寸,默认值: 0
  • bigoffsetTop : 大图盒子的距离顶部偏移位置,不带单位的number,传值不能转换成数字,会被强制改成默认值 ,默认值: 0
  • bigoffsetLeft : 大图盒子的距离左侧偏移位置,不带单位的number,传值不能转换成数字,会被强制改成默认值,默认值: 0
  • scale : 设置小图放大倍数后的数值给大图用,不带单位的number,传值不能转换成数字,会被强制改成默认值,默认值: 2