$ (document) .ready () срабатывает слишком рано - PullRequest
34 голосов
/ 04 февраля 2012

Итак, мне нужно знать ширину элемента с помощью javascript, у меня проблема в том, что функция срабатывает слишком рано, и ширина изменяется при тотальном применении CSS. Как я понял, функция $ (document) .ready () была запущена, когда документ завершен, но, похоже, не работает так.

В любом случае, я уверен, что с кодом моя проблема будет понята (это упрощенный пример):

<html>
<head>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
    <link href='http://fonts.googleapis.com/css?family=Parisienne' rel='stylesheet' type='text/css'>

    <style type="text/css">
        #target {
            font-family: 'Parisienne', cursive;
            float: left;
        }
    </style>
</head>
<body>
    <div id="target">Element</div>
</body>
</html>

<script type="text/javascript">
    $(document).ready(function(){
        console.debug($('#target').outerWidth());
        alert('hold on');
        console.debug($('#target').outerWidth());
    });
</script>

Я хочу знать ширину #target div, проблема в том, что код, который выполняется перед предупреждением, выдает другой вывод, чем тот, который следует после, возможно потому, что шрифт загружен не полностью и он измеряет div с шрифт по умолчанию.

Он работает, как я ожидаю, в Google Chrome, но не работает в IE и Firefox.

Ответы [ 7 ]

69 голосов
/ 04 февраля 2012

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

$(window).on("load", function() {
    // code here
});

Поведение этих событий описано в thisarticle :

Существует [a] готовое состояние, известное как DOM-ready.Это когда браузер на самом деле создал страницу, но все еще может потребоваться захватить несколько изображений или флэш-файлов.

Редактировать: изменен синтаксис, чтобы также работать с jQuery 3.0 отмечено Алексом H

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

Цитата OP:

"Как я понял, функция $(document).ready() сработала после завершения документа"

$(document).ready() срабатывает, когда DOM («объектная модель документа») полностью загружен и готов к работе. DOM отличается от «документа».

W3C - Часто задаваемые вопросы по DOM

Вы можете попробовать $(window).load() функцию вместо ...

$(window).load(function() {
    // your code
});

Он будет ждать полной загрузки всех ресурсов страницы (например, изображений, шрифтов и т. Д.) Перед запуском.

5 голосов
/ 04 февраля 2012

Функция jQuery .ready () срабатывает, как только DOM завершен.Это не означает, что все ресурсы (такие как изображения, CSS и т. Д.) Были загружены в этот момент, и, следовательно, размер элементов может быть изменен.

Используйте $ (window) .load (), если вам нужноразмер элемента.

4 голосов
/ 04 февраля 2012

Событие "ready" возникает при загрузке DOM, что означает, когда можно безопасно работать с разметкой.

Ожидание загрузки всех ресурсов (css, images, external javascript ...), вы бы предпочли использовать событие загрузки.

$(window).load(function() {
    ...
});
2 голосов
/ 04 февраля 2012

Вы можете использовать $(window).load(), но это будет ждать всех ресурсов (например, изображений и т. Д.). Если вы хотите только дождаться загрузки шрифта, попробуйте что-то вроде этого:

<script type="text/javascript"> 
    var isFontLoaded = false;
    var isDocumentReady = false;
    $("link[href*=fonts.googleapis.com]").load(function () {
        isFontLoaded = true;
        if (isDocumentReady) {
            init();
        }
    });
    $(document).ready(function () {
        isDocumentReady = true;
        if (isFontLoaded) {
            init();
        }
    });
    function init () {
        // do something with $('#target').outerWidth()
    }
</script> 

Отказ от ответственности: я не совсем уверен, что это будет работать. Событие <link> onload может сработать, как только будет проанализирована таблица стилей, но до того, как будут загружены ее внешние ресурсы. Может быть, вы могли бы добавить скрытый <img src="fontFile.eot" /> и вместо него поместить на свой обработчик загрузки.

1 голос
/ 02 ноября 2013

Проблема $ (document) .ready () срабатывает слишком рано может иногда происходить из-за неправильного объявления функции jQuery onReady.

Если возникают проблемы, убедитесь, что ваша функция объявлена ​​так:

 $(document).ready(function() 
 {
   // put your code here for what you want to do when the page loads.
 });

Например, если вы забыли часть анонимной функции, код все равно будет работать, но он будет работать "не по порядку".

console.log('1');
$(document).ready()
{
  console.log('3');
}
console.log('2');

это выдаст

1
3
2
1 голос
/ 27 марта 2013

Я абсолютно неоднократно видел ту же проблему в IE9 и IE10. Вызов jquery ready () срабатывает, и один из моих

не существует. Если я обнаружу это и затем перезвоню после короткого тайм-аута (), он будет работать нормально.

Мое решение на всякий случай было двояким:

  1. Добавить window.fullyLoaded = true; в конце документа, затем проверить эту переменную в обратном вызове ready (), И

  2. Проверьте, $ ('# lastElementInTheDocument'). Длина> 0

Да, я понимаю, что это противные хаки. Однако, когда ready () не работает должным образом, требуется какой-то обходной путь!

Кроме того, «правильное» решение, вероятно, включает установку $ .holdReady в заголовке и очистку его в конце документа. Но, конечно, действительно правильное решение для готовности () к работе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...