Javascript-форум (https://javascript.ru/forum/)
-   Ваши сайты и скрипты (https://javascript.ru/forum/project/)
-   -   Рекурсия и setTimeout() (https://javascript.ru/forum/project/21360-rekursiya-i-settimeout.html)

indian_fingers 06.09.2011 15:03

Рекурсия и setTimeout()
 
Требовалось написать слайдшоу. Главное условие - "лёгкость".
Я только начал осваивать js, да и программирование в целом, поэтому первый вариант был таков:
var i1=new Image(); i1.src="img/slideshow1/i1.jpg";
var i2=new Image(); i2.src="img/slideshow1/i2.jpg";
var i3=new Image(); i3.src="img/slideshow1/i3.jpg";
var i4=new Image(); i4.src="img/slideshow1/i4.jpg";
var i5=new Image(); i5.src="img/slideshow1/i5.jpg";
var i6=new Image(); i6.src="img/slideshow1/i6.jpg";
var i7=new Image(); i7.src="img/slideshow1/i7.jpg";
var i8=new Image(); i8.src="img/slideshow1/i8.jpg";
function op() { setTimeout("op9()",4000); }
function op9() { document.images.slide.style.opacity=0.9; setTimeout("op8()",speed); }
function op8() { document.images.slide.style.opacity=0.8; setTimeout("op7()",speed); }
function op7() { document.images.slide.style.opacity=0.7; setTimeout("op6()",speed); }
function op6() { document.images.slide.style.opacity=0.6; setTimeout("op5()",speed); }
function op5() { document.images.slide.style.opacity=0.5; setTimeout("op4()",speed); }
function op4() { document.images.slide.style.opacity=0.4; setTimeout("op3()",speed); }
function op3() { document.images.slide.style.opacity=0.3; setTimeout("op2()",speed); }
function op2() { document.images.slide.style.opacity=0.2; setTimeout("op1()",speed); }
function op1() { document.images.slide.style.opacity=0.1; setTimeout("slide()",speed); }
function slide() { if (!document.images) return; document.images.slide.src=eval("i"+step+".src"); if (step<8) step++; else step=1; setTimeout("o2()",speed); }
function o2() { document.images.slide.style.opacity=0.2; setTimeout("o3()",speed); }
function o3() { document.images.slide.style.opacity=0.3; setTimeout("o4()",speed); }
function o4() { document.images.slide.style.opacity=0.4; setTimeout("o5()",speed); }
function o5() { document.images.slide.style.opacity=0.5; setTimeout("o6()",speed); }
function o6() { document.images.slide.style.opacity=0.6; setTimeout("o7()",speed); }
function o7() { document.images.slide.style.opacity=0.7; setTimeout("o8()",speed); }
function o8() { document.images.slide.style.opacity=0.8; setTimeout("o9()",speed); }
function o9() { document.images.slide.style.opacity=0.9; setTimeout("o1()",speed); }
function o1() { document.images.slide.style.opacity=1; setTimeout("op9()",2500); }

Несмотря на дикость кода, он работал чётко и насиловал процессор в три раза меньше, чем его аналог на jQuery (стоит отметить, что на jQuery код получился гораздо изящнее в исполнении, но я от него отказался).
И вот последняя редакция первого варианта кода. Вроде всё должно работать, но почему-то функция slidePic() не хочет вызывать саму себя (т.е. происходит только первый вызов из функции loadPic()), хотя уже был опыт использования подобной рекурсии. Подозреваю, что дело может быть в setTimeout(), но медитация и курение мануалов пока не принесли результатов:
var step=2;
var speed=80;
var pic=new Object();
var countPic=8;
var arrPic=new Array();
var opc=9; var nav=0;
var app=navigator.appVersion.indexOf("MSIE");
function loadPic()
	{
	pic=document.getElementById("sl");
	for(i=1;i<countPic+1;i++)
		{
		arrPic[i]=new Image();
		arrPic[i].src="img/slideshow1/i"+i+".jpg";
		}
	setTimeout(slidePic,2500);
	}
function slidePic()
	{
	op=opc/10;
	pic.style.opacity=op;
	if(app>=0){op*=100;
	document.getElementById("sl").style.filter="progid:DXImageTransform.Microsoft.Alpha(opacity="+op+")";}
	else pic.style.opacity=op;
	if(nav==0)
		{
		if(opc==0)
			{
			pic.src=arrPic[step].src;
			if(step==countPic) step=1;
			else step++;
			opc=1; nav=1;
			setTimeout(slidePic,speed);
			}
		else
			{
			opc--;
			setTimeout(slidePic,speed);
			}
		}
	else
		{
		if(opc==10)
			{
			opc=9; nav=0;
			setTimeout(slidePic,2500);
			}
		else
			{
			opc++;
			setTimeout(slidePic,speed);
			}
		}
	}

Фрагмент html-разметки (в первом варианте по onload запускалась функция op()):
<body onload="loadPic()"><!--other content-->
<img src="img/slideshow1/i1.jpg" id="sl" name="slide"><!--other content--></body>

Не знаю как отловить ошибку.
И, конечно, буду благодарен за указания по оптимизации этого кода.

dmitriymar 06.09.2011 15:28

http://shamansir.github.com/JavaScript-Garden/#other

indian_fingers 06.09.2011 20:03

Статья неплохая. Убрал кавычки и параметры, код заработал (отредактировал исходный пост).

А вот какой из этих вариантов менее нагружает систему я ещё размышляю. Во втором варианте используется только одна функция, а в первом - 19. В то же время в первом варианте каждая из функций (кроме slide()) крайне примитивны, а во втором варианте каждый раз функция выполняет несколько (4-6) вычислений. Получается одна итерация "цикла" (одна фотография слайдшоу) в первом варианте использует 19 простых функций, а во втором 18 раз одну, но более сложную функцию. Опять же - 19 функций первого варианта постоянно занимают память.

Поправьте, если бред говорю.

Виктор Кон 08.09.2011 11:17

Посмотрите каталог моих фото-шоу вот тут http://kohnvict.narod.ru/b/ph-sh-list.htm, js код можно посмотреть в каждом файле. Все делается по javascript программе, там ссылка указана. А на моем сайте http://kohnvict.narod.ru есть анимация иконок каталога, все написано в книге http://xray-optics.ucoz.ru/vk-js-book.htm

Gozar 08.09.2011 11:36

Цитата:

Сообщение от Виктор Кон (Сообщение 125498)
Посмотрите каталог моих фото-шоу

Лучше не надо.
Виктор вы уж простите, но ваше слайдшоу глюкает если понажимать back в середине слайдшоу. Одно дело если вы пишете код для себя, другое вы предлагаете посмотреть другим. Вы не получите здесь признание, пока не прислушаетесь к мнению окружающих. Вы, казалось бы, взрослый человек - перестаньте плодить подобный код и уж тем более его пиарить, ведь форум читают даже дети, а вдруг они вам поверят на слово, что так писать хорошо?!

В своем мирке мы все божки.

Виктор Кон 08.09.2011 15:34

Про глюкает хотелось бы поподробнее, также хотелось бы понять чем мой код плохой, по крайней мере у меня setTimeout написано только один раз. Слово окружающие не есть синоним слова Gozar, а пиарят все, в том числе и вы. С кнопкой back никаких проблем нет, просто надо уметь пользоваться.

indian_fingers 08.09.2011 20:45

Я пока не смотрел вышеупомянутый сайт, но "С кнопкой back никаких проблем нет, просто надо уметь пользоваться" - это в корне неверная логика, так как большинство интернет посетителей даже не имеют понятия про яваскрипт и если код лагает в результате "не так нажал", то будьте уверены - не так нажимать будут постоянно.

Виктор Кон 08.09.2011 20:54

А вы просто посмотрите. Нет никаких глюков вообще. Это мне наговорили в другом посте. Кнопка back меняет направление показа на обратное, при этом нажимать ее надо всего один раз, если пять раз нажать - эффект тот же. А кто-то решил, что она при каждом нажатии меняет направление. Восстанавливает направление кнопка Start. Но большинство вообще не пользуется кнопками, это просто дополнительная редкая услуга.

indian_fingers 08.09.2011 21:04

Виктор, я был бы признателен вам, если вы напишите суть вашего кода слайдшоу, ибо разбирать чужой не хочу, нет сейчас времени и желания.
В моём варианте изначально слайдшоу не работает, а просто загружается изображение - это позволит быстрее загрузится странице, а лишь затем подгружаю остальные фото слайдшоу. Суть кода - через равные промежутки времени для
<img id="sl" />
меняется src с помощью уже имеющихся в памяти изображений. Для красоты добавил плавное изменение прозрачность, через изменение насыщенности. На данный момент я не знаю как сделать это слайдшоу менее тяжёлым для системы пользователя с сохранением плавности.

indian_fingers 08.09.2011 21:11

Ещё добавил ИЕ в список браузеров, обладатели которого смогут насладится моим слайдшоу, строками 7, 22 и 23. Ещё одна любопытная особеность - интернет эксплорер не хочет менять насыщенность через ссылку на объект, поэтому пришлось каждый раз обращатся прямо к объекту - строка 23. Мистика?


Часовой пояс GMT +3, время: 18:51.