Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Javascript и объект IMG = глюки

4.6K
26 января 2004 года
zetter
9 / / 10.10.2003
Вот такая задачка для господ программистов...
Есть программка, которая показывает картинки, точнее должна показывать картанки. Но делает она это не совсем правильно, а точнее, только со второго запуска. Вот что происходит:
Я написал функцию, проверяющую img.readystate и выходящую из самой себя когда "complete", выдавая алерт "done"
Попутно внедрил отладочный счетчик самовызовов функции. Кроме того, поставил печатать img.readystate после вызова функции.
Происходит совершенно загадочная вещь: при первом запуске этого скрипта происходит следующее: сначала выскакивает алерт "done", потом печатается undefined 1 и... все, белый экран, то есть картинки нет.
Закрываем окно браузера и снова запускаем этот файл. Наблюдается следущее: тут-же то есть мгновенно получаем алерт "done", печатется complete 0, потом показывается картинка.
Говорим "хорошо" и жмем reftesh. Наблюдается следущее: тут-же то есть мгновенно печатается - undefined 1, потом показывается картинка, а уж после всего этого - алерт done. Я не пойму - как это получается? Ведь функция checkPicture вызывается ДО ТОГО, как происходит выполнение document.write?
Причем, самое интересное, что если жать refresh несколько раз, то примерно с вероятностью 1:5 получаем вариант 2, то есть сначала алерт, потом надпись complete 0 и картинку.
Вот текст файла, над которым и проводились опыты.
Может кто поможет мне сделать то-же самое, но как-нибудь по другому? Или поправить что-то?

<HTML><HEAD><TITLE>picture show</TITLE>
<SCRIPT LANGUAGE="JavaScript"><!--

function calculate() {
if (document.images)
{
img = new Image();
img.src = "../images/picture.jpg" ;
}
if (document.all) h = document.body.clientHeight - 60;
else if (document.layers) h = window.innerHeight - 60;
else h = 640;
if (document.all) w_doc = document.body.clientWidth;
else if (document.layers) w_doc = window.innerWidth;
else w_doc = 640;
w = h * img.width / img.height;
if (w > w_doc) w = (w_doc - 20);
if (w > img.width) w = img.width;

return (w);
}

function checkPicture() {
if (img.readyState == 'complete') {
alert('Done');
rrr = img.readyState
return (rrr);
}
setTimeout('checkPicture()',100);
b = b + 1;
}
//-->
</script>
</HEAD>
<BODY>
<SCRIPT LANGUAGE="JavaScript"><!--
w = calculate();
b = 0;
a = 0;
a = checkPicture();
document.write (a, b);
document.write('<img src = "' + img.src + '" width="' + w + '" border="0">');
//-->
</script>
</BODY></HTML>
365
28 января 2004 года
MasterSID
230 / / 23.02.2003
Ты бы пояснил задачку подробнее. Как я понял ты хочешь что бы картинки показывались только после того, как загрузятся целиком?
4.6K
28 января 2004 года
zetter
9 / / 10.10.2003
Цитата:
Originally posted by MasterSID
Ты бы пояснил задачку подробнее. Как я понял ты хочешь что бы картинки показывались только после того, как загрузятся целиком?


Не совсем так... я хотел бы, чтобы картинки ПОКАЗЫВАЛИСЬ с первого раза. А тут получается, что с первого запуска - чичтый экран. Я закрываю окно, запускаю еще раз - все нормально! В чем грабли - не пойму!

365
28 января 2004 года
MasterSID
230 / / 23.02.2003
А кстати у меня картинки показываются с первого раза. Так если тебе просто нужно показать картинку, то зачем такие сложные манипуляции?
4.6K
28 января 2004 года
zetter
9 / / 10.10.2003
Цитата:
Originally posted by MasterSID
А кстати у меня картинки показываются с первого раза. Так если тебе просто нужно показать картинку, то зачем такие сложные манипуляции?


попробуй подсунь картинку пожирнее... типа 1600х1200 и размерчиком под 2 мегабайта и посмотри еще разок, что получится.

365
28 января 2004 года
MasterSID
230 / / 23.02.2003
Ну очевидно она просто будет очень долго загружаться и постепенно показываться, т.к. процесс передачи файлов вроде бы здорово отлажен в HTTP. Не знаю зачем тебе такой скрипт.
372
28 января 2004 года
Flying
312 / / 20.09.2000
Кстати, свойство readyState - это фишка IE, запусти свой скрипт где-нибудь еще, будет еще более интересный результат (в смысле ошибок JavaScript).

