开发者

Javascript only works in Safari with alert

I am a newbie to javascript and am having trouble getting my script to work in Safari. I have done numerou开发者_运维知识库s google searches to find a solution, but haven't found anything that worked.

I have an HTML page that uses javascript to load an swf and a caption from two separate arrays. There is a next button that will load another SWF and a new caption upon being clicked. It works perfectly in IE and Firefox, but in Safari the new SWF does not display. In the Safari debugger it shows the correct new SWF file name, but displays the original SWF on screen. The only way I have gotten it to work is if I have an alert after the code. I have tried adjusting the order of events in my function, but that has not solved anything.

Any ideas? (I apologize if I've provided too much code, I just want to give you the full picture.)

Javascript (located in the header):

var swfFrame=new Array();
swfFrame[0]='frame_01.swf';
swfFrame[1]='frame_02.swf';
swfFrame[2]='frame_03.swf';

var paragraphTxt=new Array();
paragraphTxt[0]='caption 1';
paragraphTxt[1]='caption 2';
paragraphTxt[2]='caption 3';

function nextFrame(x){
i = i+x;
if(i>=swfFrame.length){
    i=i-1;
    window.open('quiz.html');
}else{
document.getElementById("framenum").innerHTML = (i+1) + " of " + swfFrame.length;
document.getElementById("paragraph").innerHTML = paragraphTxt[i];
// IE
document.getElementById("flashPlayer").movie = "swf/" + swfFrame[i];
// FIREFOX et al
<!--[if !IE]>-->
document.getElementById("flashPlayer").data = "swf/" + swfFrame[i];
<!--[endif}-->
//  ALERT (doesn't work in Safari if alert is off)
alert(document.getElementById("flashPlayer").data);
}
if(i>0){
    document.getElementById("button_Bck").style.visibility = "visible";
}else{
    hideBack();
}
}

function hideBack(){
document.getElementById("button_Bck").style.visibility = "hidden";
}

Code for button used to advance to the next swf:

<a href="javascript://" onclick="nextFrame(1)"><div id="button_Nxt"><div id="buttonText">Next</div></div></a>


@rlane423: I don't think you can actually use conditional comments like that within a script block.

Try --

    /* preceding code omitted for brevity */

    var isIE = false; // set to false by default
</script>

<!--[if IE]>
<script type="text/javascript">
    isIE = true;
</script>
<![endif]-->

<script type="text/javascript">
     if (isIE) {
         // IE
         document.getElementById("flashPlayer").movie = "swf/" + swfFrame[i];
     } else {
         // FIREFOX et al
         document.getElementById("flashPlayer").data = "swf/" + swfFrame[i];
     }

     /* rest of script omitted for brevity */
</script>


I think your problem is due to the fact that flash runs in a separate thread from javascript. When you use an alert for debugging and your page includes flash you can run into these sorts of heisenbugs. In the absence of flash, everything on your page, including javascript, will block during an alert. Flash on the other hand runs on a separate thread and does not block for alerts.

This example illustrates what I am talking about:

<object width="480" height="390"><param name="movie" value="http://www.youtube.com/v/oHg5SJYRHA0?fs=1&amp;hl=en_US&amp;rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/oHg5SJYRHA0?fs=1&amp;hl=en_US&amp;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="390"></embed></object>
<a href="javascript:alert('hello'); return false;">Click me!</a>

Start the movie and then click the link - the video will not stop playing while the alert is up.

The easiest fix for this is probably to wrap the code after the alert statement in a setTimeout function with a short delay:

setTimeout(function() { ... }, 50);

A better fix would be to register an event with the flash movie or poll it until it's ready to be updated.


Is your array index of i actually making it to the third index?

If you are calling your function nextFrame(1) each time... are you only passing the number 1 into the function each time you call the function or do you have 3 different function calls with

nextFrame(1) nextFrame(2) nextFrame(3)

also, you have not declared i as in var i = 0; I would do this ... for these purposes your code would be a lot lighter if you were to declare i as global outside of your nextFrame function and then increment it by 1 every time the nextframe() function is called. And then load in the movie you want based on the global i.

var i = 0;
function nextFrame(){
    loadSwf[i];
    i++;
}

then call the function with

onclick="nextFrame()"


I came up with a solution that works. It may be a complete hack, but it's working in all the browsers I need it to.

First I changed the way I was detecting IE, as suggested by @stealthyninja. Then I decided to try entirely reloading the flash instead of just swapping the file name of the swf. The first flash is being loaded using the swfobject.js dynamic publishing method. So I am reloading the subsequent frames the same way. I wanted to use innerHTML for this, but it didn't like me trying to put javascript in it. So I added an empty javascript block within the div of the flash content and used innerHTML to load the swfobject call within that. (Hopefully this makes sense and isn't a totally backwards way of doing it.) Code is below.

<script type="text/javascript">
var isIE =false;
</script>

<!--[if IE]>
<script type="text/javascript">
    isIE = true;
</script>
<![endif]-->

<script type="text/javascript">
    var flashvars = {};
    var params = {};
    params.play = "true";
    params.loop = "false";
    params.menu = "false";
    params.quality = "best";
    params.wmode = "window";
    params.bgcolor = "#FFFFFF";
    params.allowscriptaccess = "sameDomain";
    var attributes = {};
    attributes.align = "middle";
    swfobject.embedSWF("swf/frame_01.swf", "flashPlayer", "100%", "100%", "9.0.0", false, flashvars, params, attributes);

var i=0;
var swfFrame=new Array();
    swfFrame[0]='frame_01.swf';
    swfFrame[1]='frame_02.swf';
    swfFrame[2]='frame_03.swf';

var paragraphTxt=new Array();
    paragraphTxt[0]='caption 1';
    paragraphTxt[1]='caption 2';
    paragraphTxt[2]='caption 3';

function nextFrame(x){
i = i+x;
//alert("i+x = " + (i));
if(i>=swfFrame.length){
    i=i-1;
    window.open('quiz.html');
}else{
    document.getElementById("framenum").innerHTML = (i+1) + " of " + swfFrame.length;
    document.getElementById("paragraph").innerHTML = paragraphTxt[i];
    if(isIE){
        // IE
        document.getElementById("flashPlayer").movie = "swf/" + swfFrame[i];
    }else{
        document.getElementById("newScript").innerHTML = swfobject.embedSWF("swf/" + swfFrame[i],"flashPlayer","100%","100%","9.0.0",false,flashvars,params,attributes);
    }
}
if(i>0){
    document.getElementById("button_Bck").style.visibility = "visible";
}else{
    hideBack();
}
}

Div location of Flash content with newly added javascript block:

<div id="flash">
    <script type="text/javascript" id="newScript">
    </script>
        <div id="flashPlayer">
        <a href="http://www.adobe.com/go/getflashplayer">
            <img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" />
        </a>
        </div>
</div>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