2012-04-20 112 views
0

我对Javascript一般来说比较陌生,我拼凑了一些来自本网站大部分内容的小脚本,试图获得一个小的iframe通过一系列的链接循环播放,它的表现非常出色。不过,我也希望它在用户点击iframe或其任何内容时停止骑车。Javascript - JQuery - clearInterval/setInterval - 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> 
+0

当用户将鼠标悬停在iframe上时,如何暂停它? – 2012-04-20 11:17:41

+0

'$('iframe')'位不起作用,它将返回一个1(或更多,取决于页面上iframe的数量)的数组。对不起,但它是伪代码。尝试使用'$('iframe')[0]'或给iFrame一个id,并使用id选择器'$('#iFrameId')' – 2012-04-20 13:54:49

+0

我试过了你的建议和'$('#sideframe') '并且'$('iframe')[0]是未定义的',因为错误(对其他人也是如此)。完整的:'var $ iframe = $('iframe')[0] .attr(“src”,“side/html5.html”);' - 我会把这个在线并让你看到它的行动。编辑:见http://www.gandcdesign.co.uk/ – 2012-04-20 14:36:08

回答

1

我觉得你的代码是不工作,因为这

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

这可以得到的iFrame因为头您将iframeDoc值保存到iframe的第一个孩子,即head标记,实际上,如果您的窗口中有多个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 purprouses文档,所以基本上你必须进入新文档,解开你需要使用的事件,并将它们绑定正如@Elias指出的那样。但要注意,你不断地改变你的iframe的src,所以如果yu真的需要这样做,你将不得不分开代码去解绑并重新绑定你的clearInterval,因此,$.on()可能适合你。

编辑:调用到iframe中应该以这种方式工作IF iframe的SRC是同一个域里,用相同的端口和相同的协议:

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

我添加了一个新变量因为我们想要将点击事件绑定和解除绑定到iframe的文档,而不是iframe,我们使用该窗口。帧集合属性,但现代浏览器会抛出异常并拒绝访问,如果您尝试访问一个帧,并且您使用相同的端口和相同的协议不在同一个域中...

另外使用$.on()$.off()而不是$.bind$.unbind()是因为第一个是新的,尽管我们没有在这里使用它们,但它们能够不断地监视新元素的DOM,如果这段代码仍然不起作用,这可能对这种情况有用。如果是这样的话,你仍然可以改变这一点:

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

这:

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

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

+0

我已经尝试了你的解决方案,大卫和埃利亚斯,但不幸的是,它似乎甚至没有循环浏览任何页面更多,使测试停止功能有点困难。我可以看看你是从哪里来的,因为iframe的难度叫它是父窗口。我试图用Firebug来调试它,但它拒绝打断点,它几乎就像它没有运行... – 2012-04-20 12:51:10

+0

编辑:在大卫的代码,它的说myFrame是未定义的,即使它通过后滚动getElementsByTagName方法。 – 2012-04-20 12:57:38

+0

@SarahCarter:你有权访问该网站在iFrame中的加载情况,还是他们是外部的?否则,最快的解决办法是编写一个js文件,并将其包含在所有这些站点中......或者使用ajax来获取内容服务器端,并在其中添加js – 2012-04-20 13:38:10

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)在回调只有更好,我利用了这个事实,即函数是对象,并创建了一个静态变量var,设置为您的站点数组的长度(当undefined或0时),在两种情况下1都被减1

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

3)因为你操纵iFrame中的DOM,这是最好的解除绑定要绑定

4)iFrame中的事件,您不必父窗口,直接进入您的间隔是。

你可能想如何处理内部框架,因为他们可以是一个有点faff的不时

编辑读了起来: 大卫·迭斯是正确的,最简单的方法解决这个是结合了结合在超时功能:

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

从理论上讲,这应该click事件绑定到身体已经加载

Ë后dit2

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

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

,并添加到您的setInterval函数:

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

这将得到尽快的iFrame内容加载触发,并绑定click事件取消设置定时器,就像你想

+1

'$('iframe')。contents()。get('body'))。unbind('click')。bind '是一个非常棒的技巧,但要小心,这不会工作,因为他的代码不断地改变iframe中的DOM,所以基本上他不能跟踪iframe中的事件!如果功能是分开的,可以使用'。.on()'而不是'$ .bind()' – 2012-04-20 11:52:15

+0

@DavidDiez:增加了一个理论上的解决方法,没有经过测试,但基本的想法是绑定'ready'事件,这应该和'on'有相同的效果 – 2012-04-20 12:39:49