Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > JavaScript: Общие вопросы > Image()


Автор: Sheff 5.1.2004, 02:49
Народ, нужна помощь и срочно. Допустим у меня есть код:
Код

var img = new Image();
img.src = "http://путь_к_файлу";

Так вот, как мне дождаться полной загрузки этого файла ? Т.е я хочу после
Код
img.src = "http://путь_к_файлу";
написать цикл, что-то вроде
Код

while (картинка_не_загружена)
{
     //Ничего не делать
}
//Загрузилась! Теперь сделать то-то

Есть у Image() какое-нить свойство, которое содержит его состояние ? Или может как-нить по другому это всё можно реализовать ? Предлагайте, буду рад любым советам

Автор: Sardar 5.1.2004, 03:25
Код
while(!img.complete){

}

Также есть свойство: readyState.
А еще лучше продолжать загрузку и переписать img.onload=function в которой и сделаешь то, что тебе нужно.
Код

for(i in object) {
document.write("object."+i+"="+object[i]+"\n<br>");
}

Решит многие вопросы smile.gif


Автор: Sheff 6.1.2004, 01:34
Спасибо, попробую =)

Автор: Sheff 6.1.2004, 14:59
Мда, получилось, но не совсем, дело в том что:
Код

while(!img.complete){

}

Тормозит браузер и не даёт картинке загрузится, я вообще вот что делаю, ставлю event handler:
Код

window.attachEvent?window.attachEvent("onbeforeunload",setCookies):void(0);

Функция setCookies() у меня вызывается всякий раз когда юзер выходит с текущего URL'а либо закрывает окно, мне нужно, чтобы в функции setCookies() всё что пользователь ввёл в полях формы текущего URL'а посылалось на сервак, для этот я формирую запрос типа:
save.php?name0=firstname&value0=Stas&name1=lastname&value1=Vorobiov
Затем, чтобы пользователь ничего не увидел, что типа посылается инфа, я делаю так:
Цитата

img = new Image();
img.src = [мой_запрос];

Так вот дальше нужно подождать, пока запрос уйдёт на сервер и потом уже можно окно закрывать, переходить на другой URL т.д. Так вот в чём вопрос, как же подождать. while'ом не получается, я уже сказал почему, как же быть ?

Автор: Sardar 6.1.2004, 16:07
По моему все происходит при закрытии окна, то есть уже не важен результат.
Можно сделать такой "запрос" и банально подождать 3 секунды на то что бы он дошел. На серваке если используется PHP установишь ignore_user_abort(true) и сделаешь что надо.

[q]Затем, чтобы пользователь ничего не увидел, что типа посылается инфа...[/q]
"Пользователь" может не понять smile.gif
Может лучше кнопку сделать со строкой процесса?

Автор: Sheff 6.1.2004, 16:51
А как банально подождать 3 секунды ? У меня была такая идея, но реализовать не получилось. Понимаешь в чём дело, после того как setCookies (функция, которая вызывается при событии onbeforeunload) завершит свою работу, окно закрывается => эти 3 секуды надо ждать так чтобы не выходить из этой функции, можно конечно:
Код

d1 = new Date();
while (true)
{
d2 = new Date();
if (d2-d1) > чего-то, то break;
}

Но так не катит, т.к while тормозит всю страницу и => запросы не шлёт и вообще ничего не делает, полный halt
Как же это реализовать, чтобы браузер "банально" ждал 3 секунды ?

Автор: Secandr 6.1.2004, 16:58
Sheff в JS была хорошая функция timer, может она тебе пригодится?

Автор: Sardar 6.1.2004, 18:44
Цитата
Но так не катит, т.к while тормозит всю страницу и => запросы не шлёт и вообще ничего не делает, полный halt

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

Может все же лучше сделать кнопку или работать не из предсмертного события smile.gif.

Автор: Sheff 7.1.2004, 18:10
Secandr timer не катит, ведь он работает через определённый интервал времени, а как только функция завершается уже не важно что там выполянется по setTimeout.
Sardar
Цитата
Наверное браузер перед закрытием окна уже не хочет что либо грузить

Нет, это не так, он всё прекрасно грузит, проверял так:
Код

img.src = ...
alert(img.complete);
alert('wait');
alert(img.complete);

В первый раз он вывел false, а во второй раз (я подождал перед тем как кликать на 'Ok' диалога со строкой 'wait') - true.
Так что, то что я хочу сделать можно, но как, этот вопрос всё ещё не решён...