PS: нафига народ извращается, непонятно....
537
29 января 2004 года
Cover
87 / / 14.11.2002
Я тоже очень долго смотрел на твой чудо-скрипт, но так и не понял его чудесных свойств.
Но зато я заметил там интересные вещи, которые вобще не понятно зачем сделаны:

функцию calculate() пропускаем - там ничего страшного нету.

А дальше смотрим вместе, так сказать, по-шагово:

1 function checkPicture() {
2 if (img.readyState == 'complete') {
3 alert('Done');
4 rrr = img.readyState
5 return (rrr);
6 }
7 setTimeout('checkPicture()',100);
8 b = b + 1;
9 }

И что мы видим???
- если картинка большая, то на строчке 2 условие не срабатывает (следовательно alert тоже) и мы попадаем на строчку 7.
В 7-ой строке мы устанавливаем таймаут, увеличиваем b и ВЫХОДИМ ничего не возвращая. Таким образом, у нас a = НЕПОНЯТЬ_ЧТО, b=1 и вся эта фигня печатается в документ вместе с тэгом img - картинка грузится и выводится.
Но мы не забыли про то, что у нас в таймауте висит функция, поэтому по истечении 100мсек. она опять вызывается, есесно, картинка уже подгрузилась, поэтому на строчке 7 условие срабатывает - мы видим alert и функция возвращает "compleat" НЕПОНЯТЬ_КУДА.

Ну а при F5 всякие описанные тобой, катаклизмы получаются из-за кэширования катринок. Поэтому иногда у тебя картинка загружается сразу и всё ОК, а иногда всё так, как описано выше.
443
29 января 2004 года
REmindER
292 / / 23.03.2003
Цитата:
a = checkPicture();
document.write (a, b);



Это как, сначала в a пишется значение из функции checkPicture - естественно неизвестно какое, т.к. при первом старте функции картинка еще не загружена. Затем, без всяких проверок a на истину (в теории функция вернет истину при загрузке картинки) в документ пишется НЕОПРЕДЕЛЕННОЕ а и количество проверок, которое на момент записи равно 1 или 0, если картинка успела загрузиться до обращения к функции (при использовании кэша). Дальше идет строка:

Цитата:
document.write('<img src = "' + img.src + '" width="' + w + '" border="0">');


img.src - это путь к картинке, т.е. таким макаром картинка может быть загружена и без всяких функций.

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

<HTML><HEAD><TITLE>picture show</TITLE>
<SCRIPT LANGUAGE="JavaScript"><!--

b = 0;

function calculate() {
if (document.images)
{
img = new Image();
img.src = "../images/picture.jpg" ;
}
if (document.all) h = document.body.clientHeight - 60;
else if (document.layers) h = window.innerHeight - 60;
else h = 640;
if (document.all) w_doc = document.body.clientWidth;
else if (document.layers) w_doc = window.innerWidth;
else w_doc = 640;
w = h * img.width / img.height;
if (w > w_doc) w = (w_doc - 20);
if (w > img.width) w = img.width;
}

function checkPicture()
{
if(document.all("ds") != "undefined")
{
if (img.readyState == 'complete')
{
ds.innerHTML = '<img src = "' + img.src + '" width="' + w + '" border="0">';
alert('Done');
return;
}
b = b + 1;
if(b > 120)
{
ds.innerText = "Timeout exceeded.";
return;
}
ds.innerText = 'Overhead sent at ' + b + ' sec. before...';
setTimeout("checkPicture()", 1000);
return;
}
setTimeout("checkPicture()", 1000);
return;
}
//-->
</script>
</HEAD>
<BODY onLoad="calculate();checkPicture();">
<TABLE CELLPADDING = "1" BORDER = "1"><TR><TD>Image preloading.</TD></TR><TR><TD>
<DIV ID="ds"></DIV>
</TD></TR></TABLE>
</BODY></HTML>

4.6K
30 января 2004 года
zetter
9 / / 10.10.2003
Цитата:
Originally posted by REmindER


Это как, сначала в a пишется значение из функции checkPicture - естественно неизвестно какое, т.к. при первом старте функции картинка еще не загружена. Затем, без всяких проверок a на истину (в теории функция вернет истину при загрузке картинки) в документ пишется НЕОПРЕДЕЛЕННОЕ а и количество проверок, которое на момент записи равно 1 или 0, если картинка успела загрузиться до обращения к функции (при использовании кэша).


