воскресенье, 28 сентября 2008 г.

JavaScript слайдшоу своими руками

Недавно мне потребовалось для одного сайта создать слайдшоу на JavaScript, но сделать его похожим на другое, сделанное во Flash. Переход между фотографиями - простой фейдаут и во флеше это делается за 5 минут, а вот с яваскриптом это немного более проблематично - тем более, что нужно было это сделать кроссбраузерно. Вначале поискал в Гугле и нашел немало красивых фотогалерей и слайдшоу, но все это было не то - то слишком наворочено, то нужно все время кликать для перехода к следующей фотографии; было также одно слайдшоу, которое вроде и делало все так как надо и работало отлично, но использовало jQuery но как-то было не совместимо с той версией jQuery, которая установлена в Wordpress 5.2, на котором был сделано тот сайт, а переустановка jQuery тоже не решала проблемы, так как с новой версией переставал работать LightBox. В довершение ко всему обнаружил, что судя по описанию внутри файлов этих двух версий jQuery, они имеют один номер сборки... хотя размеры файлов отличаются почти в два раза. Из этого я сделал вывод, что, видимо, разработчики Wordpress изменили код jQuery, забыв указать это где-либо.
Но что-то я отвлекся....
Столкнувшись с такой вот загвоздочкой, я решил, что напишу такое слайдшоу сам. И спустя пару часов пыхтения над яваскриптом - добился желаемого эфекта. РЕЗУЛЬТАТ МОЖНО ВИДЕТЬ ОДНОВРЕМЕННО НИЖЕ И СПРАВА ВВЕРХУ







Кстати, размеры этих рисунков я менял с помощью уже описанной мною программы xnView


Ниже приведу код этого слайдшоу:



<style>
#slide-container {
text-align:center;
margin:20px 0px;
}
#slide-container #slideshow {
width:400;
height:300px;
margin:auto;
position:relative;
}
#slide-container #slideshow IMG {
position:absolute;
top:0;
left:0;
}
</style>

<script>
function animate(tagId,alfa,step){
div = document.getElementById(tagId);
var items = new Array();
//Выбираем все рисунки слайдшоу
for(c=i=0;i<div.childNodes.length;i++){
if (div.childNodes[i].tagName=="IMG"){
items[c] = div.childNodes[i];
c++;
}
}
last = items[items.length-1];
next = items[items.length-2];
//делаем верхний в стопке(текущий) рисунок более прозрачным
last.style.opacity= alfa/100;
last.style.filter= "progid:DXImageTransform.Microsoft.Alpha(opacity="+alfa+")";
last.style.filter= "alpha(opacity="+alfa+")";

if ((alfa-step)>0){
//если еще не достигли полной прозрачности верхнего рисунка - продолжаем анимацию
setTimeout("animate('"+tagId+"',"+(alfa-step)+","+step+");",50);
}else{
//если достигли полной прозрачности верхнего рисунка
//делаем абсолютно непрозрачным следующий рисунок
next.style.opacity= 1;
next.style.filter= "progid:DXImageTransform.Microsoft.Alpha(opacity=100)";
next.style.filter= "alpha(opacity=100)";
// а верхний рисунок перемещаем в низ стопки
tmp = last;
div.removeChild(last);
div.insertBefore(tmp,items[0]);
tmp.style.opacity= 1;
tmp.style.filter= "progid:DXImageTransform.Microsoft.Alpha(opacity=100)";
tmp.style.filter= "alpha(opacity=100)";

setTimeout( "slideSwitch('"+tagId+"',1000)", 8000 );
}
}
//эта функция делает видимым блок с рисунками для слайдшоу (изначально он невидим, чтобы избежать мерцания во время загрузки картинок) и запускает анимацию
function slideSwitch(tagId,speed){
div = document.getElementById('slideshow');
if (div.style.visibility!="visible"){
div.style.visibility = "visible";
}
items = div.getElementsByTagName('img');
if (items.length>0){
animate(tagId,100,10);
}
}
//выжидаем пару секунд, чтобы картинки успели загрузиться... можно просто поставить на onload-событие последнего из рисунков
setTimeout( "slideSwitch('slideshow',1000);",2000 );
</script>

...
...
...

<div id="slide-container">
<div id="slideshow">
<img src="..."/>
<img src="..."/>
...
<img src="..."/>
</div>
</div>



Если кому-то захочется сделать слайдшоу с рисунками в виде ссылок, можно заменить в коде div.childNodes[i].tagName=="IMG" на div.childNodes[i].tagName=="A" или div.childNodes[i].tagName=="DIV" ;)

Вот, немного изменил скрипт, таким образом, что на одной странице может одновременно проигрываться несколько слайдшоу, с одинаковой или разной скоростью, например одно слайдшоу на этой странице в сайдбаре справа вверху, а другое - в тексте статьи. Нужно только указать ID родительского DIV'a.

Экспериментируйте!

103 коммент.:

Анонимный комментирует...

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

Камынин Дмитрий комментирует...

я рад, что вы нашли в моем блоге то, что искали! А, что касается проблемы со слайдшоу... это моя ошибка, я забыл вставить код CSS стилей, исправлю это в ближайшее время. Если есть какие-либо пожелания по поводу улучшения слайдшоу в частности и всего сайта в общем - буду рад выслушать

Владимир комментирует...

Все бы хорошо, вот только в ИЕ6 не пашет крипт :(

Владимир комментирует...

т.е. скрипт :)

Камынин Дмитрий комментирует...

