Pull to refresh

Comments 52

Подозрительное решение… Получается, таймаут надо выставлять в зависимости от производительности системы? Странно как-то…
т.к. не во всех браузерах существуют события, которые сообщат нам о том что дерево DOM готово (токое как, например, onload при загрузке страницы), то придется использовать таймауты, и уж вам выбирать — только лишь для IE (спасибо за подсказку комментариев ниже) или для всех браузеров
У вас ошибки в коде, пожалуйста протестите такой код, и увидите, что всьо работает нормально…

Text
<div id='mainDiv'>Text</div>
<script>
var str='<div>какойто мега контент</div>'+'<div id=«testDiv»>Всьо работает нормально</div>';
document.getElementById('mainDiv').innerHTML=str;
alert(document.getElementById('testDiv').innerHTML);
</script>
onload — не удачный пример…

document.addEventListener( «DOMContentLoaded»,…, false );
document.documentElement.doScroll(«left»); // javascript.nwbox.com/IEContentLoaded/
document.readyState != «loaded» || document.readyState != «complete»

ajax возвращал не текст, а часть HTML? и потом шло getElementById к тому что было вставлено с помощью innerHTML?
и что происходит при повторном запросе? флаг то уже существует.
hiddenDiv.innerHTML = oXmlHttp.responseText; alert(document.getElementById('flag').tagName);
получим undefined, если контент будет сложной древовидной структуры, именно в этом случае необходимо использовать таймаут
UFO just landed and posted this here
UFO just landed and posted this here
понимаю что глупо, но где-то видел такой хак

hiddenDiv.innerHTML = oXmlHttp.responseText;
setTimeout(«_alert()», 10);

function _alert(){
alert(document.getElementById('flag').tagName);
}

т.е. смысл — разнести в разные функции
UFO just landed and posted this here
UFO just landed and posted this here
В каких браузерах наблюдается? На каких объёмах вставляемого кода?
получаемый контент содержал пору десятков DIV в каждом из которых еще по 3-4 DIV с разметкой (span, a, strong, etc...)
может стоит переделать ваше дерево элементов раз оно локально строится браузером дольше, чем происходит ajax-запрос на внешний ресурс?
В мозилле, опере и вебките есть событие DOMContentLoaded

А вообще во всех фреймворках есть событие, происходящие после загрузки DOM. Можете в исходном коде того же jQuery посмотреть. Правда для IE там тоже проверка через таймауты. Вот такой вот трюк:
javascript.nwbox.com/IEContentLoaded/
Я думаю, что проще будет добавить необходимые элементы в дерево, после того как их подгрузили. Посмотрите статью на сайте Sun (http://java.sun.com/developer/technicalArticles/J2EE/AJAX/), а конкретно — 6 и 7 разделы статьи. Я полагаю, вам должно это помочь.
Можно попробовать Mutation Events. DOMNodeInserted

А вообще ситуация странная. Даже если полученный html-код был очень громоздким, то браузер должен был «подвиснуть» на вот этой строке:

hiddenDiv.innerHTML = oXmlHttp.responseText;

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

P.S. Жаль, что регистрация закрыта.
дело в том, что я при написание кода думал именно так, но на практике получилось, что задержки в выполнении js-кода не возникало, то есть у элемента hiddenDiv в момент выполнения следующей строки кода не было ниодного дочернего узла, хотя можно было проследить с помощью breakpoint'ов в firebug что в параметре innerHTML находится весь подгруженный контент.
Столкнувшись с этим я начал выяснять в чем же дело, и нашел решение с помощью timeout
А как устроена функция createXmlHttp? Там, случайно, не используется один и тот же экземпляр XMLHttpRequest?
простите, не понял что вы имеете ввиду
Я имею ввиду ошибку в Firefox и IE, возникающую при вызове метода abort. А именно, возникает событие readystatechange и свойство readyState при этом будет равно 4. После этого readyState снова устанавливается в ноль.
хм, не понимаю, каким образом это связано с проблемой описанной в топе.
повторюсь, что контент приходит в полном объеме, но он на тот момент является текстом. Конечно, можно с помощью регулярных выражений без всяких задержек распилить его на повторюсь текстовые блоки и вставить их куда нужно. Но удобнее конечно вылавливать нужные блоки по id, а для этого контент должен быть не текстом, а DOM элементом, и именно преобразование текста в элемент посредством innerHTML занимает время, то есть не происходит мгновенно, на что я и хотел обратить внимание в своем топике, дабы, наткнувшись на грабли потратил довольно много времени на повторную проверку всего кода, на предмет косяков…
Не пойму почему нельзя использовать oXmlHttp.responseXML.getElementById('id тогочто нужно'); вместо этих огородов. Вупор не пойму может я глупый обьясните :)
Ну если у вас не получается получит responseXML то можно попробывать так

