我正在尝试将容器的纵横比与一系列图像的纵横比进行比较,并为图像添加类纵向或横向。此外,我试图根据定义的容差检测非常高/宽的图像(如大全景图)。我的基本功能正常here(前两个图像的左上角有一个“缩放”按钮)。
现在,我正在尝试拆分该功能,因此当我调整页面大小时,脚本不再计算所有图像的比例(var i_ratio),它只是将这些与新容器比率(var)进行比较c_ratio)。我的开发示例是here。
我想我的问题是我不知道如何:
在开发示例中,有一个控制台日志,显示i_ratio在第二个函数中未定义,但是当您调整窗口大小时,它似乎得到一个值 - 不确定发生了什么。
// Get window aspect ratio
var container = $('.main');
var c_ratio = container.width() / container.height();
var i_ratio;
function imageRatios() {
// Get original dimensions of image (IE8+)
if (this.naturalWidth) {
i_width = this.naturalWidth;
i_height = this.naturalHeight;
} else {
// Get original dimensions of image with JQuery
i_width = this.width;
i_height = this.height;
}
i_ratio = i_width / i_height;
// Don't allow images to get bigger than their original size
$(this).css('max-width', i_width).css('max-height', i_height);
}
function setClass() {
console.log('number of images: '+images.length+', i_ratio from imageRatios function: '+i_ratio);
// Add ratio classes
if (c_ratio > i_ratio) {
$(this).parent('li').removeClass('landscape').addClass('portrait');
} else {
$(this).parent('li').removeClass('portrait').addClass('landscape');
}
// Identify long/tall panoramas and add zoom button
tolerance = c_ratio / i_ratio;
if (tolerance < 0.3 || tolerance > 5) {
$(this).after('<div class="zoom"></div>');
} else {
$(this).remove('.zoom');
}
// Show/hide zoomed image
var img = $(this);
$(this).next('.zoom').click(function() {
if (img.siblings('.big_image').size() > 0) {
$('.big_image').remove();
} else {
$(this).after('<div class="big_image"><img src="'+$img.attr('src')+'"></div>');
}
});
}
// Get images
var images = $('.main img');
images.each(function(i) {
if (this.complete) {
imageRatios.call(this);
setClass();
} else {
this.onload = imageRatios;
setClass();
}
});
// Update ratio class on resize
$(window).on("throttledresize", function() {
var c_ratio = container.width() / container.height();
images.each(function() {
setClass();
});
});
答案 0 :(得分:1)
有几个问题 - 这将是未经测试的,因此您可能需要调整一下以使其正确
this
将成为全局对象获取图像逻辑可以调整为:
// Get images
var images = $('.main img');
images.each(function(i) {
if (this.complete) {
imageRatios.call(this, i);
setClass.call(this, i); // <== call with image as the context and pass its index
} else {
// Wrap the calls to imageRatios & setClass in the callback so
// they can be called sequentially
this.onload = function() {
imageRatios.call(this, i);
setClass.call(this, i); // <== call with image as the context and pass its index
};
}
});
限制调整大小可以修改为:
// Update ratio class on resize
$(window).on("throttledresize", function() {
c_ratio = container.width() / container.height(); // <== remove var - needs to be available to other functions in this closure (already declared at top)
// TODO: Just need to update class, not recalculate image ratios on resize
images.each(function(i) {
setClass.call(this,i); // <== call with image as the context and pass its index
});
});
imageRatios to:
var i_ratio = []; // <== use an array of values indexes will match image indexes
function imageRatios(i) { // <== change to accept an index
var i_width, i_height; // <== declare as local variables
// Get original dimensions of image (IE8+)
if (this.naturalWidth) {
i_width = this.naturalWidth;
i_height = this.naturalHeight;
} else {
// Get original dimensions of image with JQuery
i_width = this.width;
i_height = this.height;
}
i_ratio[i] = i_width / i_height; // <== set the ratio using the passed in index
// Don't allow images to get bigger than their original size
$(this).css('max-width', i_width).css('max-height', i_height);
}
setClass为:
function setClass(i) { // <== Change to accept an index
var tolerance; // <== Declare as local variable
console.log('number of images: '+images.length+', i_ratio from imageRatios function: '+i_ratio);
// Add ratio classes
if (c_ratio > i_ratio[i]) { // <== Use the index to get the right ratio
$(this).parent('li').removeClass('landscape').addClass('portrait');
} else {
$(this).parent('li').removeClass('portrait').addClass('landscape');
}
// Identify long/tall panoramas and add zoom button
tolerance = c_ratio / i_ratio[i]; // <== Use the index to get the right ration
if (tolerance < 0.3 || tolerance > 5) {
$(this).after('<div class="zoom"></div>');
} else {
$(this).remove('.zoom');
}
// Show/hide zoomed image
var img = $(this);
$(this).next('.zoom').click(function() {
if (img.siblings('.big_image').size() > 0) {
$('.big_image').remove();
} else {
$(this).after('<div class="big_image"><img src="'+$img.attr('src')+'"></div>');
}
});
}
答案 1 :(得分:0)
未定义值的问题来自此代码
images.each(function (i) {
if (this.complete) {
imageRatios.call(this);
setClass();
} else {
this.onload = imageRatios;
setClass();
}
});
将每个图像的onload回调设置为imageRatios
,然后调用setClass()
但是它不会等到onload
事件被触发后才能继续setClass
尝试这样的事情
images.each(function (i) {
if (this.complete) {
imageRatios.call(this);
setClass();
} else {
this.onload = function () {
imageRatios();
setClass();
};
}
});
在为图片触发imageRatios()
事件时,将按此顺序调用setClass()
然后调用onload