Jquery Cycle + Firefox Squishing Images - PullRequest
       13

Jquery Cycle + Firefox Squishing Images

6 голосов
/ 12 ноября 2009

Эй, ребята, я запускаю jQuery Cycle для галереи изображений. Посмотреть ссылку: Здесь

Моя проблема в том, что при просмотре в Firefox изображения становятся плоскими. Проблема исчезает, когда я перезагружаю страницу. Это заставляет меня поверить, что Javascript запускается до того, как все изображения загружены (обычно первое изображение работает нормально, а остальные сжимаются).

Жесткий повторный повтор воспроизводит проблему.

Я завернул все в $ (документ) .ready (function () {}); но это все еще происходит.

Дополнительная информация: Если я укажу ширину и высоту изображения, все будет отлично. Однако существуют сотни изображений разных размеров ..

Я довольно разочарован этой проблемой. Любые идеи / помощь с благодарностью!

Вот мой код:

$(document).ready(function(){
//function onBefore(curr,next,opts) {
//    var $slide = jQuery(next);
//    var w = $slide.outerWidth();
//    var h = $slide.outerHeight();
//    $slide.css({
//        marginTop: (482 - h) / 2,
//        marginLeft: (560 - w) / 2
//    });
//};

// Decare the function that center the images...
function onBefore(curr,next,opts) {
    var $slide = jQuery(next);
    var w = $slide.outerWidth();
    var h = $slide.outerHeight();
    $slide.css({
        marginTop: (480 - h) / 2,
        marginLeft: (560 - w) / 2
    });
};


$(document).ready(function() {
    $('#slideshow').cycle({
     fx:     'fade', 
    next:   '#next', 
    pause: 0,
    speed: 500,
    before: onBefore,
    prev:   '#prev',
    pause:  '#pause',
    pager:  '.thumbs',
    pagerClick:function(zeroBasedSlideIndex, slideElement) {$(slideElement).find('div.cover').hide();},
    pagerAnchorBuilder: function(idx, slide) {
                        var src = $('img',slide).attr('src');
                        //Change height of thumbnail here
                         return '<li><a href="#"><img src="' + slide.src + '" height="90" /></a></li>'; 

                } 
    });});});

Ответы [ 7 ]

12 голосов
/ 10 февраля 2012

Существует гораздо более простое и чистое решение, которое я использовал для решения этой проблемы, чем то, что уже было предложено:

Используя jQuery, вам нужно использовать $(window).load вместо $(document).ready для вашей конкретной ситуации. Чтобы исправить проблему, измените это:

$(document).ready(function() {
  $('#slideshow').cycle({
    /* ... */
  });
});

К этому:

$(window).load(function() {
  $('#slideshow').cycle({
    /* ... */
  });
});

Почему это работает? Поскольку window.onload срабатывает после загрузки всех ссылочных изображений на странице (см. https://developer.mozilla.org/en/DOM/window.onload, и .load () - jQuery API ), что является желательным поведением в вашей ситуации. $(document).ready, более известный как «DOM Ready», сработает до загрузки изображений. Это обычно желаемое поведение, но в вашей ситуации это слишком рано.

4 голосов
/ 12 ноября 2009

У меня была такая же проблема при работе на сайте несколько месяцев назад (ссылка ниже). Если вы запускаете цикл в $(document).ready(), вот что происходит, когда клиент переходит на вашу страницу:

1) Браузер клиента отправляет запрос на каждый элемент img. Эти запросы занимают различное количество времени.

2) Перед выполнением запросов изображения начинается цикл. Цикл работает, скрывая все, кроме первого изображения в слайд-шоу: он устанавливает visibility:hidden и display:none для каждого из своих изображений.

