我们使用Bootstrap Carousel
+Hammer.Swipe
+PhotoSwipe
构建了一个库
如果画廊里只有风景画或肖像画,一切都很好
但是,当我们在小分辨率下测试它时,同时在风景中有肖像,然后画廊将容器的高度设置为最高的肖像,这导致每个风景图像的上下都有很大的空白。
如何在移动视图中删除横向图像的边距?
这里有一个简化的代码:
// carousel.js
var Carousel = (function($, viewport) {
function init() {
var $carousels = $('.carousel');
$.each($carousels, function() {
var $carousel = $(this);
swipeHorizontalMobile($carousel, viewport);
imageNavListener($carousel);
updateArrowVisibility(0, $carousel);
});
}
// implementation of the rest of the code
return {
init: init
};
})(jQuery, ResponsiveBootstrapToolkit);
事实证明,carousel-inner
和slider-photo-wrapper
元素中存在一些预先计算的固定值
我决定根据最高的景观来限制高度,并覆盖这些元素的值。
我面临的问题:
- 在使用它们之前,我必须确保加载了图像,否则我无法获得它们的
width
和height
- 如何获取缩放图像的大小?最后,我绕过它,使用了原始大小,因为我只需要
width
和height
的比例,就可以根据转盘容器的宽度计算出最大height
- 我无法使用
getBoundingClientRect()
,因为它为未显示的图像返回0(显示:隐藏(,并且Bootstrap Carousel
中只显示第一个图像
我们从主代码中调用CarouselNormalization.init($carousel)
,在主代码中我们循环浏览库:
// carousel.js
var Carousel = (function($, viewport) {
function init() {
var $carousels = $('.carousel');
$.each($carousels, function() {
var $carousel = $(this);
swipeHorizontalMobile($carousel, viewport);
imageNavListener($carousel);
updateArrowVisibility(0, $carousel);
// fixes the size of the carousel images/containers mainly for mobile devices
CarouselNormalization.init($carousel);
});
}
// implementation of the rest of the code
return {
init: init
};
})(jQuery, ResponsiveBootstrapToolkit);
下面的代码是和我的同事在Pair编程中编写的,我们使用了Normalize Twitter Bootstrap Carousel Slide Heights的一些想法。
// carousel_normalization.js
/**
* changes the maximum height of the carousel containers based on the tallest landscape image
* and prevents to have big margins above and below landscape images in small resolution
*/
var CarouselNormalization = (function ($) {
var $carousel,
$photoWrappers,
$imgs;
function init($inputCarousel) {
$carousel = $inputCarousel;
$imgs = $carousel.find('.item img');
if ($imgs.length < 1) {
return;
}
$photoWrappers = $carousel.find('.item .slider-photo-wrapper');
var imgsLoadedCount = 0;
$imgs.one('load', function () {
imgsLoadedCount++;
if (imgsLoadedCount < $imgs.length) {
return;
}
normalizeHeights();
$(window).on('resize orientationchange', function () {
normalizeHeights();
});
}).each(function () {
if (this.complete) {
$(this).trigger('load');
}
});
}
/**
* finds the tallest landscape
* uses its height as maximum height for the 'slider-photo-wrapper' defined in the css and for the 'carousel-inner'
*/
function normalizeHeights() {
var widths = [];
var heights = [];
var maxWidth = $carousel.width();
$imgs.each(function () {
var width = $(this).prop('naturalWidth');
var height = $(this).prop('naturalHeight');
if (width > height) {
widths.push(width);
heights.push(height);
}
});
if (widths.length < 1 || heights.length < 1) {
return;
}
var tallestLandscapeHeight = Math.max.apply(null, heights);
var tallestLandscapeWidth = widths[heights.indexOf(tallestLandscapeHeight)];
var maxHeight = maxWidth * tallestLandscapeHeight / tallestLandscapeWidth;
$photoWrappers.css('height', maxHeight);
$carousel.find('.carousel-inner').css('height', maxHeight);
}
return {
init: init
};
})(jQuery);