Javascript: всплывающее окно с фильмом из изображений в главном окне - PullRequest
3 голосов
/ 28 марта 2009

Я в основном новичок в Javascript'er, и я пробую его на веб-странице, которая, после нажатия кнопки, открывает окно, которое показывает циклический «фильм» с изображениями из главного окна. Судя по тому, что я пробовал гуглить, я чувствую, что довольно близок, но что-то ускользает от меня.

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

В любом случае, вот снимок того, что я считаю соответствующим кодом:

<html>
<head>
<script language="javascript">
function wait() {}
function anim() {
  var timeout; var next;
  var popuptitle='Movie';
  var main=parent;
  var popup=parent.open("","",
      "width="+main.document.images[0].width+",height="+(main.document.images[0].height+40)+
      "toolbar=no,location=no,directories=no,status=no,"+
      "menubar=no,scrollbars=no,copyhistory=no,resizable=no");
  popup.document.write('<html><head><title>'+popuptitle+'</title></head><body>'+
    '<p align="center"><img name="anim" width="100%" alt=""></p>'+
    '<p align="center"><button name="close" onclick="javascript:window.close();">Close</button></p>'+
    '</body></html>');
  /*while(true)*/
  for(i=0; i<main.document.images.length; i++) {
    next=main.document.images[i].src;
    popup.document.images[0].src=next;
    timeout=setTimeout('wait();',500);
  }
}
</script>
</head>
<body><h1>Pictures + animation</h1>
<p><button name="exec" onclick="javascript:anim();">Animate (popup)</button></p>
<p><img src="img1.jpg"></p>
....
<p><img src="img16.jpg"></p>
</body>
</html>

Я набрал / адаптировал это для соответствия; Я надеюсь, что я не сделал никаких опечаток ...

Я работаю с Iceweasel Debian Etch (ребрендинг Firefox 2.x); Я не пробовал это с другими браузерами. В Iceweasel происходит следующее:

  1. Всплывающее окно отображается так, как и должно быть, но кажется, что цикл идет прямо к последней картинке. setTimeout кажется, не влияет на "паузу" между картинками.
  2. Отображается последнее изображение, а в строке состояния всплывающего окна отображается индикатор выполнения на полпути, что свидетельствует о загрузке.

Итак, мои вопросы:

  1. Как именно я должен использовать здесь setTimeout звонок? Я пытался заставить ее вызывать «пустую» функцию, поэтому она работает как «пауза» в цикле, имеющем setTimeout(), где цикл обновляет одиночное всплывающее изображение из массива изображений главного окна.
  2. Я считаю, что если я загружаю всплывающее окно, загружая HTML-код из внешнего файла (anim.html), строка состояния, похоже, показывает из "индикатора выполнения", что окно продолжает ожидать перезагрузки. Я все еще собираюсь попробовать, если это откуда-то еще, но что я хочу знать, если это важно / важно, чтобы я загружал HTML-страницу из внешнего файла с window.open(), в отличие от загрузки пустого окна и выполнения записи ему «написать» свой HTML.
  3. Я прокомментировал while(true) в цикле, потому что в противном случае браузер перестает отвечать на запросы, и компьютер переходит на 100% ЦП. Я мог бы сделать if в цикле for, чтобы обнулить счетчик до последнего элемента, но есть ли другой «элегантный» или «более подходящий» способ сделать этот бесконечный цикл - или делает while(true) хорошо?

Я заранее оцениваю ваши комментарии и, если возможно, указатель на существующую библиографию, описывающую подобные решения.

Ответы [ 3 ]

3 голосов
/ 28 марта 2009

Я не думаю, что это означает, что вы думаете, что означает:

timeout=setTimeout('wait();',500);

Видимо, вы пытаетесь sleep() с этим. Это не так, как работают JS timeouts - это происходит onclick в вашем коде: вы перебираете массив изображений, немедленно переключаете изображения с 0-го на 1-е ... на последнее; также, на каждом коммутаторе вы говорите «запустите функцию wait(), через 500 мсек».