Автор: Непрофессионал 7.1.2004, 22:58
[I]Добрый день, я рискую дать недельный совет, но сталкивался с похожей проблемой, как я знаю, пока в JS не выполнится до конца функция, браузер ни к чему другому не приступает (крутится внутри цикла), другими словами, браузер не хочет ничего делать
параллельно с операцией в цикле. Но, вообще, браузер много чего делает параллельно... если пока не доступна одна часть документа, грузит другую и т.д. Следовательно, внутри цикла while можно попытаться задать такой процесс, который браузер согласен выполнять параллельно с загрузкой рисунка - это должна быть не комманда JS, а, например, загрузка ещё чего-то. Не уверен, что сработает, но вот простой пример:

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

Код
<script TYPE="text/javascript"><!--
 for(i=0;i<=3000;i++){
  document.write(i,"; ");
  if(i==100){document.write("<img src='C:/1.jpg' name=ty>");  }
 if(i==1800)alert("готовность");
 if(i==1802)document.images[0].src="C:/2.jpg";
 // пока не появится окно, рисунок не перезагрузится, если комп. быстрый, числа
 //можно увеличить   чтобы было заметно ожидание
 if(i==2990)alert("ожидание");
 /* это ещё не конец загрузки чисел в окно, следовательно, цикл не закончен
 но параллельно с выводом окошка "ожидание" браузер согласен перезагрузить рисунок */
  /* я во всём этом не уверен , у меня именно так работает*/
 if (i==3000)alert("3000");
 }
--></SCRIPT>

Автор: Sheff 8.1.2004, 02:22
Непрофессионал, ты абсолютно прав, я тож делал что-то похожее, но вот только alert меня не устраивает, т.к я не хочу, чтобы пользователь что-нить видел, вот если-б что-нить другое грузить, но только вот что. Было бы неплохо, если бы в JavaScript'е было б что-то типа VB'шного DoEvents, в VB если вставить DoEvents в цикл, то паралелльно с циклом выполняются другие события, но в JS я ничего похожего не знаю =(

Автор: Непрофессионал 8.1.2004, 11:26
У меня получилось и вот так:

Код
<script TYPE="text/javascript"><!--
document.bgColor="#feffff";
 for(i=0;i<=8000;i++){
  document.write(i,"; ");
  if(i==100){document.write("<img src='C:/1.jpg'>");  }
 if(i==1800)alert("готовность");
 if(i==1802)document.images[0].src="C:/2.jpg";
 // пока не изменится фон, рисунок не перезагрузится, если комп. быстрый, числа
 //можно увеличить   чтобы было заметно ожидание
 if(i==2990)document.bgColor="#ffffff";
 /* это ещё не конец загрузки чисел в окно, следовательно, цикл не закончен
 но параллельно с изменением фона(!!!!) браузер согласен перезагрузить рисунок */

 if (i==8000)alert("8000");
 }
--></SCRIPT>


вместо alert меняем фон, думаю, много ещё чего подойдёт, числа я в цикле увеличил, чтобы видно было

забыл сказать - всё это у меня работает в MSIE 5.5. Опера скрипт не поняла (где-то есть ошибка, видимо или у меня или в Опере)

Автор: Sheff 8.1.2004, 21:50
Непрофессионал, а у меня не получилось, но я писал вот что:
Цитата

img = new Image();
img.src = 'http://...';
while (true)
{
if (img.complete) break;
document.bgColor="#ffffff";
}

Автор: Непрофессионал 9.1.2004, 12:12
Я догадываюсь, в чём дело. А оно может быть в том, что загрузка файла (признание его complete) это дело не браузера а ОС, виндовс или что там... Потому речь должна идти о многозадачности (параллельности) не на уровне ИЭ, а на уровне ОС. Потому оно и работает с alert, что прорисовка окна - дело ОС (стандартная функция операционной системы), а при изменении фона браузер сам рисует в собственном окне, не затрагивая ОС. Гипотеза - нужно найти такое действие вместо alert, которое, давало бы новую задачу ОС. Тут трудно предположить, что это может быть, я не настолько опытен - изменение размеров окна, создание нового, изменение размеров фрейма (на 1 пиксел) или что-то подобное, таких функция я не знаю
Я проверял, идёт ли запрос на сервер во время работы цикла, идёт, дело только в том, чтобы закончить цикл...

Автор: Sheff 9.1.2004, 20:35
Цитата
Я проверял, идёт ли запрос на сервер во время работы цикла, идёт

Уже хорошо, значит дело тока в этом грёбаном цикле, но как его закончить так чтобы без лишней фигни, не знаю, надо думать и много и не знаю можно ли вообще что-то придумать...

Автор: Непрофессионал 9.1.2004, 21:24
Не знаю, не подскажу, кроме последней моей гипотезы ничего в голову не приходит

Автор: Непрофессионал 11.1.2004, 00:32
Может быть, что функции работы со временем (таймер или что там...) подойдут - запустить несколько раз в цикле вместо alert - время то системное

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)