Только что слайдшоу в теле статьи совсем не работало (в сайдбаре работало) - моя вина - поставил вызов функции раньше ее опредиления... и если опредиление функции еще не успело догрузиться - возникает ошибка. Уже исправил.
А по поводу ИЕ6 - в ближайшее время проверю и исправлю. Обязательно будет работать - ведь еще не так мало людей им пользуется... к сожелению ;)

Владимир комментирует...

Скрипт хорош, хотя бы тем что он прост в установки и не обращается ни к одной из известных библиотек (prototype, jquery ..), вынести в отдельный файлик и можно любоваться результатом :)

Камынин Дмитрий комментирует...

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

Анонимный комментирует...

все это конечно хорошо и красиво а вот как это слайд-шоу разместить в таблице???

Камынин Дмитрий комментирует...

Если я правильно понял, что Вы имеете в виду, говоря "разместить в таблице", то очень просто :) Примерно вот так :

<table>
<tr>
<td>

<div id="slide-container">
<div id="slideshow">
<img src="..."/>
<img src="..."/>
...
<img src="..."/>
</div>
</div>

</td>
...
</tr>
...
</table>


и в раздел HEADER вынести весь блок SCRIPT(в принципе, наверное даже лучше разместить его в разделе BODY после slide-container)

Анонимный комментирует...

Благодарю Дмитрий..... очень помог совет.....
но будет еще вопрос...
рядом с этим слайд-шоу хочу выложить картинку..... не получается..... выходит как бы за рамки сайта эта картинка....
получается она либо выше сайта либо с правого края..... если с правого края она то между слайдами и картинкой остается пустое место....
делаю новую колонку после слайд-шоу нечего не получается.... (((
можно ли как нибудь "привязать" картинку к определенному месту на экране?? ))) смысле описать координаты..... извиняюсь если чушь сморозил )))) заранее благодарен.....

Камынин Дмитрий комментирует...

Во-первых эта картинка должна находится ЗА ПРЕДЕЛАМИ тега <div id="slideshow">...</div>
Во-вторых, если Вы хотите разместить картинку по опредиленным координатам на экране, то это можно сделать с помощью стилей, например так:
<img src="<путь к картинке>" style="position:absolute;left:100px;top:200px;">

Таким образом Вы разместите картинку по координатам x=100;y=200; отсчитывая от левого верхнего угла.

То же самое можно сделать вынеся стили в отдельный блок:
<style>
#my-image {
position:absolute;
top:100px;
left:200px;
}
...
<другие стили>
...
</style>
...
<img id="my-image" src="<путь к рисунку>">

Если же Вы хотите разместить эту картинку, например, справа от слайдшоу и при этом хотите использовать таблицы, то можно и так:
<table>
<tr>
<td>
<div id="slid-container">
....
</div>
</td>
<td>
<img src="адрес Вашего рисунка">
</td>
</tr>
</table>

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

Анонимный комментирует...

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

Камынин Дмитрий комментирует...

По-поводу отображения одного и того же сайта в разных браузерах по разному - это извечная проблема... Дело в том, что все производители браузеров придерживаются спецификаций только частично и к тому же каждый пытается продвинуть свои технологии, чтобы они были утверждены в следующей версии спецификации.
Больше всего проблем создает, как всегда Експлорер. Проще всего привести к одному виду страницу в Opera, Firefox и даже Safary(от Mac)&Chrome(от Google), а вот для Internet Explorer (IE) иногда даже приходится писать отдельные файлы со стилями и иногда применять так-называемые хаки(куски кода, выполняемые только опредиленными браузерами).
Таблицами же не пользуюсь потому, что их поведение контролировать очень сложно. Например, вы создали страницу из трех колонок с помощью таблицы, имеющей три колонки - боковые колонки по 200 пикселей, а центральная - все остальное. А теперь представим, что пользователь в комментарий к странице вставил картинку шириной в 2000 пикселей.... таблица, даже не смотря на указанную ширину будет растянута так, чтобы вместить всю картинку, при этом боковые колонки будут сплющены и будут занимать меньше указанных им 200 пикселей...
Вот поэтому я и стараюсь не использовать таблицы.
Конечно если Вы добавляете весь контент сами и контролируете все добавляемое содержимое, то вы можете проконтролировать чтобы добавляемый контент не нарушал отображение дизайна страницы... однако зачастую это тоже не так просто.
Дизайн на основе DIVов с листами стилей гораздо проще проконтролировать, хотя при этом сам процесс макетирования(верстки) немного усложняется.
Посоветуйте, может стоит отдельной статьей описать принципы верстки и разницу между версткой на дивах и в таблицах?

Камынин Дмитрий комментирует...

Только что обнаружил, что слайдшоу не работало в IE 7(как минимум)...
Причина оказалась настолько глупой, что остается только диву даваться, как вообще хоть что-то работает в IE?!

Оказывается експлореру не нравятся использование внутри функций переменных с именем "item"... Ну не глупость ли?!
Теперь все работает - переименовал переменную в "items" и все заработало!!!

Анонимный комментирует...

Спасибо большое за скрипт!!! А как все-таки разместить несколько слайд-шоу на одной странице? Через изменение Родительского DIV как-то не очень получилось... :):):)

Shock комментирует...

Очень просто - для каждого из слайдшоу создаем отдельный DIV для каждого из слайдшоу, при этом не забываем дописывать стили и вызываем для каждого из них функцию slideSwitch.
Покажу на примере:


