0

总的来说,我对 Javascript 还很陌生,我从这个网站上主要发现的东西中拼凑了一个小脚本,试图让一个小的 iframe 循环浏览一堆链接,它做得非常好。但是,我还希望它在用户单击 iframe 或其任何内容时停止循环。

这是我到目前为止的代码。HTML 页面上只有一个 iframe。

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript" charset="utf-8">
<!--
var sites = [
  "side/html5.html",
  "side/silverlight.html",
  "side/wordpress.html",
  "side/mysql.html",
  "side/php.html",
  "side/css3.html"
];
var currentSite = sites.length;
var timerId;
var iframeDoc = $("iframe").contents().get(0);

$(document).ready(function ()
{
  var $iframe = $("iframe").attr("src","side/html5.html");

  timerId = setInterval(function()
  {
    (currentSite == 0) ? currentSite = sites.length - 1 : currentSite = currentSite -1;
    $iframe.attr("src",sites[currentSite]);
  }, 4000);

  $(iframeDoc).bind('click', function()
  {
    clearInterval(timerId);
  });

});
//-->
</script>
</head>

<body>

<sidebar>
<iframe name="sideframe" src="side/html5.html"></iframe>
</sidebar> ..etc..

请帮忙,我正在尝试尽可能快地学习 Javascript,但据我所知,它应该可以工作,但实际上并没有。

感谢您能给我的任何帮助,非常感谢。


编辑:

好的,我现在有了一个新脚本,主要基于 Elias 的工作,但它也不起作用。我已经将它固定在 Firebug 中,它说 timerCallback.currentSite 值正在正确更新,尽管我找不到 $iframe 的 src 值来明确检查它。据我所知,它正在正确更新变量,只是没有正确更新 iframe。我是否在此代码中正确调用/设置 iframe?另外,jquery 库中的链接是否足以满足我的目的?我有点迷失了所有这些要链接到的库...

<script type="text/javascript" src="http://code.jquery.com/jquery.js"></script>
<script type="text/javascript" charset="utf-8">

<!--

var sites = 
[
  "side/html5.html",
  "side/silverlight.html",
  "side/wordpress.html",
  "side/mysql.html",
  "side/php.html",
  "side/css3.html"
];

var $iframe = $("iframe").attr("src","side/html5.html");

function timerCallback()
{
    timerCallback.currentSite = (timerCallback.currentSite ? timerCallback.currentSite : sites.length) -1;
    $iframe.attr("src",sites[timerCallback.currentSite]);

    $($('iframe').contents().get('body')).ready(function()
    {
        $(this).unbind('click').bind('click',function()
        {
            var theWindow = (window.location !== window.parent.location ? window.parent : window);
            theWindow.clearInterval(theWindow.timerId);
        });
    });

}

var timerId = setInterval(timerCallback, 4000);

//-->

</script> 
4

2 回答 2

1

如果我是你,我会谨慎行事。既然您说您对 JS 相当陌生,那么它可能会提供非常丰富的信息。

function timerCallback()
{
    timerCallback.currentSite = (timerCallback.currentSite ? timerCallback.currentSite : sites.length) -1;
    $iframe.attr("src",sites[timerCallback.currentSite]);
}
var timerId = setInterval(timerCallback, 4000);
$($('iframe').contents().get('body')).unbind('click').bind('click', function()
{
    var theWindow = (window.location !== window.parent.location ? window.parent : window);
    theWindow.clearInterval(theWindow.timerId);
});

现在我必须承认这段代码根本没有经过测试。尽管我认为它提供了一些帮助您上路的东西:

1)间隔是使用回调函数设置的,因为有很多原因它更好

1b)在该回调中,我利用函数是对象这一事实,并创建了一个静态变量,该变量设置为站点数组的长度(当未定义或 0 时),在这两种情况下都减去 1

2) jQuery 的,get()方法返回一个 DOM 元素,而不是一个 jquery 对象,这就是为什么我将它包装在$()一个新的 jQ obj 中,为您提供所需的方法。

3)由于您正在操作 iFrame 内的 dom,因此最好取消绑定要绑定的事件

