6

I am trying to fade in youtube iframe embed, but it only works in IE9, all other newest browsers (Safari, Opera, Chrome, Firefiox) it doesnt. Iframe is shown immediatelly regarldess of setting opacity to 0.

I am on Windows.

What I am dong wrong?

ps: this works well with Vimeo youtube iframe embed.

JsFiddle:

http://jsfiddle.net/jgtSS/26/

Toniq
  • 4,492
  • 12
  • 50
  • 109

2 Answers2

3

For security reasons, an inline frame becomes fully visible when the alpha channel level (opacity / background) of the iframe/closest layer is reduced. So, even when the opacity is set to 0.99999, the frame shows up.

I've created a solution for this issue: Create two layers with the same size, and add them right after the iFrame's parent.

  1. Attach a background to the first image, which is a preview of the video
  2. Set the background of the second div to the page's background, for example white.

Then, animate the second DIV, to opacity 0. The background at the first image becomes more visible. At the end of the animation, hide the first div using a callback function:

To allow the user to activate the video during the animation, bind a click event handler to the DIV, which immediately hides the layers, and call the playVideo method of the inline video.

To invoke the playVideo method, you need a reference to the embedded video. Since you haven't created the video using the YouTube video API, you cannot use a global variable to access the video. A while back, I have created a function to invoke methods on an embedded video.
Read: YouTube iframe API: how do I control a iframe player that's already in the HTML?

The final code

I've created a live example at fiddle: http://jsfiddle.net/jgtSS/34/. The full code is also shown below.

<html><head>
<style>
#holder, #ID-of-first-div, #ID-of-second-div{
    position:absolute;
    width:320px;
    height:240px;
    top:0px;
    left:0px;
}
#ID-of-first-div, #ID-of-second-div {
    background: #FFF;
}
#btn1{
    position:absolute;
    background:#09C;
    width:40px;
    height:40px;
    top:250px;
    left:0px;
      
}
</style>
<script type="text/javascript">
$(window).load(function() {
    $('#btn1').click(function(){
        var vid_id = $('#player').get(0).src.match(/embed\/([^?]+)/)[1];
        var vid_bg = 'http://i2.ytimg.com/vi/'+vid_id+'/hqdefault.jpg';
        $('<img>').attr("src", vid_bg).css({width:'100%',height:'100%',border:'none'}).appendTo('#ID-of-first-div');
        $('#ID-of-second-div').animate({opacity: 0 }, 3000, function(){
            $('#ID-of-first-div').hide();
        });
        var both = $('#ID-of-first-div, #ID-of-second-div');
        both.click(function(){
            both.hide();
            callPlayer('player', 'playVideo');
        });
    });
});
/*
 * @author       Rob W (https://stackoverflow.com/questions/7443578/youtube-iframe-api-how-do-i-control-a-iframe-player-thats-already-in-the-html/7513356#7513356)
 * @description  Executes function on a framed YouTube video (see previous link)
 *               For a full list of possible functions, see:
 *               http://code.google.com/apis/youtube/js_api_reference.html
 * @param String frame_id The id of the div containing the frame
 * @param String func     Desired function to call, eg. "playVideo"
 * @param Array  args     (optional) List of arguments to pass to function func*/
function callPlayer(frame_id, func, args){
    if(!document.getElementById(frame_id)) return;
    args = args || [];

    /*Searches the document for the IFRAME with id=frame_id*/
    var all_iframes = document.getElementsByTagName("iframe");
    for(var i=0, len=all_iframes.length; i<len; i++){
        if(all_iframes[i].id == frame_id || all_iframes[i].parentNode.id == frame_id){
           /*The index of the IFRAME element equals the index of the iframe in
             the frames object (<frame> . */
           window.frames[i].postMessage(JSON.stringify({
                "event": "command",
                "func": func,
                "args": args,
                "id": 1/*Can be omitted.*/
            }), "*");
        }
    }
}
</script>
</head><body>
<div id="holder">
   <iframe id="player" type="text/html" width="320" height="240"
  src="http://www.youtube.com/embed/u1zgFlCw8Aw?wmode=transparent?enablejsapi=1"
  frameborder="0"></iframe>
</div>
<div id="ID-of-first-div"></div>
<div id="ID-of-second-div"></div>
      
<div id="btn1"></div>
</body></html>
Community
  • 1
  • 1
Rob W
  • 341,306
  • 83
  • 791
  • 678
  • First, thanks for the answer! Like I already said, this works like charm with Vimeo iframe embed: http://jsfiddle.net/jgtSS/33/ Not sure why it doesnt with youtube. For your answer, this means I need to have preview image. How do I get preview image for youtube video? – Toniq Oct 23 '11 at 15:03
  • @Toniq `http://i2.ytimg.com/vi/VIDEOID here/hqdefault.jpg`, example: http://i2.ytimg.com/vi/u1zgFlCw8Aw/hqdefault.jpg. I will update my answer to automate the picture-adding method. – Rob W Oct 23 '11 at 15:09
  • This is really become overkill :P Btw, regarding something very similar, I was trying to achieve this similary, I have posted this question somewhere: I am trying to fade out a div which lies above youtube iframe embed. i made a jsfiddle, you need to click on blue div, and it should fade out, which it does but it also immediatelly jumps below iframe. http://jsfiddle.net/jgtSS/2/ is there a way to prevent that? why does it change z index? (i want it to stay above) – Toniq Oct 23 '11 at 15:59
  • Another thing, is this url for getting video preview bulletproof? I heard these domains sometimes change? – Toniq Oct 23 '11 at 16:01
  • @Toniq As mentioned in my answer, the frame's contents will show up if either the [frame or first-level-layer] has an `opacity` or alpha-channel which is greater or equal to 1. By first-level-layer, I meant the first element which is (partially) above the IFrame. **About the URL**: It will match any video ID at YouTube. If you ever encounter a problem regarding the ID, feel free to ask a question. – Rob W Oct 23 '11 at 16:10
0

You should add wmode=opaque to the youtube url. Than it will fade smoothly. Like htis

<iframe src="http://www.youtube.com/embed/a-TrP8Z3Cb8?wmode=opaque" ...

Thanks to Canolucas awnser found here: https://stackoverflow.com/a/14426131/1303927

Community
  • 1
  • 1
Sjaak Wish
  • 455
  • 5
  • 8