<style>
#slide-container1,
#slide-container2 {
text-align:center;
margin:20px 0px;
}
#slide-container1 #slideshow1,
#slide-container2 #slideshow2 {
width:...px;
height:...px;
margin:auto;
position:relative;
}
#slide-container1 #slideshow1 IMG,
#slide-container2 #slideshow2 IMG {
position:absolute;
top:0;
left:0;
}
</style>

ПЕРВОЕ СЛАЙДШОУ
<div id="slide-container1">
<div id="slideshow1">
<img src="..."/>
<img src="..."/>
...
<img src="..."/>
</div>
</div>

ВТОРОЕ СЛАЙДШОУ
<div id="slide-container2">
<div id="slideshow2">
<img src="..."/>
<img src="..."/>
...
<img src="..."/>
</div>
</div>

и для запуска слайдшоу:

<script>
setTimeout( "slideSwitch('slideshow1',1000);",2000 );
setTimeout( "slideSwitch('slideshow2',2000);",2000 );
</script>

Что-то вроде этого!!!

Shock комментирует...

Кстати! Если не трудно - оставляйте ссылки на сайты где вы размещаете слайдшоу - мне просто хотелось бы увидеть его в действии.
Если же Вам действительно ОЧЕНЬ понравилось это слайдшоу - то разместите на своем сайте ссылочку на мой блог - мне будет приятно. Но это конечно же только по желанию ;) Я, например, написал это слайдшоу для испанского сайта Hotel Spa Armuña Oasis

Анонимный комментирует...

Спасибо! Как оказывается все просто...и даже работает...:)

Анонимный комментирует...

А как можно на этой основе сделать смену обоев рабочего стола. Что бы брались файлы по очереди (или в перемешку) из определенной папки и каждые 5 мин. плавно менялись?
Спасибо.

Shock комментирует...

По поводу размещения такого слайд-шоу на рабочий стол... В принципе для этого есть специальные программы, а в Висту, если не ошибаюсь встроена такая возможность. НО если Вы все же хотите сделать это с помощью такого скрипта, то сделать так, чтобы брались файлы из папки по-очереди - не получится - в JavaScript нет доступа к просмотру файловой системы из соображений безопасности. Единственное, что можно сделать, это кинуть все рисунки в один DIV, запустить слайдшоу, и страничку, на которой все это находится поместить на рабочий стол (возможность помещать веб-страницы на рабочий стол есть начиная с Windows 98, если не ошиаюсь) Делается это там же где и устанавливается рисунок Рабочего Стола, но только в разделе "Дополнительно".
Успехов!

B@c!fer комментирует...

А как сделать чтобы скрипт работал ток когда на него мышь наведена?

Shock комментирует...

Сделать так, чтобы слайдшоу запускалось только при наведении на него мышью можно так:

...
var sh=false;
function animate(tagId,alfa,step){
...
if (sh)
setTimeout( "slideSwitch('"+tagId+"',1000)", 8000 );
...
}
...
<div id="slide-container1" onmouseover="sh=true;setTimeout( \"slideSwitch('slideshow1',1000);\",100 );" onmouseout="sh=false;">
<div id="slideshow1">
...
</div>
</div>

Жирным выделены добавленные части кода. Таким образом, слайд-шоу должно запускаться при наведении мышью на него и останавливаться при убирании мыши.
Код писал сходу, так что возможны опечатки, но идея в целом такова.

Arhangel комментирует...

И всё таки как сделать несколько слайдшоу на странице без созадния дополнительных стилей для каждго слайдшоу? Очень надо

Arhangel комментирует...

Решил проблему сам.
В функции slideSwitch(tagId,speed)
заменил div = document.getElementById('slideshow'); на div = document.getElementById(tagId);
а стили прописал в самих єлементах

pravokriliy комментирует...

Спасибо!
Именно то что искал! Просто в точку!

grok.ru комментирует...

Да, отличный скрипт, взял на заметку.

Анонимный комментирует...

не получается создать 3 слайда.

Ставлю как написано контейнеры в ячейки таблицы. Получается что попало, мягко говоря. Вот код:

Блин что за хрень не могу код НТМЛ вставить

Shock комментирует...

да, со вставкой HTML тут проблема...
Я вставляю коды html, заменяя угловые скобки тегов на & lt; (<) и & gt; (>)
без пробелов, конечно же.
Например: <div class="slideshow">

Shock комментирует...

А теперь о самом вопросе...

Чтобы более точно понять, что у Вас не получается, объясните, что у вас получается :) например: вместо слайдшоу появляются все картинки. Или не появляется вообще ничего.
Объясните подробнее.

Анонимный комментирует...

С одним слайд шоу все нормально. Точнее почти нормально. Дримвивер сохраняет ШТМЛ только после долгой и упорной ругани в мой адрес:) Что ему не нравится так и не понял.

Несколько не пашут. Как не бьюсь:(
Вот код <> заменены на ()

(html)
(head)
(style)
#slide-container1,
#slide-container2 {
text-align:center;
margin:20px 0px;
}
#slide-container1 #slideshow1,
#slide-container2 #slideshow2 {
width:200px;
height:200px;
margin:auto;
position:relative;
}
#slide-container1 #slideshow1 IMG,
#slide-container2 #slideshow2 IMG {
position:absolute;
top:0;
left:0;
}
(/style)

