Действительно загадочные проблемы с DOM в Chrome

#jquery #dom

#jquery #dom

Вопрос:

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

У меня есть четыре тега LI, которые после $ (window).load() клонируются в DIVs, а затем высоты DIVs извлекаются с помощью цикла $.each (). Проблема, с которой я сталкиваюсь, заключается в том, что в большинстве браузеров на разных ОС высоты одинаковы, за исключением Chrome на Linux и Mac. Я расскажу немного подробнее.

Каждый LI содержит некоторый текст и некоторые другие разделы, в основном просто общее содержимое. И я использую $.contents().clone(), чтобы клонировать каждый LI и поместить его в DIV, где он оформлен по-другому. Именно так работает эта конкретная часть, и это не может измениться.

Хорошо, время кода jQuery:

 $(window).load(function() {

    $('.carousel-thumb').each(function(i) {
        var $story = $(this).contents().clone();

        // Remove all <script> tags before appending, otherwise we're looking
        // for trouble
        $('script', $story).remove();

        $story.appendTo('#featured-story')
            .wrapAll('<div class="carousel-story" />');
    });

    // Fix the sizing on the featured story container
    $('.carousel-story').each(function(i) {
        console.log('story '   i   ' = '   $(this).height());
        if ($(this).height() > storyMaxHeight)
            storyMaxHeight = $(this).height();
    });
    /*$('.carousel-story').height(storyMaxHeight);
    $('#featured-story').height(storyMaxHeight);*/
});
  

Я отвечу на один потенциальный вопрос, который может возникнуть в связи с этим. Что с удалением тегов скрипта? Исходные теги LI содержат различное содержимое, включая встроенные скрипты. Я заметил, что когда я клонировал это содержимое, оно вносило хаос в структуру страницы. Не уверен, выполнялись ли скрипты снова или что, но удаление скриптов (тем более, что они уже были выполнены) решило проблему.

Теперь ознакомьтесь с этим интересным лакомым кусочком. На этом рисунке слева показан Windows Chrome, а справа — Linux Chrome. Обратите внимание, что Linux / Mac Chrome ведут себя неправильно.

Слева: Windows Chrome; Справа: Linux Chrome

Разве ЭТО не странно? Во время выполнения скрипта высоты в Linux совершенно неправильные. Тем не менее, после того, как все полностью сделано, и я вручную запрашиваю высоту третьего div, он сообщает высоту правильно! Тем не менее, поведение слева (правильное) демонстрируется Windows Chrome, а также Firefox на всех платформах, даже IE7.

Есть ли какая-то странная задержка в вызове clone ()? Занимает ли клонирование большого количества содержимого некоторое время, и скрипт jQuery продолжает выполняться и, следовательно, захватывает неправильные высоты? Есть ли способ приостановить, чтобы убедиться, что все содержимое было клонировано должным образом?

Спасибо. Я действительно рву на себе волосы из-за этого.

Комментарии:

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

2. Я поставил в тупик StackOverflow? Получу ли я значок за это? 😉 Я провел тест и запустил код выборки height () внутри функции, которая вызывается после срабатывания таймера 10 мс. Тогда высоты указаны правильно. Похоже, что весь процесс $.clone () в некоторых случаях занимает некоторое время. Похоже, мне нужен еще один вызов onDomReady после вызовов $.clone() .

Ответ №1:

По-видимому, это ошибка в Chrome и Safari, которая появляется случайным образом. Эти браузеры иногда запускают функцию load () до завершения загрузки всех изображений / мультимедиа. Один человек рекомендует это исправление / взлом:

 jQuery(window).load(function(){
  if (jQuery.browser.safari amp;amp; document.readyState != 'complete'){
    // chrome / safari will trigger load function before images are finished
    // check readystate in safari browser to ensure images are done loading
    setTimeout( arguments.callee, 100 );
    return;
  }
  // do things you want to do
});
  

Источник: http://javascript.livejournal.com/169501.html