дык это я просто понавтыкал, чтобы видеть то, что происходит в скрипте. Может не очень грамотно понавтыкал, но тут уж как получилось :-))) В конечной версии никаких печатей и алертов просто не будет.

Цитата:
Originally posted by REmindER

img.src - это путь к картинке, т.е. таким макаром картинка может быть загружена и без всяких функций.


естественно, только эти картинки не успевают...

Цитата:
Originally posted by REmindER

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

<HTML><HEAD><TITLE>picture show</TITLE>
<SCRIPT LANGUAGE="JavaScript"><!--

skip


Блин! не работает. Я уж подумал на свою систему (w2k + 6ie) но вот щас прошелся по другим и все то-же самое. Проверял на w98+5ie, wme+6ie и w98+6ie. все один в один. Вот смотри, я приложил картиночку, вверху - то, что получается после первого запуска. Внизу - после второго запуска файла.

443
30 января 2004 года
REmindER
292 / / 23.03.2003
Работает, работает. Что выбрано у тебя в настройке Check for newer versions of stored pages? Прикол-то весь в этом самом кэше. Когда я ставлю на Never, картинка начинает грузиться из и-нета при записи в документ:
Цитата:
ds.innerHTML = '<img src = "' + img.src + '" width="' + w + '" border="0">';


Если ставлю на Automatic, то картинка отображается сразу после загрузки.

4.6K
30 января 2004 года
zetter
9 / / 10.10.2003
Цитата:
Originally posted by REmindER
Работает, работает. Что выбрано у тебя в настройке Check for newer versions of stored pages? Прикол-то весь в этом самом кэше. Когда я ставлю на Never, картинка начинает грузиться из и-нета при записи в документ:

Если ставлю на Automatic, то картинка отображается сразу после загрузки.