(script)
function animate(tagId,alfa,step){
div = document.getElementById(tagId);
var items = new Array();
//Выбираем все рисунки слайдшоу
for(c=i=0;i(div.childNodes.length;i++){
if (div.childNodes[i].tagName=="IMG"){
items[c] = div.childNodes[i];
c++;
}
}
last = items[items.length-1];
next = items[items.length-2];
//делаем верхний в стопке(текущий) рисунок более прозрачным
last.style.opacity= alfa/100;
last.style.filter= "progid:DXImageTransform.Microsoft.Alpha(opacity="+alfa+")";
last.style.filter= "alpha(opacity="+alfa+")";

if ((alfa-step))0){
//если еще не достигли полной прозрачности верхнего рисунка - продолжаем анимацию
setTimeout("animate('"+tagId+"',"+(alfa-step)+","+step+");",50);
}else{
//если достигли полной прозрачности верхнего рисунка
//делаем абсолютно непрозрачным следующий рисунок
next.style.opacity= 1;
next.style.filter= "progid:DXImageTransform.Microsoft.Alpha(opacity=100)";
next.style.filter= "alpha(opacity=100)";
// а верхний рисунок перемещаем в низ стопки
tmp = last;
div.removeChild(last);
div.insertBefore(tmp,items[0]);
tmp.style.opacity= 1;
tmp.style.filter= "progid:DXImageTransform.Microsoft.Alpha(opacity=100)";
tmp.style.filter= "alpha(opacity=100)";

setTimeout( "slideSwitch('"+tagId+"',1000)", 1000 );
}
}
//эта функция делает видимым блок с рисунками для слайдшоу (изначально он невидим, чтобы избежать мерцания во время загрузки картинок) и запускает анимацию
function slideSwitch(tagId,speed){
div = document.getElementById('slideshow');
if (div.style.visibility!="visible"){
div.style.visibility = "visible";
}
items = div.getElementsByTagName('img');
if (items.length)0){
animate(tagId,100,10);
}
}
//выжидаем пару секунд, чтобы картинки успели загрузиться... можно просто поставить на onload-событие последнего из рисунков
setTimeout( "slideSwitch('slideshow1',1000);",2000 );
setTimeout( "slideSwitch('slideshow2',2000);",2000 );
(/script)
(/head)
(body)
(div id="slide-container1") (div id="slideshow1")
(img src="1.gif"/)
(img src="2.gif"/)
(/div)(/div)

(div id="slide-container2") (div id="slideshow2")
(img src="3.gif"/)
(img src="4.gif"/)
(/div)
(/div)

(/body)
(/html)

Eidelman комментирует...

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

Анонимный комментирует...

А как все-таки сделать, чтобы картинки стали ссылками? я убился - или ссылки не получаются, или шоу не идет. Кроме замены на div.childNodes[i].tagName=="A" нужно еще что-то, а что именно? Спасибо?

Anita комментирует...

Здравствуйте,
Спасибо за слайдшоу, то сто я искала. К сожалению, владею только минимальным уровнем даже хтмла.. а тут надо сайт построить отцу...
Буду очень признателна, если посмотрите, конечно если Вам не сложно, что не так со слайд-шоу, оно то мельком пробигает фо фотам, то остается на первой.

http://valery-photos.ucoz.com/index/0-1

Анонимный комментирует...

Доброе время суток!
Заметил проблемный момент.
Особенно в эксплорере он проявляется.
Быстро пролистываются все картинки подряд которые в списке. По идее я думал загрузится первая картинка дергаться ничего не будет и потом пойдет слайд шоу. Вот где применил ваш скрипт inworkgraphics.ru/
Может что неправильно вставил?
Сергей

Shock комментирует...

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

Shock комментирует...

А теперь на вопрос Аниты...
Попытаюсь Вам помочь... Просмотрев исходный код Вашей страницы первое что бросилось в глаза: до тега <html> не должно быть ничего кроме DOCTYPE у Вас же там идет объявление SCRIPT... так работать ничего не будет...
Второе - уберите угловую скобку перед <function
Третье - около 50-ой строки кода страницы вставлены ваши картинки <img ... > оттуда их нужно удалить - это раздел скриптов, html текст там недопустим. И в конце раздела script 83-я строка удалите <br>

Возможно, что после устранения этих ошибок что-то заработает ;)

К тому же хотел бы обратить внимание на то как отображается страница в Firefox... Старайтесь проверять страницы в Internet Explorer и Firefox - на данный момент это самые используемые браузеры

Анонимный комментирует...

Здравствуйте!
Попробовал Ваш скрипт и тоже воткнулся в проблему с двумя слайдшоу.
Вот тут http://peterburg-kino.spb.ru/rep.php все работает, а http://peterburg-kino.spb.ru/rep2.php - уже нет.
Сайт верстал не я, он сделан шибко криво, поэтому слайдшоу подверстано в конце, но одно почему-то работает - а два не хотят =(
Если поможете, буду очень признателен.

Katya комментирует...

Shock, огромное вам спасибо за скрипт! Очень красиво, и просто устанавливать! Вот пример, как я его использовала:
http://www.protea.ru/biznes.htmНо у меня та же проблема, что у предпоследнего Анонимного - сначала все картинки быстро-быстро пролистываются. Как сделать, чтобы ничего не показывалось до полной загрузки всех картинок?
Заранее спасибо:)

Shock комментирует...

По-поводу http://peterburg-kino.spb.ru

Похоже во втором варианте Вы забыли вставить

setTimeout( "slideSwitch('slideshow1',1000);",2000 );
setTimeout( "slideSwitch('slideshow2',1000);",2000 );

Shock комментирует...

