views:

951

answers:

3

I am attempting to load an embedded Youtube video when my page loads, and then hide it right away once it has loaded. This is working fine, however when I want to make it visible it appears for just a second then it disappears. This is happening in both Firefox 3.0 and Safari 4, I haven't tried it in any other browsers.

I have tried hiding it using .style.display = 'none' then .style.display = ''; and style.display='block'; to make it visible again, as well as tried using jQuery .hide() and .show() but both methods result in the youtube video vanishing after it is made visible.

Is there a 'proper' way I should be making the <object>...<embed> tags hidden and visible using javascript so it doesn't disappear when I try to make it visible? The reason I'm not just loading the 2nd video dynamically when I need it is I want the video to start downloading so that it is immediately available to be played when I am ready to make it visible.

Below is my html and javascript code snippets:

mute(), play(), stop() are just wrappers for the youtube javascript api calls of the same name.

switchVideoPlayers() is called from an html button passing 1 and 2 as oldid and newid respectively.

I couldn't figure out what pieces I should include as snippets, so I've dumped the whole page below:

<html>
<head>
<title>YouTube test</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"&gt;&lt;/script&gt;

<script>

var player = new Array();
var currentplayer = 1;

function onYouTubePlayerReady(playerid)
{
    if (playerid.indexOf('obj') > -1)
    {
     playerid = playerid.substring(3);
    }

    debug("player " + playerid + " loaded");

    player[playerid] = document.getElementById(playerid);

    if (playerid == 1)
     player[playerid].loadVideoById('5hSW67ySCio');
    else
    {
     player[playerid].loadVideoById('VgMVHc5N3WM', 10); //videoid
     mute(playerid);
     setTimeout(function() { 
      stop(playerid);
      $("#obj" + playerid).hide();
     }, 1000); 

    }
}

function play(id)
{
    player[id].playVideo();
}

function pause(id)
{
    player[id].pauseVideo();
}

function stop(id)
{
    player[id].stopVideo();
}

function mute(id)
{
    player[id].mute();
}

function unmute(id)
{
    player[id].unMute();
}


function seek(id,seconds)
{
    player[id].seekTo(seconds, false);
}

function getCurrentTime(id)
{
    return player[id].getCurrentTime();
}

function loadNewVideo(id,videoid, startseconds)
{
    player[id].loadVideoById(videoid, startseconds);
    mute(id);
    setTimeout(function() { stop(id); }, 1000); 
}

function switchVideoPlayers(oldid, newid)
{
    stop(oldid);
    $("#obj" + oldid).hide();

    $("#obj" + newid).show();
    setTimeout(function() {
     unmute(newid);
     play(newid);
    }, 10);
}

function debug(message)
{
    $('#debug').html($('#debug').html() + message + "<br />");
}


</script>

</head>

<body>

<object id='obj1' width="425" height="344">
<param name="movie" value="http://www.youtube.com/v/5hSW67ySCio&amp;hl=en&amp;fs=1&amp;"&gt;&lt;/param&gt;
<param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param>
<embed id='1' src="http://www.youtube.com/apiplayer?enablejsapi=1&amp;playerapiid=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed>
</object>

<object id='obj2' width="425" height="344">
<param name="movie" value="http://www.youtube.com/v/5hSW67ySCio&amp;hl=en&amp;fs=1&amp;"&gt;&lt;/param&gt;
<param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param>
<embed id='2' src="http://www.youtube.com/apiplayer?enablejsapi=1&amp;playerapiid=2" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed>
</object>


<br />
<br />

<input type='button' value='Play' onclick='play(currentplayer);' />
<input type='button' value='Pause' onclick='pause(currentplayer);' />
<input type='button' value='Stop' onclick='stop(currentplayer);' />
<input type='button' value='Mute' onclick='mute(currentplayer);' />
<input type='button' value='UnMute' onclick='unmute(currentplayer);' />
<input type='button' value='Seek' onclick='seek(currentplayer,getCurrentTime(currentplayer) + 10);' />
<input type='button' value='Get Current Time' onclick='alert(getCurrentTime(currentplayer));' />
<input type='button' value='load strain video' onclick='loadNewVideo(currentplayer+1,"VgMVHc5N3WM", 10);' />
<input type='button' value='switch to next video' onclick='switchVideoPlayers(currentplayer,currentplayer + 1);' />

<br />
<br />
<a href='http://code.google.com/apis/youtube/js_api_reference.html'&gt;api&lt;/a&gt;

<div id='debug'>DEBUG MESSAGES:<br />
</div>
</body>

</html>
A: 

Took another look at this, and it turns out the onYouTubePlayerReady() function gets called again when the video is made visible. Inside this function the code to hide the video player is called again which is why it was disappearing.

jcaruso
+1  A: 

Most browsers treat flash like this - when you hide + show it, it will re-initialize the swf.

If you don't want it to get reinitialized, you can just move it out of the way (absolute position it) - something like -9999px or something, then just move it back into place when you want to show it.

Geoff
I tried this out but the video still gets re-initialized (i.e. the onYouTubePlayerReady() still gets called after the player is moved. I used both jQuery .css("top","100px") and regular javascript .style.top = "100px" to move it back into view.
jcaruso
Ok i fixed that... i was adding the position = absolute property when i was doing the switch. loading the page by default with position: absolute; on the object allows for repositioning it without reloading. You my friend get a checkmark!
jcaruso
A: 

On most browsers you can avoid the re-initialization problem by setting the css style visibility: hidden;

This is a little annoying since the flash movie still occupies the same position in the page flow, but it will keep the swf invisible and helps alleviate problems like flash showing through overlays (like lightbox)

On Opera, the hidden swf stops responding to functions exposed to javascript via ExternalInterface.addCallback so this solution may be unacceptable for either of those reasons.

Duncan Beevers