简体   繁体   中英

Custom plugin to move image around not moving image when src changed

I have created a jQuery plugin that has a plus/minus button to zoom into/out of an image, and allows the user to drag/move the image around within its container.

Snippet contains entire plugin code and minimum required html/css to recreate issue:

 /*! * jQuery Image Zoom v1 * http://richard.parnaby-king.co.uk * https://github.com/richard-parnaby-king/jQuery-Image-Zoom */ //////////////////// Plugin ///////////////////// ;( function ( $, window, document, undefined ) { var pluginName = 'imageZoom', options = { scaleAmount:1.2, //(float) amount to zoom in / out by zoomInText:'+', //(string) Text to show in span for zoom in button zoomOutText:'-' //(string) Text to show in span for zoom out button }; function ImageZoom( element, opts ) { this.element = element; this._name = pluginName; options = $.extend( {}, options, opts ); //local variables var link = this.element.find('a'), bigImage = link.attr('href'), image = this.element.find('img'), currentScale = 1, mouseDown = false, ix = 0, iy = 0, sWidth,sHeight; this.image = image; this.link = link; link.on('click.' + pluginName, function(e){e.preventDefault();}); this.element.addClass('imageZoom-holder'); image.on('load',function(){ image.css({ '-webkit-transform' : 'scale(1)', '-moz-transform' : 'scale(1)', '-ms-transform' : 'scale(1)', '-o-transform' : 'scale(1)', 'transform' : 'scale(1)', 'top' : '0', 'left' : '0' }); sWidth = image.width(); sHeight = image.height(); image.attr('src',bigImage); image.width(sWidth); image.height(sHeight); }); //add buttons to image this.element.append('<div class="imageZoom-buttons"><span class="zoomInButton" unselectable="on">'+options.zoomInText+'</span><span class="zoomOutButton" unselectable="on">'+options.zoomOutText+'</span></div>'); var buttons = this.element.find('.imageZoom-buttons'); //when click on zoom in/out buttons, scale image accordingly buttons.find('.zoomInButton').on('click.' + pluginName,function(){ currentScale *= options.scaleAmount; image.css({ '-webkit-transform' : 'scale(' + currentScale + ')', '-moz-transform' : 'scale(' + currentScale + ')', '-ms-transform' : 'scale(' + currentScale + ')', '-o-transform' : 'scale(' + currentScale + ')', 'transform' : 'scale(' + currentScale + ')' }); }); buttons.find('.zoomOutButton').on('click.' + pluginName,function(){ //make image smaller, but do not allow image to be made smaller than original size if(currentScale > 1) { currentScale /= options.scaleAmount; image.css({ '-webkit-transform' : 'scale(' + currentScale + ')', '-moz-transform' : 'scale(' + currentScale + ')', '-ms-transform' : 'scale(' + currentScale + ')', '-o-transform' : 'scale(' + currentScale + ')', 'transform' : 'scale(' + currentScale + ')' }); } else { //if image is original size, position image back into centre image.css({'left':0,'top':0}); } }); this.buttons = buttons; //when click/drag on image, move image image.on('mousedown.' + pluginName + ' touchstart.' + pluginName,function(e){ ix = e.pageY, iy = e.pageX; if(e.originalEvent instanceof TouchEvent) { ix = e.originalEvent.touches[0].pageX; iy = e.originalEvent.touches[0].pageY; } mouseDown = true; return false; }); image.on('mouseup.' + pluginName + ' touchend.' + pluginName + ' touchcancel.' + pluginName,function(e){ mouseDown = false; }); image.on('mousemove.' + pluginName + ' touchmove.' + pluginName,function(e){ if(e.originalEvent instanceof TouchEvent) { e.pageX = e.originalEvent.touches[0].pageX; e.pageY = e.originalEvent.touches[0].pageY; } if(mouseDown == true) { var offsetLeft = parseInt( image.css('left').replace(/[^0-9\\.\\-]+/,'') |0 ) - ( iy - e.pageX ), offsetTop = parseInt( image.css('top').replace(/[^0-9\\.\\-]+/,'') |0 ) - ( ix - e.pageY ); //move image image.css( 'left', offsetLeft ); image.css( 'top', offsetTop ); iy = e.pageX; ix = e.pageY; } }); }; ImageZoom.prototype.destroy = function(){ this.image.off('.' + pluginName); this.buttons.off('.' + pluginName); this.element.find('.imageZoom-buttons').remove(); this.element.removeData(); }; $.fn[pluginName] = function( options ){ return this.each( function() { if( !$.data( this, pluginName )) { $.data( this, pluginName, new ImageZoom ( $(this), options )); } }); } } )( jQuery, window, document ); /////////////// End Plugin //////////////////// $(document).ready(function(){ $('.main').imageZoom(); $('.extra a').on('click',function(e){ e.preventDefault(); var image = $('.main'), $this = $(this); image.data('imageZoom').destroy(); image.find('a').attr('href',$this.attr('href')).find('img').attr('src',$this.attr('href')); image.imageZoom(); }); }); 
 div.main { width:300px; height:200px; } .imageZoom-holder { overflow:hidden; position:relative; } .imageZoom-holder .imageZoom-buttons { position:absolute; top:0; left:0; } .imageZoom-holder .imageZoom-buttons span { display:inline-block; padding:1em; cursor:pointer; font-size:1em; color:#000; background:#fff; border:1px solid #d0d0d0; } .imageZoom-holder img { -webkit-transition:-webkit-transform 0.3s linear; -moz-transition:-moz-transform 0.3s linear; -ms-transition:-ms-transform 0.3s linear; -o-transition:-o-transform 0.3s linear; transition:transform 0.3s linear; position:relative; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <div class="main"> <a href="http://dummyimage.com/600x400/000/fff"> <img src="http://dummyimage.com/300x200/000/fff"> </a> </div> <div class="extra"> <a href="http://dummyimage.com/600x400/b806b8/ffffff&text=1"><img src="http://dummyimage.com/150x100/b806b8/ffffff&text=1"></a> <a href="http://dummyimage.com/600x400/ffffff/111111&text=2"><img src="http://dummyimage.com/150x100/ffffff/111111&text=2"></a> </div> 

My issue is that when I change the image (click on one of the small thumbnails under the main image), the src of the image is changed, but the move feature stops working - the image will jutter around a little bit, but fundamentally does not move position.

What part of my plugin is causing the image to not move?

The problem is in:

image.on('load',function(){
    image.css({ 
        ...
    });
    ...
}); 

This function is called infinitely. I think it's because in this function you modify src attribute of the image and the load event fires again.

image.on('load',function(){
    console.log('Hi!!');
    image.css({
        '-webkit-transform' : 'scale(1)',
        '-moz-transform'    : 'scale(1)',
        '-ms-transform'     : 'scale(1)',
        '-o-transform'      : 'scale(1)',
        'transform'         : 'scale(1)',
        'top'               : '0',
        'left'              : '0'
    });
    sWidth = image.width();
    sHeight = image.height();
    image.attr('src',bigImage);  
    image.width(sWidth);
    image.height(sHeight);
});

I don't know why you attach this code to load event. I think it should be executed every time the image changes and ImageZoom is called. It works ok if you don't attach it:

// image.on('load',function(){
    image.css({
        '-webkit-transform' : 'scale(1)',
        '-moz-transform'    : 'scale(1)',
        '-ms-transform'     : 'scale(1)',
        '-o-transform'      : 'scale(1)',
        'transform'         : 'scale(1)',
        'top'               : '0',
        'left'              : '0'
    });
    sWidth = image.width();
    sHeight = image.height();
    image.attr('src',bigImage);
    image.width(sWidth);
    image.height(sHeight);
// });

JSFiddle

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM