3

我是一个主要是新手 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>

我为相关性输入/改编了这个;我希望我没有写错别字...

我正在使用 Debian Etch 的Iceweasel(Firefox 2.x 更名);我没有在其他浏览器上尝试过。在 Iceweasel 中,会发生以下情况:

  1. 弹出窗口按预期显示,但似乎循环直接进入最后一张图片。setTimeout似乎对图片之间的“暂停”没有影响。
  2. 显示了最后一张图片,并且弹出窗口的状态栏在中途显示其进度条,表明正在加载某些内容。

所以我的问题是:

  1. 我究竟应该如何在setTimeout这里使用电话?我试图让它调用一个“空”函数,所以它在具有 的循环中作为“暂停”工作,循环setTimeout()从主窗口的图像数组中更新弹出的单个图像。
  2. 我发现,如果我通过从外部文件 ( anim.html) 加载 HTML 代码来加载弹出窗口,状态栏似乎从“进度条”显示窗口一直期待重新加载。我仍然会尝试它是否来自其他地方,但我想知道我从外部文件加载 HTML 页面是否重要/相关window.open(),而不是加载一个空窗口并对其执行 writeln 到“写” HTML。
  3. 我已经while(true)在循环中评论了,否则浏览器会停止响应并且计算机会进入 100% CPU。我可以iffor循环中设置一个在最后一项之前将计数器设置回零,但是是否有另一种“优雅”或“更合适”的方式来使这个无限循环 - 或者while(true)做得很好?

我提前感谢您的评论,如果可能的话,请指向描述类似解决方案的现有参考书目。

4

3 回答 3

3

我不认为这意味着你认为它意味着什么:

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

显然,您正在尝试sleep()解决此问题。这不是 JS超时的工作方式——这发生onclick在你的代码中:你循环遍历图像数组,立即将图像从第 0 个切换到第 1 个……到最后一个;此外,在每个开关上,您都会说“运行该wait()功能,从现在开始 500 毫秒”。

window.setTimeout(foo,bar,baz)这样做:它设置一个以bar毫秒为单位的计时器并返回。代码继续执行下一条语句。bar毫秒后,函数foo(baz)被自动调用。的第三个和后面的参数setTimeout是可选的,将在第一个参数中传递给函数。

你可以做什么:

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 毫秒内调用;发生这种情况时,图像将设置为第一个,并且将设置一个计时器以next_image(2)在另一个 500 毫秒内调用,依此类推,直到数组中没有更多图像。

于 2009-03-28T11:44:44.587 回答
1

这不是您问题的直接答案,但是通过使用 JavaScript 框架jQuery插件,您可以轻松地制作图像幻灯片。我认为你想从头开始学习 JavaScript 很棒,但是走 jQuery+插件路线可以为你节省很多很多时间。哎呀,即使你想 DIY,我仍然建议使用 jQuery,因为它使 DOM 操作变得更加容易。

于 2009-03-28T12:20:55.263 回答
0

致 Piskvor:感谢您的回复,这正是我需要知道的:

setTimeout(foo,bar,baz)这样做:它设置一个以bar毫秒为单位的计时器并返回。代码继续执行下一条语句。bar毫秒后,函数foo(baz)被自动调用。的第三个和后面的参数setTimeout是可选的,将在第一个参数中传递给函数。

因此,这里遵循更正的示例;我希望它可以帮助其他 Google 员工 ;-)

<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()函数中使用了一个条件,当它到达末尾时将索引设置回零。
于 2009-03-28T13:35:03.743 回答