Что касается того, чтобы не отображать слайдшоу до полной загрузки картинок, попробуйте в css добавить
#slide-container #slideshow {
visibility: hidden;
}

и в последний img слайдшоу желательно дописать
<img ... onload="document.getElementById('slideshow').style.visibility='visible';">

Анонимный комментирует...

"По-поводу http://peterburg-kino.spb.ru

Похоже во втором варианте Вы забыли вставить"
Пардон, это я убрал для проверки, вернул на место, но не заработало =(

Shock комментирует...

По-поводу http://peterburg-kino.spb.ru

попробуйте убрать br между картинками...
и вызовы

setTimeout( "slideSwitch('slideshow1',1000);",2000 );
setTimeout( "slideSwitch('slideshow2',1000);",2000 );

лучше ставить ПОСЛЕ дивов слайд-шоу.

Других ошибок пока не вижу.

Анонимный комментирует...

По-поводу http://peterburg-kino.spb.ru

попробуйте убрать br между картинками...
и вызовы

Спасибо за советы, но, к сожалению, и к удивлению, не заработало... Есть еще идеи?? Простите за назойливость =)

Анонимный комментирует...

По-поводу http://peterburg-kino.spb.ru
разобрался!! Внутри функции SlideSwitch тоже прописан конретное слайдшоу, то есть ее тоже надо продублировать. Спасибо!

Анонимный комментирует...

Точнее надо в этой функции
function slideSwitch(tagId,speed){
div = document.getElementById('slidehow');
поменять 'slideshow' на tagId.

Katya комментирует...

Спасибо, идея с тем, чтобы скрыть все при помощи visibility помогла. Только пришлось сделать не совсем так, как в совете, т.к. скрыть div не получается, приходится скрывать сами картинки:

1. сначала скрываем все картинки последовательности:
#slide-container #slideshow IMG {
visibility:hidden;
position:absolute;
top:0;
left:0;
}

2. Открываем их уже непосредственно перед тем, как начать делать прозрачной предыдущую. Для этого я добавила такуие строчки в код:
last = items[items.length-1];
next = items[items.length-2];
last.style.visibility='visible'; // вот эту
next.style.visibility='visible'; // и вот эту
last.style.opacity= alfa/100;

Как лучше сделать - уже не знаю :)

Shock комментирует...

Katya, делайте так, как Вам удобнее, тем более если работает :)

Анонимный комментирует...

А ведь Катя то права, ее совет действено помогает. При совете автора все равно рябление было. Правда у меня показ шоу начиналсся не 1.jpg а с 10, но переименовать то картинки то просто.
Спасибо автору и общественности. Еще бы картинки менялись более плавно, если это регулируется, то в какой строке?

Shock комментирует...

По поводу плавности смены картинки...
Третий параметр в функции
animate(tagId,100,10);
отвечает за шаг смены прозрачности картинки... Поставте меньшее число чтобы сделать смену плавной...
Лучше выбрать это число так, чтобы оно было делителем 100(1,2,5,10,20,25,50)

alexeyblohin комментирует...

Еще раз огромное спасибо. Вариант с делителем 5 показался мне самым удачным, на 2 - чуть не уснул, красиво-плавно, но долго.
У вас кстати нет подобного примера, поэтому привожу, я использовал ваш скрипт для дизайна header блока сайта, облегчил тем самым себе работу (отпала необходимость колдовать с флэш) http://www.salusclinic.ru/ . Танцы с "скрыть все при помощи visibility " решил просто сократив количество картинок до разумного.

Анонимный комментирует...

а вы не могли бы подсказать как сделать тоже самое только с текстом?!

то есть чтобы текст так же плавно менялся...

буду очень признателен
мой ящик volkodav@ymail.com

Анонимный комментирует...

Добрый день, облазил страниц 40 в поисках такого скрипта, спасибо за него! То что нужно! Только не понял как сделать чтобы текст плавно обтекал меняющуюся картинку? У меня в css прописан раздел для картинок в тексте:
#main .picture {
float:right;
padding: 2px;
border-style:solid; border-width:2px;
margin:10px 0 0 10px;
border-color:#a3461d;
}

и при размещении дивов картинка просто становится ниже текста в середине и после нее снова идет текст. Подскажите как изменить Ваши стили, чтобы добиться такого результата? Сам пробовал - не получилось, то картинки размножатся, то ещё какая напасть приключится :(

Владимир "ловец" Вишневский комментирует...

Спасибо за код. Мне как человеку далекому от программирования он очень помог.
Слайд-шоу торчит на главной странице.

Вопрос в том, как заставить показывать случайную картинку, а не по порядку.
Мозгами понимаю что надо прикрутить генератор случайных чисел, чтобы порядок был не fotoN+1 (где номер показанной в данный момент картинки), а fotoN, где N - случайное число в диапазоне от и до...

Shock комментирует...

По-поводу обтекания текстом слайдшоу...
float: right нужно добавить к контейнеру слайдшоу, а не к картинке... например, вот так:

#slide-container {
float:right;
}

К слову, так же важно разместить слайдшоу раньше по коду текста, который должен обтекать картинки

Shock комментирует...

Что же касается появления картинок в случайном порядке, то это несколько сложнее. Тут нужно немного переделать саму концепцию слайдшоу и одним циклом или n+1 не обойтись... дайте подумать - скоро отвечу

Olga комментирует...

Спасибо за скрипт, очень помог :) Все просто и красиво!
Оставляю ссылочку страницы, где использовала Ваш скрипт
http://n-chhotel.com/