У меня этих картинок - навалом! Просто девать некуда :-) Поэтому я ПЕРЕД КАЖДЫМ ЗАПУСКОМ меняю номер картинки на следующий по порядку.
Следуя твоему совету, провел эксперимент: 3 запуска, каждый раз с новыми картинками, и с параметрами кеша:
1) при каждом посещении
2) автоматически
3) никогда
Ты будешь смеяться, но результат ПОЛНОСТЬЮ совпадает с тем, что я писал в предыдущем письме и полностью совпадает с картинкой, которую я присылал. :-((((
Я плакаль :-(

443
30 января 2004 года
REmindER
292 / / 23.03.2003
Цитата:
Originally posted by zetter

У меня этих картинок - навалом! Просто девать некуда :-) Поэтому я ПЕРЕД КАЖДЫМ ЗАПУСКОМ меняю номер картинки на следующий по порядку.
Следуя твоему совету, провел эксперимент: 3 запуска, каждый раз с новыми картинками, и с параметрами кеша:
1) при каждом посещении
2) автоматически
3) никогда
Ты будешь смеяться, но результат ПОЛНОСТЬЮ совпадает с тем, что я писал в предыдущем письме и полностью совпадает с картинкой, которую я присылал. :-((((
Я плакаль :-(


Использовал explorer 5.00 - все работает идеально. Картинка отображается сразу с сообщением Done!

443
30 января 2004 года
REmindER
292 / / 23.03.2003
Настройки Settings у меня такие:
4.6K
30 января 2004 года
zetter
9 / / 10.10.2003
Цитата:
Originally posted by REmindER
Настройки Settings у меня такие:


ага, ну так я говорю - ставил и то и другое... и третье.
И на четырех компах пробовал.
Попробуй подсунь картинку пожирнее... типа 1600х1200 или побольше, да и размерчиком под 2-3 мегабайта и посмотри еще разок, что получится.
Я уже месяца 3 бьюсь, чего только не перепробовал - проблема остается. И систему за это время переставлял, все равно не помогает. Книгу, блин, купил тоооолстючую про JavaScript - нифига!
Вот и думаю....
Давай попробуем так - вот смотри, самый первый вариант, безо всяких там функций и таймаутов. Попробуй, что будет? Покажет с первого раза?

<HTML><HEAD>
<TITLE>pic</TITLE>
</HEAD>
<BODY bgcolor="#CCCCCC" text="#000000" link="#0000FF" vlink="#800080" alink="#FF0000" >
<CENTER>
<SCRIPT LANGUAGE="JavaScript"><!--
if (document.images)
{
img = new Image();
img.src = "../images/picture001.jpg" ;
}
if (document.all) h = document.body.clientHeight - 60;
else if (document.layers) h = window.innerHeight - 60;
else h = 640;
if (document.all) w_doc = document.body.clientWidth;
else if (document.layers) w_doc = window.innerWidth;
else w_doc = 640;
w = h * img.width / img.height;
if (w > w_doc) w = (w_doc - 20);
if (w > img.width) w = img.width;
document.write('');
//-->
</script>
</center></BODY></HTML>

443
30 января 2004 года
REmindER
292 / / 23.03.2003
Давай-ка обратим внимание вот сюда:
Цитата:

function calculate() {
if (document.images)
{
img = new Image();
img.src = "http://foto.yarnet.ru/photo/animals/photo_13.jpg" ;
}
if (document.all) h = document.body.clientHeight - 60;
else if (document.layers) h = window.innerHeight - 60;
else h = 640;
if (document.all) w_doc = document.body.clientWidth;
else if (document.layers) w_doc = window.innerWidth;
else w_doc = 640;
w = h * img.width / img.height;
if (w > w_doc) w = (w_doc - 20);
if (w > img.width) w = img.width;


Получается, что вычисление w начинается при НЕЗАГРУЖЕННОЙ картинке, т.е. данные о ширине и высоте НЕОПРЕДЕЛЕНЫ!!! Дальше ты пишешь:

Цитата:
ds.innerHTML = '<img name = "img1" width="' + w + '" border="0">';


И получаешь в параметре width чушь! На самом деле картинка загрузится, но ее ширина будет 0, поэтому ты видишь в таблице на месте картинки какую-то точку. При перезагрузке старницы эта картинка на момент расчета w будет существовать в кэше и все отобразится правильно.

4.6K
30 января 2004 года
zetter
9 / / 10.10.2003
Цитата:
Originally posted by REmindER

Получается, что вычисление w начинается при НЕЗАГРУЖЕННОЙ картинке, т.е. данные о ширине и высоте НЕОПРЕДЕЛЕНЫ!!!

И получаешь в параметре width чушь! На самом деле картинка загрузится, но ее ширина будет 0, поэтому ты видишь в таблице на месте картинки какую-то точку. При перезагрузке старницы эта картинка на момент расчета w будет существовать в кэше и все отобразится правильно.


Золотые слова! Я до такого-же точно расклада дошел только через месяц наверное! вот что значит профессионал!
Вот теперь пытаюсь затормозить вычисление w до полной загрузки картинки... для того и весь этот геморрой, но нифига не выходит. Помоги, а?

443
30 января 2004 года
REmindER
292 / / 23.03.2003
Да к в чем проблема:

<HTML><HEAD><TITLE>picture show</TITLE>
<SCRIPT LANGUAGE="JavaScript"><!--

b = 0;
h = 0;
w_doc = 0;

function calculate() {
if (document.images)
{
img = new Image();
img.src = "../images/picture.jpg" ;
}
if (document.all) h = document.body.clientHeight - 60;
else if (document.layers) h = window.innerHeight - 60;
else h = 640;
if (document.all) w_doc = document.body.clientWidth;
else if (document.layers) w_doc = window.innerWidth;
else w_doc = 640;
}

function checkPicture()
{
if(document.all("ds") != "undefined")
{
if (img.readyState == 'complete')
{
w = h * img.width / img.height;
if (w > w_doc) w = (w_doc - 20);
if (w > img.width) w = img.width;
ds.innerHTML = '<img name = "img1" width="' + w + '" border="0">';
document.images['img1'].src = img.src;
alert('Done');
return;
}
b = b + 1;
if(b > 120)
{
ds.innerText = "Timeout exceeded.";
return;
}
ds.innerText = 'Overhead sent at ' + b + ' sec. before...';
setTimeout("checkPicture()", 1000);
return;
}
setTimeout("checkPicture()", 1000);
return;
}
//-->
</script>
</HEAD>
<BODY onLoad="calculate();checkPicture();">
<TABLE CELLPADDING = "1" BORDER = "1"><TR><TD>Image preloading.</TD></TR><TR><TD>
<DIV ID="ds"></DIV>
</TD></TR></TABLE>
</BODY></HTML>
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог