Показать сообщение отдельно
  #1 (permalink)  
Старый 18.08.2009, 12:21
Интересующийся
Отправить личное сообщение для SleepWalker Посмотреть профиль Найти все сообщения от SleepWalker
 
Регистрация: 09.11.2008
Сообщений: 15

Отслеживание готовности DOM-структуры
К сожалению мне сново пришлось создать тему, но я риально нигде немогу найти инфы ни в этой ветке, ни в статьях, ни в поисковиках.

В общем прочитал я в одной книжечке, что страница в браузере загружаеться так:
1. Синтаксический анализ HTML-разметки.
2. Загрузка внешних сценаривев.
3. Выполнение сценариев по мере их анализа в документе.
4. Полное формирование DOM-структуры HTML-кода.
5. Загрузка изображений и внешнего содержимого.
6. Завершение загрузки страницы.

И соответственно скриптик:
function domReady(f)
{
    // Если DOM уже загружена, немедленно выполнить функцию
    if (domReady.done) return f();

    // Если мы уже дополнили функцию
    if (domReady.timer) {
        // внести ее в список исполняемых
        domReady.ready.push(f);
    }else{
        // Подключение события завершения загрузки страницы
        // на тот случай, если ее загрузка закончится первой.
        addEvent(window, 'load', isDOMReady);
        test = function() {alert(111);}
        addEvent(window, 'load', test);
        // Инициализация массива исполняемых функций
        domReady.ready = [f];

        // Проверка DOM на готовность, проводимая как можно быстрее
        domReady.timer = setInterval(isDOMReady, 13);
    }
}
// Проверка DOM на готовность к перемещению по ее структуре
function isDOMReady()
{
    // Если мы уже определили готовность страницы - проигнорировать
    // дальнейшее выполнение
    if (domReady.done) return false;

    // Проверка доступности некотрых функций и элементов
    if(document && document.getElementsByTagName && document.getElementById && document.body) {
    alert(document.getElementById('search_module'))
        // Если они готовы, можно прекратить проверку
        clearInterval(domReady.timer);
        domReady.timer =  null;
        //removeEvent(window, 'load', isDOMReady);

        // Выполнение всех ожидавших функций
        for (var i = 0; i< domReady.ready.length; i++) {
            domReady.ready[i]();
        }

        // Сохранение того, что только что было сделано
        domReady.ready = null;
        domReady.done = true;
    }
}


Готовность DOM они там определяют по доступности методов и свойств:
document && document.getElementsByTagName && document.getElementById && document.body


Если добавить в загрузку допустим такую функцию:

domReady(function()
{
alert('DOM is ready!');
});

то мы и вправду получим alert() теоретически до загрузки картинок(теоретически, потому что я картинки до алерта уже видел, но только часть, возможно єто чемто связано с кєшированием..)

Но вот когда я попытался использовать эту функцию напрактике, то столкнулся с следущей проблемой:
Все функции выполняються по два раза. Первый раз по таймеру, причем они получают сбой изза того что getElementById существует, но вот самого id эллемента еще нету. Ну а второй раз уже все почеловечески запускаеться, по событию onload. Моих знаний нехватает, что бы обеспечить правильную работу этого скрипта. Я сейчас вижу только четыре варианта решения проблемы, которые вобщем-то значительно отличаються от начальной цели.
1. Переделать все функции, которые будут запускаться, что бы они сами проверяли наличие нужных им id в документе и возвращали false в случае неудачи, а в скрипте проверки готовности DOM дописать проверку значений возвращаемых функциями (но ето только для инициализирующих функций, которые ничего вобщемто возвращать недолжны)
2. Вставить файл скрипта вконце страницы. Минус - пока браузер не добереться до конца хтмл кода, страница будет малость некрасивая... Еще в той же книге я читал, что мол это не лучший вариант, так как оно вносит беспорядок: в HTML вносятся дополнение только ради инициализации (там основной код был в шапке, а внизу вызывалась функция инициализации. Я вообще планирую туда просто весь JS код кинуть, думаю тогда никаких беспорядков точно не будет или всетаки лучше размещать основной код в шапке?).
3. Забить на всю эту затею и переделать функцию domReady только на событие onload. Ет уже намного дальше от истинной цели, эдинственное что не прикольно, что юзер не будет видеть нормальной страницы, до того как она вся не загрузиться. И есть еще один минус... Бывает передача содержимого страницы затягиваеться надолго изза какогото эллемента, который не как не выдаеться браузеру. В итоге будет совсем уныло(
4. Хоть ето самый "лучший" вариант в данном случае, но я разместил его в самом конце, так как я не хочу использовать библиотеки, потому, что я не собираюся пользоваться ихними вспомогательными функциями (если не щитать готовность DOM), а +60кб к загрузке страницы изза одной функции мне незачем...

на данный момент мне 2 пункт кажеться самым оптимальным, поскольку у него скорость срабатывания будет быстрее чем у пункта 3, ну и тормозить загрузку он будет меньше чем 1 пункт (у меня такое чуство, что если каждых 13 милисекунд будут проверяться все функции, а их около 10, то это может малость замедлить загруку... что мне совсем не нужно)

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

З.Ы. Еще я дето читал мол есть событие загрузки DOM для w3c браузеров, но как тогда поступить с ие?
книга: Рейсиг Дж. Javascript. Профессиональные приемы программирования. - СПб.: Питер 2008.
Ответить с цитированием