[DOT] комментирует...

Для генерации случайных чисел используются обьект Math.
ниже представлены два способа, второй более предпочтителен.
Math.floor(Math.random() *(n+1))
Math.floor(Math.random() *n)+1;

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

Shock комментирует...

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

Последние пару недель времени нет заняться... но в скором времени будет сделано...

Кстати, собираюсь перенести блог, а то здесь нельзя файлы вылаживать, код неудобно писать и т.д.

wd400 комментирует...

Всем привет!
такой вопрос можно-ли выложить весь этот скрипт в css, а

(div id="slide-container1">
(div id="slideshow1">(img src="..."/>
(img src="..."/>
...
(img src="..."/>
(/div>
(/div>

оставить в html?
всем Спасибо.

Shock комментирует...

Можно и даже желательно... но только не только в css, а и в js - все, что находится между <script> и </script> выносим в js , а все что между <style> и </style> выносим в css... Просто данный блог не позволяет вылаживать файлы, поэтому написал все здесь все вместе.

moxhatbi4 комментирует...

День добрый!

В коде Вы написали, что:
//выжидаем пару секунд, чтобы картинки успели загрузиться... можно просто поставить на onload-событие последнего из рисунков
Вы не могли бы показать, как это реализовать? К сожалению, я не очень силен в js :(

P.S.: Случайный порядок картинок решил так:
Вставил вместо
<div id="slide-container">
<div id="slideshow">
<img src="..."/>
<img src="..."/>
...
<img src="..."/>
</div>
</div>

Вот это:
<?php
$arrayimg = array (
"img-01.jpg", "img-02.jpg", ..., "veg-xx.jpg"
);
shuffle($arrayimg);
foreach ($arrayimg as $img) {
echo "<img src='/images/$img'/>";
}
php?>

moxhatbi4 комментирует...

Прошу прощение, в предыдущем листинге не взял php-код в div'ы вот так:
<div id="slide-container">
<div id="slideshow">
<?php
$arrayimg = array (
"img-01.jpg", "img-02.jpg", ..., "veg-xx.jpg"
);
shuffle($arrayimg);
foreach ($arrayimg as $img) {
echo "<img src='/images/$img'/>";
}
php?>
</div>
</div>


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

Shock комментирует...

Для начала, хотел бы поблагодарить за выложенное решение отображения картинок в случайном порядке. Однако это решение с помощью PHP и с точки зрения JavaScript картинки все равно остаются в статичном порядке.
В любом случае рад, что вам пригодилась моя работа.

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

Shock комментирует...

а что касается ONLOAD, так делается это очень просто :

тег IMG последней картинки в слайдшоу изменяем следующим образом:

<img src="..." onload="slideSwitch('slideshow',1000);" />

а нижеуказанную строку удаляем:
setTimeout( "slideSwitch('slideshow',1000);",2000 );

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

Анонимный комментирует...

А я наоборот скоректировал чтобы задержка в начале была не более чем 2 сек. Этого времени достаточно чтобы остальные картинки постепенно подгружались, не дожидаясь загрузки всего документа, но мне пришлось чуть растянуть время смены изображений.

ПОЖЕЛАНИЯ:
- Было бы замечательно если бы во время кеширования изображений отображался не белый квадрат, а видиость загрузки (%-ы или анимированный gif).
- использование cssText, взамен style мне кажется помогло бы сократь количество кода.
- условие после цикла, которое практически повторяет, предыдущее можно либо совсем убрать, либо скорректировать иначе, тем самым сэкономить место.

Кстати идентификатор разве не должен быть в кавычках?
div = document.getElementById(tagId);

Да, еще хотел бы спросить относительно события onload, которое вы предлагаете в последний узел IMG поставить, возможно ли его в качестве аргумента создать, через document.createAttribute()?

Есть ли какой-либо метод определения последнего узла в массиве, что то типа свойства lastChild?

Shock комментирует...

Во-первых, спасибо большое за замечания по улучшению - все-таки взгляд со стороны никогда не помешает.

Что касается анимированного gif во время загрузки - очень просто - этот gif можно поставить на background #slideshow вот так:

#slide-container #slideshow {
...
background:url(my_preloader.gif) center center no-repeat;
...
}

По-поводу cssText - абсолютно согласен - это заметно сократит код, но у меня есть сомнения с совместимостью этого свойства со всеми версиями браузеров - нужно будет проверить и, если что, заменить. Да и, если честно, при написании этого слайдшоу я не смог вспомнить названия этого свойства :)

А вот о каком условии и после какого цикла вы говорите, если честно, я не совсем понимаю.

что же касается этого вопроса:
Кстати идентификатор разве не должен быть в кавычках?
div = document.getElementById(tagId);

tagId - это переменная содержащая в себе текстовый идентификатор - имя переменной НЕ должно быть в кавычках.

Самый простой аналог last-child будет выглядеть примерно так
my_array[my_array.length-1]

И последнее - добавить onload событие на последнее изображение слайдшоу с помощью javascript отличная идея ! Я думаю это будет выглядеть примерно так:

window.onload = function (){
  container = document.getElementById('slideshow');
  images = container.getElementsByTagName('img');
  if (images.length){
    images[images.length-1].onload = function(){
      slideSwitch('slideshow',1000);
    }
  }
}

Что-то вроде этого... Думаю это немного грубо, но в целом идея такова и должна работать. Думаю в моем новом блоге я перепишу заново это слайдшоу с учетом этого и других усовершенствований !

Анонимный комментирует...

раньше вроде без проверки коментарии выводились или я что-то туплю.

Анонимный комментирует...

не могу понять что с коментариями, короткий текст выводит, а длинный нет, что такое...

По поводу идентификатора это я действительно сильно попутал, невнимательный я совсем :)

свойство cssText кроссбраузерно и работает уверенно даже в IE5.1+

А вот без этих условий после оператора else, слайдшоу функционирует без каких-либо изменений даже в IE5.1+

next.style.opacity = 1;
next.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=100)";
next.style.filter = "alpha(opacity=100)";
tmp.style.opacity = 1;
tmp.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=100)";
tmp.style.filter = "alpha(opacity=100)";

Может я что-то не понимаю :) прошу растолковать для не понятливых :D

А в целом идея этого слайдшоу мне очень даже импонирует, нем есть все, что нужно, а если чего не хватает то легко встраиватся.
С нетерпением будем ждать новой версии!
СПАСИБО!

Shock комментирует...

свойство cssText кроссбраузерно и работает уверенно даже в IE5.1+
Значит в новой версии будет с его использованием ;)

А насчет тех условий...(точнее не условий, а операций)

Эта часть делает полностью непрозрачной следующую в очереди картинку

next.style.opacity = 1;
next.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=100)";
next.style.filter = "alpha(opacity=100)";

