1
對不起,如果這是混亂。我爲我正在處理的頁面合併了Automatic Image Montage jQuery插件,並且似乎打破了在窗口大小調整事件時自動調整圖像大小的功能。關於該插件的其他一切正在按照應有的方式工作。我究竟做錯了什麼?我如何打破自動圖像蒙太奇jQuery插件的自動調整大小功能?
我很不熟悉jQuery和Javascript,但只修改了插件的js文件中的一些最大/最小圖像大小選項。似乎與這個問題有關的js文件中的內部引用是'smartresize'。如果你不想從上面的鏈接下載演示,我已經在下面包含了js文件的縮小版。首先,我的相關CSS和HTML如下:
CSS
/*=========================automontage==============================*/
.am-container {
margin-top:75px;
}
.am-wrapper{
float:left;
position:relative;
overflow:hidden;
}
.am-wrapper img{
position:absolute;
outline:none;
}
/*=========================automontage==============================*/
HTML
<div class="am-container" id="am-container">
<a href="#="asdf"><img src="img/265_s.jpg"></img></a>
<a href="#" title="asdf"><img src="img/mont1_cloud_s.jpg"></img></a>
<a href="#" title="asdf"><img src="img/san_diego_street.jpg"></img></a>
<a href="#" title="asdf"><img src="img/IMG_8576_s.jpg"></img></a>
<a href="#" title="asdf"><img src="img/IMG_9827_1_s.jpg"></img></a>
<a href="#" title="asdf"><img src="img/IMG_0999_s.jpg"></img></a>
<a href="#" title="asdf"><img src="img/Lake_pano_11.jpg"></img></a>
<a href="#" title="asdf"><img src="img/IMG_8967_s.jpg"></img></a>
<a href="#" title="asdf"><img src="img/IMG_1346_s.jpg"></img></a>
<a href="#" title="asdf"><img src="img/IMG_2450.jpg"></img></a>
</div>
在HTML腳本
<script type="text/javascript" src="js/jquery.montage.min.js"></script>
<script type="text/javascript">
/*automontage*/
$(function() {
var $container = $('#am-container'),
$imgs = $container.find('img').hide(),
totalImgs = $imgs.length,
cnt = 0;
$imgs.each(function(i) {
var $img = $(this);
$('<img/>').load(function() {
++cnt;
if(cnt === totalImgs) {
$imgs.show();
$container.montage({
fillLastRow : true,
alternateHeight : true,
alternateHeightRange : {
min : 150,
max : 350
}
});
}
}).attr('src',$img.attr('src'));
});
});
</script>
jQuery插件文件代碼(DE-精縮)
/**
* jQuery Montage plugin
* http://www.codrops.com/
*
* Copyright 2011, Pedro Botelho
* Licensed under the MIT license.
* http://www.opensource.org/licenses/mit-license.php
*
* Date: Tue Aug 30 2011
*/
(function(window, $, undefined) {
\t
\t /*
\t * Array.max, Array.min
\t * @John Resig
\t * http://ejohn.org/blog/fast-javascript-maxmin/
\t */
\t
\t // function to get the Max value in array
Array.max \t \t \t \t \t = function(array){
return Math.max.apply(Math, array);
};
// function to get the Min value in array
Array.min \t \t \t \t \t = function(array){
return Math.min.apply(Math, array);
};
\t
\t /*
\t * smartresize: debounced resize event for jQuery
\t *
\t * latest version and complete README available on Github:
\t * https://github.com/louisremi/jquery.smartresize.js
\t *
\t * Copyright 2011 @louis_remi
\t * Licensed under the MIT license.
\t */
\t var $event = $.event, resizeTimeout;
\t $event.special.smartresize \t = {
\t \t setup: function() {
\t \t \t $(this).bind("resize", $event.special.smartresize.handler);
\t \t },
\t \t teardown: function() {
\t \t \t $(this).unbind("resize", $event.special.smartresize.handler);
\t \t },
\t \t handler: function(event, execAsap) {
\t \t \t // Save the context
\t \t \t var context = this,
\t \t \t \t args \t = arguments;
\t \t \t // set correct event type
\t \t \t event.type = "smartresize";
\t \t \t if (resizeTimeout) { clearTimeout(resizeTimeout); }
\t \t \t resizeTimeout = setTimeout(function() {
\t \t \t \t jQuery.event.handle.apply(context, args);
\t \t \t }, execAsap === "execAsap"? 0 : 50);
\t \t }
\t };
\t $.fn.smartresize \t \t \t = function(fn) {
\t \t return fn ? this.bind("smartresize", fn) : this.trigger("smartresize", ["execAsap"]);
\t };
\t
\t // ======================= imagesLoaded Plugin ===============================
\t // https://github.com/desandro/imagesloaded
\t // $('#my-container').imagesLoaded(myFunction)
\t // execute a callback when all images have loaded.
\t // needed because .load() doesn't work on cached images
\t // callback function gets image collection as argument
\t // `this` is the container
\t // original: mit license. paul irish. 2010.
\t // contributors: Oren Solomianik, David DeSandro, Yiannis Chatzikonstantinou
\t $.fn.imagesLoaded \t \t \t = function(callback) {
\t \t var $images = this.find('img'),
\t \t \t len \t = $images.length,
\t \t \t _this \t = this,
\t \t \t blank \t = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==';
\t \t function triggerCallback() {
\t \t \t callback.call(_this, $images);
\t \t }
\t \t function imgLoaded() {
\t \t \t if (--len <= 0 && this.src !== blank){
\t \t \t \t setTimeout(triggerCallback);
\t \t \t \t $images.unbind('load error', imgLoaded);
\t \t \t }
\t \t }
\t \t if (!len) {
\t \t triggerCallback();
\t \t }
\t \t $images.bind('load error', imgLoaded).each(function() {
\t \t // cached images don't fire load sometimes, so we reset src.
\t \t if (this.complete || this.complete === undefined){
\t \t \t \t var src = this.src;
\t \t \t \t // webkit hack from http://groups.google.com/group/jquery-dev/browse_thread/thread/eee6ab7b2da50e1f
\t \t \t \t // data uri bypasses webkit log warning (thx doug jones)
\t \t \t \t this.src = blank;
\t \t \t \t this.src = src;
\t \t }
\t \t });
\t \t return this;
\t }; \t
\t
\t $.Montage \t \t \t \t \t = function(options, element) {
\t \t this.element \t = $(element).show();
\t \t this.cache \t \t = {};
\t \t this.heights \t = new Array();
\t \t this._create(options);
\t };
\t
\t $.Montage.defaults \t \t \t = {
\t \t liquid \t \t \t \t \t : true, // if you use percentages (or no width at all) for the container's width, then set this to true
\t \t \t \t \t \t \t \t \t \t // this will set the body's overflow-y to scroll (fix for the scrollbar's width problem)
\t \t margin \t \t \t \t \t : 1, \t // space between images.
\t \t minw \t \t \t \t \t : 70, \t // the minimum width that a picture should have.
\t \t minh \t \t \t \t \t : 20, \t // the minimum height that a picture should have.
\t \t maxh \t \t \t \t \t : 250, \t // the maximum height that a picture should have.
\t \t alternateHeight \t \t \t : false,// alternate the height value for every row. If true this has priority over defaults.fixedHeight.
\t \t alternateHeightRange \t : { \t \t // the height will be a random value between min and max.
\t \t \t min \t : 100,
\t \t \t max \t : 300
\t \t },
\t \t fixedHeight \t \t \t \t : null, \t // if the value is set this has priority over defaults.minsize. All images will have this height.
\t \t minsize \t \t \t \t \t : false,// minw,minh are irrelevant. Chosen height is the minimum one available.
\t \t fillLastRow \t \t \t \t : false \t // if true, there will be no gaps in the container. The last image will fill any white space available
};
\t
\t $.Montage.prototype \t \t = {
\t \t _getImageWidth \t \t : function($img, h) {
\t \t \t var i_w \t = $img.width(), \t i_h \t = $img.height(), r_i = i_h/i_w;
\t \t \t return Math.ceil(h/r_i);
\t \t },
\t \t _getImageHeight \t \t : function($img, w) {
\t \t \t var i_w = $img.width(), i_h = $img.height(), r_i = i_h/i_w;
\t \t \t return Math.ceil(r_i * w);
\t \t },
\t \t _chooseHeight \t \t : function() {
\t \t \t // get the minimum height
\t \t \t if(this.options.minsize) {
\t \t \t \t return Array.min(this.heights);
\t \t \t }
\t \t \t // otherwise get the most repeated heights. From those choose the minimum.
\t \t \t var result \t = {},
\t \t \t \t max \t = 0,
\t \t \t \t res, val, min;
\t \t \t \t
\t \t \t for(var i = 0, total = this.heights.length; i < total; ++i) {
\t \t \t \t var val \t = this.heights[i], inc = (result[val] || 0) + 1;
\t \t \t \t
\t \t \t \t if(val < this.options.minh || val > this.options.maxh) continue;
\t \t \t \t
\t \t \t \t result[val] = inc;
\t \t \t \t
\t \t \t \t if(inc >= max) {
\t \t \t \t \t max = inc; res = val;
\t \t \t \t }
\t \t \t }
\t \t \t for (var i in result) {
\t \t \t \t if (result[i] === max) {
\t \t \t \t \t val = i;
\t \t \t \t \t min = min || val;
\t \t \t \t \t
\t \t \t \t \t if(min < this.options.minh)
\t \t \t \t \t \t min = null;
\t \t \t \t \t else if (min > val)
\t \t \t \t \t \t min = val;
\t \t \t \t \t if(min === null)
\t \t \t \t \t \t min = val;
\t \t \t \t }
\t \t \t }
\t \t \t if(min === undefined) min = this.heights[0];
\t \t \t
\t \t \t res = min;
\t \t \t
\t \t \t return res;
\t \t },
\t \t _stretchImage \t \t : function($img) {
\t \t \t var prevWrapper_w \t = $img.parent().width(),
\t \t \t \t new_w \t \t \t = prevWrapper_w + this.cache.space_w_left,
\t \t \t \t crop \t \t \t = {
\t \t \t \t \t x \t : new_w,
\t \t \t \t \t y \t : this.theHeight
\t \t \t \t };
\t \t \t
\t \t \t var new_image_w \t \t = $img.width() + this.cache.space_w_left,
\t \t \t \t new_image_h \t \t = this._getImageHeight($img, new_image_w);
\t \t \t
\t \t \t this._cropImage($img, new_image_w, new_image_h, crop);
\t \t \t this.cache.space_w_left = this.cache.container_w;
\t \t \t // if this.options.alternateHeight is true, change row/change height
\t \t \t if(this.options.alternateHeight) \t
\t \t \t \t this.theHeight \t \t \t = Math.floor(Math.random()*(this.options.alternateHeightRange.max - this.options.alternateHeightRange.min + 1) + this.options.alternateHeightRange.min); \t \t
\t \t },
\t \t _updatePrevImage \t : function($nextimg) {
\t \t \t var $prevImage \t \t = this.element.find('img.montage:last');
\t \t \t
\t \t \t this._stretchImage($prevImage);
\t \t \t
\t \t \t this._insertImage($nextimg);
\t \t },
\t \t _insertImage \t \t : function($img) {
\t \t \t // width the image should have with height = this.theHeight.
\t \t \t var new_w = this._getImageWidth($img, this.theHeight);
\t \t \t
\t \t \t // use the minimum height available if this.options.minsize = true.
\t \t \t if(this.options.minsize && !this.options.alternateHeight) {
\t \t \t \t if(this.cache.space_w_left <= this.options.margin * 2) {
\t \t \t \t \t this._updatePrevImage($img);
\t \t \t \t }
\t \t \t \t else {
\t \t \t \t \t if(new_w > this.cache.space_w_left) {
\t \t \t \t \t \t var crop = { x : this.cache.space_w_left, y : this.theHeight };
\t \t \t \t \t \t this._cropImage($img, new_w, this.theHeight, crop);
\t \t \t \t \t \t this.cache.space_w_left = this.cache.container_w;
\t \t \t \t \t \t $img.addClass('montage');
\t \t \t \t \t } \t
\t \t \t \t \t else {
\t \t \t \t \t \t var crop = { x \t : new_w, y : this.theHeight };
\t \t \t \t \t \t this._cropImage($img, new_w, this.theHeight, crop);
\t \t \t \t \t \t this.cache.space_w_left -= new_w;
\t \t \t \t \t \t $img.addClass('montage');
\t \t \t \t \t }
\t \t \t \t } \t
\t \t \t }
\t \t \t else {
\t \t \t \t // the width is lower than the minimum width allowed.
\t \t \t \t if(new_w < this.options.minw) {
\t \t \t \t \t // the minimum width allowed is higher than the space left to fill the row.
\t \t \t \t \t // need to resize the previous (last) item in that row.
\t \t \t \t \t if(this.options.minw > this.cache.space_w_left) {
\t \t \t \t \t \t this._updatePrevImage($img);
\t \t \t \t \t }
\t \t \t \t \t else {
\t \t \t \t \t \t var new_w = this.options.minw, new_h = this._getImageHeight($img, new_w), crop = { x : new_w, y : this.theHeight };
\t \t \t \t \t \t this._cropImage($img, new_w, new_h, crop);
\t \t \t \t \t \t this.cache.space_w_left -= new_w;
\t \t \t \t \t \t $img.addClass('montage');
\t \t \t \t \t }
\t \t \t \t }
\t \t \t \t else {
\t \t \t \t \t // the new width is higher than the space left but the space left is lower than the minimum width allowed.
\t \t \t \t \t // need to resize the previous (last) item in that row.
\t \t \t \t \t if(new_w > this.cache.space_w_left && this.cache.space_w_left < this.options.minw) {
\t \t \t \t \t \t this._updatePrevImage($img);
\t \t \t \t \t } \t
\t \t \t \t \t else if(new_w > this.cache.space_w_left && this.cache.space_w_left >= this.options.minw) {
\t \t \t \t \t \t var crop = {x : this.cache.space_w_left, y : this.theHeight};
\t \t \t \t \t \t this._cropImage($img, new_w, this.theHeight, crop);
\t \t \t \t \t \t this.cache.space_w_left = this.cache.container_w;
\t \t \t \t \t \t // if this.options.alternateHeight is true, change row/change height
\t \t \t \t \t \t if(this.options.alternateHeight)
\t \t \t \t \t \t \t this.theHeight \t = Math.floor(Math.random()*(this.options.alternateHeightRange.max - this.options.alternateHeightRange.min + 1) + this.options.alternateHeightRange.min);
\t \t \t \t \t \t $img.addClass('montage');
\t \t \t \t \t } \t
\t \t \t \t \t else {
\t \t \t \t \t \t var crop = { x : new_w, y : this.theHeight};
\t \t \t \t \t \t this._cropImage($img, new_w, this.theHeight, crop);
\t \t \t \t \t \t this.cache.space_w_left -= new_w;
\t \t \t \t \t \t $img.addClass('montage');
\t \t \t \t \t } \t
\t \t \t \t }
\t \t \t }
\t \t },
\t \t _cropImage \t \t \t : function($img, w, h, cropParam) {
\t \t \t // margin value
\t \t \t var dec = this.options.margin * 2;
\t \t \t
\t \t \t var $wrapper \t = $img.parent('a');
\t \t \t
\t \t \t // resize the image
\t \t \t this._resizeImage($img, w, h);
\t \t \t
\t \t \t // adjust the top/left values to slice the image without loosing the its ratio
\t \t \t $img.css({
\t \t \t \t left \t : - (w - cropParam.x)/2 + 'px',
\t \t \t \t top \t \t : - (h - cropParam.y)/2 + 'px'
\t \t \t }); \t
\t \t \t
\t \t \t // wrap the image in a <a> element
\t \t \t $wrapper.addClass('am-wrapper').css({
\t \t \t \t width \t : cropParam.x - dec + 'px',
\t \t \t \t height \t : cropParam.y + 'px',
\t \t \t \t margin : this.options.margin
\t \t \t });
\t \t },
\t \t _resizeImage \t \t : function($img, w, h) {
\t \t \t $img.css({ width : w + 'px', height : h + 'px' });
\t \t },
\t \t _reload \t \t \t \t : function() {
\t \t \t // container's width
\t \t \t var new_el_w = this.element.width();
\t \t \t
\t \t \t // if different, something changed...
\t \t \t if(new_el_w !== this.cache.container_w) {
\t \t \t \t this.element.hide();
\t \t \t \t this.cache.container_w \t \t = new_el_w;
\t \t \t \t this.cache.space_w_left \t = new_el_w;
\t \t \t \t var instance \t \t \t \t = this;
\t \t \t \t instance.$imgs.removeClass('montage').each(function(i) {
\t \t \t \t \t instance._insertImage($(this));
\t \t \t \t });
\t \t \t \t if(instance.options.fillLastRow && instance.cache.space_w_left !== instance.cache.container_w) {
\t \t \t \t \t instance._stretchImage(instance.$imgs.eq(instance.totalImages - 1));
\t \t \t \t } \t
\t \t \t \t instance.element.show();
\t \t \t }
\t \t },
\t \t _create \t \t \t : function(options) {
\t \t \t this.options \t = $.extend(true, {}, $.Montage.defaults, options);
\t \t \t
\t \t \t var instance \t \t = this,
\t \t \t \t el_w \t \t \t = instance.element.width();
\t \t \t
\t \t \t instance.$imgs \t \t = instance.element.find('img');
\t \t \t instance.totalImages= instance.$imgs.length;
\t \t \t
\t \t \t // solve the scrollbar width problem.
\t \t \t if(instance.options.liquid)
\t \t \t \t $('html').css('overflow-y', 'scroll');
\t \t \t
\t \t \t // save the heights of all images.
\t \t \t if(!instance.options.fixedHeight) {
\t \t \t \t instance.$imgs.each(function(i) {
\t \t \t \t \t var $img \t = $(this), img_w = $img.width();
\t \t \t \t \t
\t \t \t \t \t // if images have width > instance.options.minw then "resize" image.
\t \t \t \t \t if(img_w < instance.options.minw && !instance.options.minsize) {
\t \t \t \t \t \t var new_h = instance._getImageHeight($img, instance.options.minw);
\t \t \t \t \t \t instance.heights.push(new_h);
\t \t \t \t \t }
\t \t \t \t \t else {
\t \t \t \t \t \t instance.heights.push($img.height());
\t \t \t \t \t } \t
\t \t \t \t });
\t \t \t }
\t \t \t
\t \t \t // calculate which height to use for each image.
\t \t \t instance.theHeight \t \t \t = (!instance.options.fixedHeight && !instance.options.alternateHeight) ? instance._chooseHeight() : instance.options.fixedHeight;
\t \t \t
\t \t \t if(instance.options.alternateHeight)
\t \t \t \t instance.theHeight \t \t = Math.floor(Math.random() * (instance.options.alternateHeightRange.max - instance.options.alternateHeightRange.min + 1) + instance.options.alternateHeightRange.min);
\t \t \t \t
\t \t \t // save some values.
\t \t \t instance.cache.container_w \t = el_w;
\t \t \t // space left to fill the row.
\t \t \t instance.cache.space_w_left = el_w;
\t \t \t
\t \t \t // wrap the images with the right sizes.
\t \t \t instance.$imgs.each(function(i) {
\t \t \t \t instance._insertImage($(this));
\t \t \t });
\t \t \t
\t \t \t if(instance.options.fillLastRow && instance.cache.space_w_left !== instance.cache.container_w) {
\t \t \t \t instance._stretchImage(instance.$imgs.eq(instance.totalImages - 1));
\t \t \t }
\t \t \t
\t \t \t // window resize event : reload the container.
\t \t \t $(window).bind('smartresize.montage', function() {
\t \t \t \t instance._reload();
\t \t \t });
\t \t },
\t \t add \t \t \t \t \t : function($images, callback) {
\t \t \t // adds one or more images to the container
\t \t \t var $images_stripped \t = $images.find('img');
\t \t \t this.$imgs \t \t = this.$imgs.add($images_stripped);
\t \t \t this.totalImages= this.$imgs.length;
\t \t \t this._add($images, callback);
\t \t },
\t \t _add \t \t \t \t : function($images, callback) {
\t \t \t var instance \t = this;
\t \t \t $images.find('img').each(function(i) {
\t \t \t \t instance._insertImage($(this));
\t \t \t });
\t \t \t
\t \t \t if(instance.options.fillLastRow && instance.cache.space_w_left !== instance.cache.container_w)
\t \t \t \t instance._stretchImage(instance.$imgs.eq(instance.totalImages - 1));
\t \t \t
\t \t \t if (callback) callback.call($images);
\t \t },
\t \t destroy \t \t \t \t : function(callback) {
\t \t \t this._destroy(callback);
\t \t },
\t \t _destroy \t \t \t : function(callback) {
\t \t \t this.$imgs.removeClass('montage').css({
\t \t \t \t position \t : '',
\t \t \t \t width \t \t : '',
\t \t \t \t height \t \t : '',
\t \t \t \t left \t \t : '',
\t \t \t \t top \t \t \t : ''
\t \t \t }).unwrap();
\t \t \t
\t \t \t if(this.options.liquid)
\t \t \t \t $('html').css('overflow', '');
\t \t \t
\t \t \t this.element.unbind('.montage').removeData('montage');
\t \t \t $(window).unbind('.montage');
\t \t \t
\t \t \t if (callback) callback.call();
\t \t },
\t \t option \t \t \t \t : function(key, value) {
\t \t \t // set options AFTER initialization:
\t \t \t if ($.isPlainObject(key)){
\t \t \t \t this.options = $.extend(true, this.options, key);
\t \t \t }
\t \t }
\t };
\t
\t // taken from jquery.masonry
\t // \t https://github.com/desandro/masonry
\t // helper function for logging errors
\t // $.error breaks jQuery chaining
\t var logError \t \t \t \t = function(message) {
\t \t if (this.console) {
\t \t \t console.error(message);
\t \t }
\t };
\t
\t // Structure taken from jquery.masonry
\t // \t https://github.com/desandro/masonry
\t // ======================= Plugin bridge ===============================
\t // leverages data method to either create or return $.Montage constructor
\t // A bit from jQuery UI
\t // https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.widget.js
\t // A bit from jcarousel
\t // https://github.com/jsor/jcarousel/blob/master/lib/jquery.jcarousel.js
\t $.fn.montage \t \t \t \t = function(options) {
\t \t if (typeof options === 'string') {
\t \t \t // call method
\t \t \t var args = Array.prototype.slice.call(arguments, 1);
\t \t \t this.each(function() {
\t \t \t \t var instance = $.data(this, 'montage');
\t \t \t \t if (!instance) {
\t \t \t \t \t logError("cannot call methods on montage prior to initialization; " +
\t \t \t \t \t "attempted to call method '" + options + "'");
\t \t \t \t \t return;
\t \t \t \t }
\t \t \t \t if (!$.isFunction(instance[options]) || options.charAt(0) === "_") {
\t \t \t \t \t logError("no such method '" + options + "' for montage instance");
\t \t \t \t \t return;
\t \t \t \t }
\t \t \t \t // apply method
\t \t \t \t instance[ options ].apply(instance, args);
\t \t \t });
\t \t }
\t \t else {
\t \t \t this.each(function() {
\t \t \t \t var instance = $.data(this, 'montage');
\t \t \t \t if (instance) {
\t \t \t \t \t // apply options & reload
\t \t \t \t \t instance.option(options || {});
\t \t \t \t \t instance._reload();
\t \t \t \t }
\t \t \t \t else {
\t \t \t \t \t // initialize new instance
\t \t \t \t \t $.data(this, 'montage', new $.Montage(options, this));
\t \t \t \t }
\t \t \t });
\t \t }
\t \t
\t \t return this;
\t };
\t
})(window, jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>