圖片放大功能插件及jquery.extend函數理解

前端時間,產品提出社區評論中的圖片須要有放大功能。感受能夠共用,因此就想整合一個插件,過程當中也借鑑了一些例子css

分析下本身的代碼思路:html

var scaleImg = function(opts) {
    this.opts = $.extend({
        wrap: '', 
        clickimgs: '', 
        callback: function(){}
    }, opts);
        
    this.images_n = []; //保存一條評論中的全部圖片
    this.$showArrow = false; //顯示左右翻頁按鈕 
    this.$image = new Image(); //新的image對象,用於大圖展現
    this.now_page = 0; //翻頁索引
    this.init();
};

定義該插件名稱,及其裏面的變量和方法。前端

scaleImg.prototype = {
    init: function() {
        this.createDom();
        this.bindEvt();
    },
    createDom: function() {
        var _html = [];
        _html.push('<div class="scaleImg_box zoom">');
        _html.push('<div class="zoom_content"> ');
        _html.push('</div>');
        _html.push('</div>');

        this.opts.wrap = $('body');
        this.$wrap= $(this.opts.wrap);
        this.$wrap.append(_html.join(''));
        this.zoom = this.$wrap.find('.zoom');
    },

    bindEvt: function() {
        var self = this;

        $(self.opts.clickimgs).on('click' , '.img_mask', function() {
            var $this = $(this).prev('img');
            self.nextPic($this);
       });

        self.$wrap.on('click', function() {
            self.zoom.hide();
            $('body').css('overflow', 'auto');
        });

        //右翻頁
        this.$wrap.on('click', '.zoom_right', function(event) {
            var number = $(this).data('num');
            if(number+1 <= self.images_n.length - 1) {
                self.nextPic($(self.images_n[number+1]));
            }
            event.stopPropagation();
        });

        //左翻頁
        this.$wrap.on('click', '.zoom_left', function(event) {
            var number = $(this).data('num');
            if(number > 0 ) {
                self.nextPic($(self.images_n[number-1]));
            }
            event.stopPropagation();
        });
    },
   //處理左右翻頁來源
    nextPic: function($this) {
        var self = this;
        self.now_page = 0;
        self.images_n = [];
        var sibParentImg = $this.parent().parent().find('img');
        for(var i = 0; i < sibParentImg.length; i++) {
            if($(sibParentImg[i]).attr('src') == $this.attr('src')) {
                self.now_page = i;
            }
            self.images_n.push(sibParentImg[i]);
        }
        if(self.images_n.length > 1) {
            self.$showArrow = true;
        } else {
            self.$showArrow = false;
        }

        var src = $this.attr('src');
        if(src.indexOf('?') != -1) {
            src = src.substring(0, src.indexOf('?'));
        }
        self.limitPic(src);
    },
  //處理圖片的大小
    limitPic: function(src) {
        var self = this;
        $image = self.$image;
        $image.src = src;
        $image.onload = function() {
            var w = $image.width;
            var h = $image.height;
            var height = (window.document.documentElement.clientHeight || window.document.body.clientHeight) - 100;
            var width = (window.document.documentElement.clientWidth || window.document.body.clientWidth) - 100;

            if(w < width) { //若圖片的寬度小於屏幕的寬度,則以實際寬度爲準
                width = w;
            }
            if(h < height) { //同以上
                height = h;
            }
            self.showBigPic(src, width, height);
        }
    },
  //顯示大圖
    showBigPic: function(thisImg, width, height) {
        var self = this;
        var zoom_content = self.$wrap.find('.zoom_content');
        zoom_content.html('');
        var close = '<div class="dialog_close"></div>';
        zoom_content.append(close);
        zoom_content.append('<div class="img_con"><img src=' + thisImg + '></div>');
        zoom_content.animate({
          width: width + 80 + 'px',
          marginLeft: -(width/2) + 'px',
          marginTop: -(height/2) + 'px'
        }, 0, null, function() {
            if(self.$showArrow) {
                var arrow_html = [];
                    arrow_html.push('<div class="zoom_arrow zoom_left" data-num='+self.now_page+'><div>');
                    arrow_html.push('</div></div>');
                    arrow_html.push('<div class="zoom_arrow zoom_right" data-num='+self.now_page+'><div>');
                    arrow_html.push('</div></div>');
                zoom_content.append(arrow_html);
                var arrow = self.$wrap.find('.zoom_arrow');
                arrow.show();
            }
            self.zoom.html(zoom_content);
            $('body').css('overflow', 'hidden');
            self.zoom.show();
        });
    }
}
View Code