А эту часть в принципе можно удалить - она делает непрозрачной картинку, которую мы только что переместили в конец очереди...

tmp.style.opacity = 1;
tmp.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=100)";
tmp.style.filter = "alpha(opacity=100)";

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

Shock комментирует...

очепятка: рывки будут В анимации...

А что касается новой версии - работа уже начата - перепишу все заново и сделаю более параметризовано.

Анонимный комментирует...

Скажите пожалуйста, как правильно задать размер изображени не в CSS коде задавать, а в сценарии?

Shock комментирует...

вообще размер изображения задавать не обязательно - обязательно задать размер контейнера #slideshow и делается это в css.
Но если у вас возникла потребность задать фиксированный размер для рисунков, то это также можно сделать в CSS коде, например:

#slide-container #slideshow img {
width:320px;
height:240px;
}

Анонимный комментирует...

Отличный скрипт.
Просто и понятно !

Shock комментирует...

Всегда пожалуйста ! ;)

Анонимный комментирует...

Спасибо. Отличный скрипт.
Только у меня один вопрос. Подскажите как сделать ссылку из картинок. А то что просто замена div.childNodes[i].tagName=="IMG" на div.childNodes[i].tagName=="A" как то не особо помогает.

Анонимный комментирует...

Все разобрался. Можно не отвечать на мой тупой вопрос )).

Shock комментирует...

Да без проблем, всегда пожалуйста.
Вы бы написали как проблему решили - вдруг у кого-то такая же будет. Спасибо.

Анонимный комментирует...

Дмитрий! Вы - гений! Спасибо огромное за этот скрипт! Работает идеально во всем. Это очень помогло мне)

Shock комментирует...

Спасибо, конечно, за гения, но Вы мне льстите :)

Анонимный комментирует...

И еще вопрос:
Делаю это слайдшоу в центре таблицы 3 на 3. Мне надо, чтобы картинки этого слайдшоу были на всю эту ячейку(2.2) таблицы.

В описании стилей пишу так:

#slide-container #slideshow {
width:100%; //либо auto
height:300; //Пытаюсь здесь написать аналогично
margin:auto;
position:relative;

вот, если пишу height:auto; то слайдшоу просто исчезает, не могу понять почему(
Заранее большое спасибо!

Shock комментирует...

Для элемента #slideshow, свойство height указывать обязательно, так как картинки внутри него позиционируются с position:absolute; , а следовательно не занимают места в общем контексте.
width:100% указывать, скорее всего, не обязательно, так как это элемент блочного типа и занимает всю предоставленную ширину.
Не могу понять почему это проблема - установите фиксированные размеры для ячейки и вставляйте изображения того же размера.

Анонимный комментирует...

Спасибо за ответ. Фиксированный размер не подходит. Я делаю чтобы размер этой ячейки был 65%, к примеру, от размера экрана, чтобы на разных разрешениях нормально это смотрелось. (Делаю страницу без скроллингов) И я хочу чтобы Эти все картинки были размером с эту ячейку таблицы, т.к. в остальных ячейках будет продолжение общего рисунка.
Надеюсь, вы поняли, что я имею ввиду)) Как это можно реализовать?

Shock комментирует...

Я думаю Вам должен подойти следующий вариант:
1) уберите элемент #slide-container(вообще-то он нужен только для выравнивания слайдшоу по центру по горизонтали) и #slideshow
2) Вашей центральной ячейке присвойте id="slideshow" и внутрь нее вставьте элементы слайдшоу, которым и присвойте width:100%;height:100%;

Я думаю должно сработать.

Анонимный комментирует...

Не силен в js) Простите, но можно, пожалуйста немного по-понятнее)))
в стилях:
(style)

#slide-container {
text-align:center;
margin:20px 0px;
}
#slide-container #slideshow {
width:100%;
height:300;
margin:auto;
position:relative;
visibility:hidden;
}
#slide-container #slideshow IMG {
position:absolute;
top:0;
left:0;
}

(/style)

Что именно убрать? Пытаюсь сам, картинки выстраиваются по вертикали друг за другом.

И id="slideshow", как я понял нада написать тут: (TD id="slideshow") ??