window.setTimeout(foo,bar,baz) делает это: устанавливает таймер на bar миллисекунды и возвращает. Выполнение кода продолжается со следующего оператора. Через bar миллисекунд функция foo(baz) вызывается автоматически. Третий и последующие аргументы для setTimeout являются необязательными и будут переданы функции в 1-м аргументе.

Что вы могли бы сделать:

function anim() { 
  var timeout; var next;
  var popuptitle='Movie';
  var main=parent;
  var popup=parent.open("","",
      "width="+main.document.images[0].width+",height="+
      (main.document.images[0].height+40)+
      "toolbar=no,location=no,directories=no,status=no,"+
      "menubar=no,scrollbars=no,copyhistory=no,resizable=no");
  popup.document.write('<html><head><title>'+popuptitle+
    '</title></head><body>'+
    '<p align="center"><img name="anim" width="100%" alt=""></p>'+
    '<p align="center"><button name="close" ' + 
    'onclick="javascript:window.close();">Close</button></p>'+
    '</body></html>');

  // *changed below*
  // start the animation with the 0th image
  next_image(0,main.document.images,popup.document.images[0]);
}

function next_image(index,source_image_array,target_image) {
    // if not at end of array
    if (source_image_array.length < index) { 
        next=source_image_array[index].src;
        target_image.src=next;

        // do this again in 500 ms with next image
        window.setTimeout(next_image,500, index+1 ,
                            source_image_array,target_image);
    }
}

Таким образом, в конце вашей функции anim() вы вызываете next_image(0), который устанавливает для изображения значение 0 в массиве и устанавливает таймер для вызова next_image(1) через 500 мс; когда это произойдет, для изображения будет установлено 1-е, а для таймера будет задан вызов next_image(2) через 500 мс и т. д., пока в массиве больше не останется изображений.

1 голос
/ 28 марта 2009

Это не прямой ответ на ваш вопрос, но с помощью фреймворка JavaScript jQuery и плагина вы можете легко получить слайд-шоу с изображениями. Я думаю, это здорово, что вы хотите изучать JavaScript с нуля, но переход на плагин jQuery + может сэкономить вам много-много часов. Черт возьми, даже если вы хотите сделать сам, я все равно рекомендую использовать jQuery, потому что это делает манипулирование DOM намного проще.

0 голосов
/ 28 марта 2009

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

setTimeout(foo,bar,baz) делает это: устанавливает таймер на bar миллисекунд и возвращает. Выполнение кода продолжается со следующего оператора. Через bar миллисекунд функция foo(baz) вызывается автоматически. Третий и последующие аргументы для setTimeout являются необязательными и будут переданы функции в 1-м аргументе.

Итак, здесь следует исправленный пример; Я надеюсь, что это помогает другим Googlers; -)

<html>
<head>
<script language="javascript">
function display(img,i, popup) {
  var next; var after_ms=750; var max=img.length;
  if(i>=max) i=0;  /* so we can cycle infinitely */
  next=img[i].src; popup.document.images[0].src=next;
  setTimeout(display,(i+1<max?after_ms:4*after_ms), img,i+1,popup);
}
function anim() {
  var popuptitle='Movie';
  var popup_properties="width="+document.images[0].width+
      ",height="+(document.images[0].height+40)+
      ",toolbar=no,location=no,directories=no,status=no"+
      ",menubar=no,scrollbars=no,copyhistory=no,resizable=no"
  var popup=parent.open("", popuptitle, popup_properties);
  popup.document.write('<html><head><title>'+popuptitle+'</title></head><body>'+
    '<p align="center"><img name="anim" width="100%" alt=""></p>'+
    '<p align="center"><button name="close" onclick="javascript:window.close();">Close</button></p>'+
    '</body></html>');
  display(document.images,0, popup);
}
</script>
</head>
<body><h1>Pictures + animation</h1>
<p><button name="exec" onclick="javascript:anim();">Animate (popup)</button></p>
<p><img name="1"  src="img1.jpg"></p>
// .... 
<p><img name="16" src="img16.jpg"></p>
</body>
</html>

Что я также узнал:

  1. while(true) это зло, оно заставляет браузер зависать. Вместо этого я использовал условие в функции anim(), которое возвращает индекс в ноль, когда он достигает конца.
...