4) 在 iF​​rame 内,您无法直接访问间隔所在的父窗口。

您可能想了解如何处理 iFrame,因为它们有时会有点麻烦

编辑: David Diez 是对的,最简单的解决方法是将绑定合并到超时函数中:

function timerCallback()
{
    timerCallback.currentSide = ...//uncanged
    //add this:
    $($('iframe').contents().get('body')).ready(function()
    {
        $(this).unbind('click').bind('click',function()
        {
            //this needn't change
        });
    });
}

理论上,这应该在加载后将点击事件绑定到正文

编辑2

我一直在搞乱,你可以保持你的代码,原样。只需添加一个功能:

function unsetInterval()
{
    window.clearInterval(window.timerId);
}

并将其添加到您的 setInterval 函数中:

$('#idOfIframe').load(function()
{
    var parentWindow = window.parent;
    $('body').on('click',function()
    {
        parentWindow.clearInterval();
    });
});

这将在加载 iFrame 内容后立即触发,并绑定单击事件取消设置计时器,就像您想要的那样

于 2012-04-20T11:48:39.550 回答
1

我认为您的代码因此无法正常工作

var iframeDoc = $("iframe").contents().get(0);

这可能是获取 iFrame 的标题,因为您将 iframeDoc 值保存到 iframe 的第一个子级head标签,实际上,如果您的窗口中有超过 1 个 iframe,iframeDoc 将是undefined因为$("iframe")获取文档的所有 iframe。

BTW your currentSite value condition is wrong, you asign the same value for both conditions

现在我给你一个例子:

<iframe id="myFrame" src="http://www.google.com/"></iframe>

和脚本:

<script type="text/javascript" src="http://code.jquery.com/jquery.js"></script>
<script type="text/javascript">

var sites = [
"site1",
"site2"
];

var myFrame = document.getElementsByTagName('iframe')[0];
var currentSite = myFrame.getAttribute('src');
var timerId;

var myFrameDoc = window.frames[0].document;

$(document).ready(function()
{
    myFrame.setAttribute('src', 'side/html5.html');

    timerId = setInterval(function()
    {
        //WRONGG
        (currentSite == 0) ? currentSite = sites.length - 1 : currentSite = currentSite -1;
        myFrame.setAttribute('src', sites[currentSite]);
        $(myFrame).off("click").on("click", clearInterval(timerId));
    }, 4000);

    //Won't work because you are trying to get events from an inside of a iframe
    //$(myFrameDoc).on("click", clearInterval(timerId));
    //This may work
    $(myFrameDoc).off("click").on("click", clearInterval(timerId));
});

</script>

当您尝试跟踪 iframe 的事件时,您必须小心,因为 iframe 包含一个完全不同的 javascript 目的文档,所以基本上您必须进入新文档,取消绑定您需要使用的事件,然后再次绑定它们正如@Elias 指出的那样,您的功能。但请注意,您会不断更改 iframe 的 src,因此,如果您真的需要这样做,您将不得不分离解除绑定和再次绑定您的 clearInterval 的代码,就此而言,这可能$.on()对您有用。

编辑: 如果 iframe 的 src 在同一个域内,具有相同的端口和相同的协议,则调用 iframe 应该以这种方式工作:

var myFrameDoc = window.frames[0].document;

我添加了一个新变量,因为我们希望将 click 事件绑定和取消绑定到 iframe 的文档,而不是 iframe,我们使用 window.frames 集合属性,但是如果您尝试访问现代浏览器会抛出异常并拒绝访问到一个框架,并且您不在同一个域中使用相同的端口和相同的协议...

另外使用$.on()and$.off()代替$.bindand$.unbind()是因为第一个是新的,尽管我们在这里没有使用它,但它们能够不断地观察 DOM 以查找要绑定的新元素(如果添加);如果此代码仍然不起作用,这可能对这种情况有用。如果是这种情况,您仍然可以更改:

var myFrameDoc = window.frames[0].window;

和这个:

$(myFrameDoc).off("click", "document").on("click", "document", clearInterval(timerId));

这会将事件处理程序重新绑定到新文档添加。未经测试,但可以工作。

于 2012-04-20T11:25:32.440 回答