Спасибо заранее))))

Анонимный комментирует...

Убирать понял что))
#slide-container {
text-align:center;
margin:20px 0px;
}
#slide-container #slideshow {
width:100%;
height:300;
margin:auto;
position:relative;
visibility:hidden;
}

только, когда я это убираю, то слайд шоу становится поверх таблицы в левом верхнем углу.
А с id="slideshow" так и не понял куда его...
Что-попало пробовал... не получается(

Shock комментирует...

в стилях удаляем первый блок.
Из остальных блоков удаляем слово "#slide-container"
Во втором блоке оставляем только строку position:relative;

(TD id="slideshow") это Вы правильно поняли ! Удачи !

Анонимный комментирует...

Простите за назойливость))))
Сделал все, как Вы сказали. Стили:
#slideshow {
position:relative;

}
#slideshow IMG {
position:absolute;
top:0;
left:0;
}
Вот фрагмент таблицы (ячейка):
(TD width="65%" height="65%" id="slideshow")
(div id="slideshow")
(img src="1.jpg" width="100%" height="100%")
(img src="2.jpg" width="100%" height="100%")
(img src="3.jpg" width="100%" height="100%")
(img src="РВ1.jpg" width="100%" height="100%")
(/div)
(/TD)

Так шоу вообще невидно(
Если еще не надоело, посмотрите пожалуйста, мб я что-то еще не так делаю) Спасибо!

Shock комментирует...

Вы немного неправильно меня поняли - все точно так, как в вашем коде, но только нужно удалить (div id="slideshow") и (/div)

Анонимный комментирует...

Все, разобрался! Спасибо вам огромное за помощь и внимание!!! ;)

Shock комментирует...

Всегда пожалуйста, приходите еще ;)

Quad комментирует...

День добрый, Shock, я вижу, что вы внимательно относитесь к комментариям, попрошу помочь и мне тоже. http://www.quad-damage.at.ua/index/0-11 Видите ли Пытаюсь использовать ваш код для своих 4 картинок, но увы случаеться то, что и у Anita, понятия не имею причем тут DOCTYPE тега < и самого символа "<" перед function у меня нету. Вот код

Прошу без строк, поскольку это сраный uCoz хостинг, пожалуйста если проблема в хостинге, то есть ли у вас какой-нибудь другой вариант, потому что к примеру http://www.art.webobzor.net/art/132.php Это работает.

Анонимный комментирует...

ВООООООООООООТ !!!
Такое большое спасибо !

Делаю сайт: комментирует...

Заранее прошу прощения за дилетантский вопрос, но у меня абсолютно нет времени на набивание шишек.
Всё устраивает, только когда я код вставляю в ячейку, картинки вставляются туда и раздвигают таблицу. Я пробовал на 3. А мне надо из 30 фото сделать шоу.

Анонимный комментирует...

Ребят все здорово! НО ТОЛЬКО ОДНО НО! Как сделать чтобы картинки были background-ами??? и еще одно чтобы программа сама брала рисунки из папки) Заранее спасибо

Анонимный комментирует...

Еще вопрос. Как сделать, чтоб по верх этого слайдшоу был текст или какие-то маленькие картинки.. (Новым слоем). Заранее спасибо!

Shock комментирует...

Огромные извинения за то что некоторое время не отвечал на вопросы - сильно загружен работой. А сейчас по-порядку.

Quad - судя по тому, что слайдшоу у вас на сайте работает, похоже вы разобрались и без меня и использовали jquery-слайдшоу.

Нелюбителю набивать шишки - какая проблема возникла с таблицами я что-то не совсем понял - если можно, то по-подробнее.

Чтобы выбрать файлы из директории - на этой странице первым примером стоит перебор файлов в папке - так вы можете сформировать код слайдшоу : http://php.net/manual/en/function.readdir.php
если что не получится - пишите - распишу подробнее.

чтобы разместить тест поверх слайдшоу нужно разместить этот текст внутри DIV после слайдшоу и дать ему стиль
{
position: relative;
top: -300px;
z-index:20;
}
где 300px - это высота блока со слайдшоу

Анонимный комментирует...

Спасибо большое по тексту. Только я в позиции не -300 а 0 сделал, и норм.
Большое спасибо! И точно так же можно и какие-то другие рисуночки сделать? И они будут поверх слайдшоу?

Анонимный комментирует...

По тексту:
Когда текст делаешь, то появляется нижний скроллер. И кусок лишнего фона. Как это убрать?

Анонимный комментирует...

А все) Я в стилях скроллер скрыл и норм)) Спасибо))

Shock комментирует...

ок, хорошо, что разобрались...
и, да, там можно размещать и рисунки и все что угодно, главное только координаты подогнать.

Анонимный комментирует...

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

Анонимный комментирует...

Облегчу работу Shock'a за его труд))
Как было написано выше:
В стилях добавляешь:
#slide-container #slideshow {
width:1024;
height:480;
margin:auto;
position:relative;
visibility: hidden; /*вот это*/

И где пишешь изображения в поседнем изображении:

(div id="slide-container")
(div id="slideshow")

(img src="s1.jpg")
(img src="s2.jpg")
(img src="s3.jpg")
..................
(img src="sn.jpg"
onload="document.getElementById('slideshow').style.visibility='visible';")

(/div)
(/div)
Жирным выделено что добавить "(" и ")" - это "<" и ">"

Shock комментирует...

О! Спасибо за помощь, товарищ Анонимный !
А то времени совсем нет, чтобы ответить.