上述爲實現該插件的具體方法。jquery

插件中用到的知識:ajax

1)jquery.extend

一 .jquery.extend 函數詳解  來源app

該方法是在寫插件的過程當中常常用到的方法。ide

①jQuery的擴展方法原型是:wordpress

extend(dest,src1,src2,src3...);函數

它的含義是將src1,src2,src3...合併到dest中,返回值爲合併後的dest,由此能夠看出該方法合併後,是修改了dest的結構的。若是想要獲得合併的結果卻又不想修改dest的結構,能夠以下使用:ui

  var newSrc=$.extend({},src1,src2,src3...)//也就是將"{}"做爲dest參數。

 這樣就能夠將src1,src2,src3...進行合併,而後將合併結果返回給newSrc了。以下例:

 那麼合併後的結果:

 也就是說後面的參數若是和前面的參數存在相同的名稱,那麼後面的會覆蓋前面的參數值。

2、省略dest參數 參考  參考2

將參數省略,該方法就只能有一個src參數,並且是將該src合併到調用extend方法的對象中去,如:

一、$.extend(src)

將src擴展到$(jquery)全局對象中。你能夠理解爲拓展jquery類,最明顯的例子是$.ajax(...),至關於靜態方法。看下例子:

在google的console中執行上面代碼,並查看 $(jQuery) 能夠看出:

開發擴展其方法時使用$.extend方法,即jQuery.extend(object);
$.extend({
  add:function(a,b){return a+b;} ,
  minus:function(a,b){return a-b;}
});

var i = $.add(3,2);
var j = $.minus(3,2);

二、$.fn.extend(src)

$.fn.extend(src1)會將src1擴張到$(jquery)實例對象中,能夠理解爲基於對象的拓展,如$("#table").changeColor(...); 這裏這個changeColor呢,就是基於對象的拓展了。看下具體的輸出:

開發擴展其方法時使用$.fn.extend方法,即jQuery.fn.extend(object);
$.fn.extend({
  check:function(){
    return this.each({
    this.checked=true;
  });
  },
  uncheck:function(){
    return this.each({
    this.checked=false;
  });
  }
});

$('input[type=checkbox]').check();
$('input[type=checkbox]').uncheck();

3、Jquery的extend方法還有一個重載原型:  

extend(boolean,dest,src1,src2,src3...)

第一個參數boolean表明是否進行深度拷貝,其他參數和前面介紹的一致,什麼叫深層拷貝,咱們看一個例子:

咱們能夠看出src1中嵌套子對象location:{city:"Boston"}, src2中也嵌套子對象location:{state:"MA"}, 第一個深度拷貝參數爲true,那麼合併後的結果就是: 

 

也就是說它會將src中的嵌套子對象也進行合併,而若是第一個參數boolean爲false,咱們看看合併的結果是什麼,以下:

那麼合併後的結果就是:

實驗過程當中我想到,第一個參數不填會是神馬結果,和第一個例子好像有相同之處,因而試驗一番: 

注意到:extend(boolean,dest,src1,src2,src3...),boolen這個參數只是決定src1,src2...中嵌套的子對象是否合併,並不影響src1,src2...之間的合併,也就是說:src1中的namesrc2中的last最後都出如今合併的result中。

原本還想繼續分析jQuery.prototype ,感受篇幅有點長,留給下一篇。。。

相關文章
相關標籤/搜索