function toXml(s) {
var doc = null;
if (window.ActiveXObject) {
doc = new ActiveXObject('Microsoft.XMLDOM');
doc.async = 'false';
doc.loadXML(s);
}
else
doc = (new DOMParser()).parseFromString(s, 'text/xml');
return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror')? doc: null;
};

var doc = toXml(oXmlHttp.responseText);
doc.getElementById('id того что нужно');
Поправьте меня, если я не прав, но разве для это не нужно, чтобы ответ был валидным xml документом? А судя по описанию, ответ представляет собой кусок html'я (например последовательность нескольких тегов без root-нода).
ну а кто мешает добввить root нод и использовать второй вариант, да и вобще я за чистату xhtml кода :)
может я не так понял статью, но я делаю так:

черт, хабрахабр питается тэгами :( он сьел мои тэги О.О
вобщем делаю так:
вставляем тег скрипта сразу за дивом в который надо поместить контент, и если скрипт выполнится, то див уже загрузился полюбому (т.к. находится перед скриптом) проблем не возникало…
UFO just landed and posted this here
мдя… чтото даже трудно педставить такой код… контент передается вместе с логикой, думаю ето кошмар для програмиста… и через несколько таких Ajax запросов у вас бутет милион Js обектов…

Так или иначе сложной логики на таком коде не построиш…
я не пишу весь код js в html а только вызов фунции и все, это не «контент передается вместе с логикой» а исключение из правил
А этот прием где-нибудь в стандартах документирован?
А то выпустят процессор с 1000 ядрами и запустят построение DOM на одном процессоре, а выполнение JS на другом и потом гадай что из них быстрее выполнится…
А зачем хранить какие-то данные в скрытых дивах? Чем вам обычный яваскриптовский массив не угодил?
А зачем хранить какие-то данные в массиве? Их же надо эскейпить!!!
Проще их в Засунуть…
сорри — контейнер вырезался…
<textarea style=«display: none»></textarea>
Тут все равно надо применять htmlspecialchars()
Мне кажется проблемы у вас в том что вы вставляете подгружаемый HTML до полной загрузки HTML страницы. Если это так, то стоит дождаться полной загрузки страницы (события onload) и затем подгружать данные. Попробуйте вставить ваш скрипт в самый конец документа (перед </body>).
В любом случае setTimeout самое плохое решение в данном случае. Всегда можно придумать другое решение по распределению (куда вставлять) подгружаемый контент.
чегото и мне так кажется
инициализация обновления страницы с помощью ajax стоит на событие onload + timeout (от 10 секунд, до нескольких минут)
Дело наверное в особенностях работы onload в разных браузерах.
В любом случае, может было бы лучше грузить данные в формате json?
например
{
htmlPart1: '....',
htmlPart2: '....'
}
тогда никаких проблем с выборкой через getElementById не будет
да, и попробуйте не document.getElementById(id), а node.getElementById(id) (тут node узел в который вы вставляете HTML)
Может я чего-то не понимаю, но неужели нельзя все ajax-подгрузки навешивать на body onload, которое срабатывает как раз апосля того, как страница загрузилась?
onload срабатывает только после загрузки всего барахла, что подключено к странице (графика, флеш и т.п.), а нам нужно подгружать данные сразу же как только построится DOM.
Ваше утверждение не совсем верно, для части браузеров это не так, и onload наступает как только загружена сама страница, css и javascript — совсем не обязательно после загрузки всех картинок. В ряде случае событие может наступить и до загрузки всего javascript (например в IE есть для этого специальный атрибут для тега script).
А я давно уже не изобретаю велосипеды. Я использую jQuery.
Документацию по этому очень полезному фреймворку можно посмотреть здесь:
docs.jquery.com/Main_Page

И Вашу задачу (ожидание окончания построения DOM) с помощью jQuery можно решить так:
$(document).ready(function () {
// А здесь можно выполнять Ajax запросы
});

А если покопаться в исходниках фреймворка на предмет функции bindReady(),
то можно насчитать 3 способа определения готовности DOM (Mozilla, IE, Safari).

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

node.innerHtml = 'много много сложного html кода';
subnode = node.getElementById(id); // легко может быть undefined, даже если он там точно есть

просто в обычной жизни практически нет необходимости пихать через innerHtml много много кода, а вот при использовании ajax — иногда появляется
Что-то мне ваш сценарий кажется сомнительным. Когда делаем node.innerHtml = 'много много сложного html кода' мы можем адресовать запросы к этому узлу сразу, за исключением, возможно, тех случаев когда сама страница еще не полностью загружена. Честно говоря не проверял, но что-то мне подсказывает что это так.
обычно пока он не выполнит комманду по вставке кода, он не двигается на следующий шаг. Поэтому неполная загрузка кажется более правдоподобным объяснением.
UFO just landed and posted this here
каков объем вставляемого кода? Современное железо вряд ли будет тупить из-за вставки текста. Пробовали ли вы искать другие возможные проблемы?
Sign up to leave a comment.

Articles