Проблема в том, что Firefox исправляет размер элемента img один раз и для всех в тот момент, когда стиль отображения не установлен . Поэтому, если изображение не завершило загрузку, его атрибуты стиля высоты и ширины невелики (я не уверен, что именно они соответствуют - возможно, размер заполнителя изображения Firefox). Когда цикл показывает изображение, устанавливая его атрибут стиля в display:block, он использует любые размеры, которые он имел в то время, когда он был скрыт.

Я решил эту проблему, изменив мой код, чтобы он не запускал плагин цикла, пока все изображения не будут загружены. Для этого я инициализирую переменную-счетчик числом изображений, которое я повторяю, а затем привязываю событие загрузки к каждому изображению следующим образом:

var imagesRemaining = 12; // 12 is just the number of images in the slideshow div

$(document).ready(function() {
    $('#slideshow > img').bind('load', function(e) {
        imagesRemaining = imagesRemaining - 1;
        if (imagesRemaining == 0) {
            // I'm doing some other stuff when initializing cycle
            startCycle();
            // My images all start with visibility:hidden so they don't show
            // before cycle hides them in a 'stack', so ...
            $('#slideshow > img').css('visibility', 'visible');
        }
    });
});

function onBefore(curr, next, opts) { // Your code here ... }

function startCycle() {
    $('#slideshow').cycle({ ... // your initialization here });
}

Вы можете увидеть это в действии, просмотрев галереи на этом сайте в Firefox. Я создаю страницы галереи динамически, поэтому она структурирована немного по-другому, чем ваша страница, но вы можете увидеть больше деталей, если возитесь с Firebug.

2 голосов
/ 10 декабря 2009

Я также хотел бы добавить, что, кажется, добавление атрибутов width и height решает эту проблему.

1 голос
/ 05 декабря 2010

Хорошо, я знаю, что это, вероятно, отличный способ вызова load, но я просто могу связать свой код цикла с .load, по какой-то причине он просто не работает, поэтому я вызвал весь инициализатор цикла внутри ...

Я не могу форсировать размеры, так как я перебираю li, содержащий динамические изображения и данные

это, вероятно, в какой-то мере ошибочно, но для таких же отчаявшихся, как я ...

0 голосов
/ 18 февраля 2015

Вы можете использовать решение, похожее на адаптацию видео на YouTube. Вам нужно знать отношение вашей ширины к высоте, и добавить это как padding-bottom к div цикла. Для моих фотографий 1024X680 я использовал 680/1024 = 66,4%

В твоем случае я верю

#slideshow{ padding-bottom:66.4%; } покажет изображение без сжатия. Я понятия не имею, с какими фактическими значениями высоты и ширины вы работаете, поэтому подставьте свои собственные. Мне пришлось использовать это решение, когда решение $ (window) .load оказалось безумно неэффективным, поэтому теперь я использую оба.

Это лучше, чем установка размеров изображения, потому что оно скользит в жидкой, отзывчивой среде.

0 голосов
/ 04 июля 2011

Джош, твое решение только что спасло меня от головной боли, большое спасибо!

Я думаю, что я немного изменил его, чтобы обрабатывать страницы, на которых вы не знаете общее количество изображений. Кажется, это работает нормально для меня, если кто-то может увидеть какие-либо недостатки, пожалуйста, укажите на них - я все еще учусь.

$(document).ready(function () {
    $('#slideshow > img').each(
        function go() {
            $(this).bind('load', function (e) {
                projects();
                $('#slideshow > img').css('visibility', 'visible');
            });
         });
    });

function projects() {
    $('#slideshow').cycle({
        fx: 'scrollHorz',
        speed: 300,
        timeout: 0,
        next: '#next ',
        prev: '#prev ',
        after: onAfter,
        nowrap: 1,
        autostop: 1 
    });
}
0 голосов
/ 11 февраля 2010

Если вы используете базу данных для заполнения слайд-шоу, вы можете попробовать получить доступ к размерам изображения из самого изображения.

Например, используя django, вы можете использовать

 width="{{ xxx.image.width }}px"  height="{{ xxx.image.height }}px" 

в вашем теге img.

...