0

Basically, is there a way to make an image/div "invisible" in the sense that user click passes right through it to div beneath it in z-space?

Example is Youtube video in iframe, but want custom play button. Catch is that it must be user pressing the native play button that initiates play. It cannot be triggered via js api or any automated method. So... essentially need to have user see the image, but have it act as if it is not there when user clicks.

Any suggestions?

aintnobody
  • 129
  • 1
  • 11
  • further reading http://stackoverflow.com/questions/5693582/propagating-mouse-events-from-iframes-to-the-hosting-document – corn3lius Jan 20 '15 at 20:10
  • OK. Read up a little on propagation. Very unclear as to whether that would invalidate the play, though. I know anything involving their js api does. Any autoplay, etc. All invalid. – aintnobody Jan 20 '15 at 20:29
  • http://stackoverflow.com/questions/2094668/overlay-div-over-iframe basically cross domain events means your hosed – corn3lius Jan 20 '15 at 20:35
  • Well, hosed for propagation, but is there definitely no other solution? Something more basic that just basically ignores a div or makes it visible but not "solid?" – aintnobody Jan 20 '15 at 20:56

2 Answers2

1

EDIT 04-22-2015

Regarding your comment:

We can read in the doc that player.playVideo() don't count toward incremental YouTube brand channel video views. Only the native button play will work for this.

In fact we can read on the doc :

player.playVideo():Void Plays the currently cued/loaded video. The final player state after this function executes will be playing (1).

Note: A playback only counts toward a video's official view count if it is initiated via a native play button in the player.

source: https://developers.google.com/youtube/iframe_api_reference#playVideo

This information is confirmed by the official YouTube support

Part: YouTube public play count

The YouTube Video Player allows masthead video views to count directly toward overall YouTube brand channel video views. For the YouTube view to count, the user must click to start the video using the standard YouTube play button. Autoplay videos don't count toward YouTube views.

Part:Standard VS chromeless

The chromeless YouTube Player lets you customize features like player controls, while still pulling in YouTube-served videos. Aside from the standard play button overlay, clicks on the chromeless player's custom control buttons don't count toward incremental YouTube brand channel video views.

source: https://support.google.com/richmedia/answer/2566092?hl=en

So i made a new solution with function hide() and show() of Jquery. With this solution, the user will click on the native button player and if the video is not playing there is an image head-on.

You need to use the element, and not the API

HTML

$(".player-video").mouseenter(function() {
    $('.player-video').hide();
    $('#player').show();
});

$("#player").mouseleave(function() {
      $('.player-video').show();
      $('#player').hide();
});

Javacript

  <iframe id="player" width="560" height="315" src="https://www.youtube.com/embed/l-gQLqv9f4o" frameborder="0" allowfullscreen style="display:none"></iframe>
  <div class="player-video">
  </div>

Im made you another live example: http://jsbin.com/luqewajuse/1/edit?html,js,console,output

END EDIT


You can use:

<div id="player"></div>
<button class="play-video">Play</button> //can be button or whatever

$(".play-video").click(function() {
     player.playVideo();
}

EDIT 31/01/2015

Regarding your comments and what you trying to do, i make you a live demo to show you how it work :

Live demo : http://jsbin.com/jefubusejo/2/edit?html,js,output

HTML:

<!DOCTYPE html>
<html>
<head>
<script src="//code.jquery.com/jquery-2.1.1.min.js"></script>
  <meta charset="utf-8">
  <title>JS Bin</title>

  <style>
.player-video {
    width: 600px;
    height: 340px;
    background-image:url('http://www.hqsoul.com/wp-content/uploads/2014/11/Mark-Ronson-Uptown-Funk-ft.-Bruno-Mars.jpg');
}
    </style>
</head>
<body>
  <div id="player" style="display:none"></div>
  <div class="player-video">
  </div>
</body>
</html>

Javascript:

var tag = document.createElement('script');

tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

// 3. This function creates an <iframe> (and YouTube player)
//    after the API code downloads.
var player;

$(".player-video").click(function() {
  $('.player-video').hide();
  $('#player').show();
  onPlayerReady();

});

function onYouTubeIframeAPIReady() {
    player = new YT.Player('player', {
        height: '390',
        width: '640',
        videoId: 'l-gQLqv9f4o',
        events: {
                'onStateChange': onPlayerStateChange
        }
    });
}

// 4. The API will call this function when the video player is ready.
function onPlayerReady() {
    player.playVideo();
}

// 5. The API calls this function when the player's state changes.
//    The function indicates that when playing a video (state=1),
//    the player should play for six seconds and then stop.
var done = false;

function onPlayerStateChange(event) {
    if (event.data == YT.PlayerState.PLAYING && !done) {
        setTimeout(stopVideo, 6000);
        done = true;
    }
}

function stopVideo() {
    player.stopVideo();
}
mpgn
  • 7,121
  • 9
  • 67
  • 100
  • These solutions might work, but maybe I should have been more specific. Youtube says explicitly that the play must come from a user clicking on their play button. Automation of the click of any kind will invalidate the play. So will using a 3rd party player. Just repeating what they've said. Dont' know enough to tell if that invalidates these solutions. – aintnobody Jan 20 '15 at 20:27
  • @aintnobody nop. Basically the button play do `player.playVideo();` the exact same thing that you do on `$(".play-video").click`. Even in the YouTube Player demo they do like this. Maybe you should look up the code may by YouTube dev team and try by yourself before telling us we have wrong. – mpgn Jan 20 '15 at 22:34
  • Not trying to tell anyone they're wrong. Just trying to clarify since I didn't do a good job of that starting out... and to learn. I tried plugging your method into fiddle here: http://jsfiddle.net/v9uq651g/ Can't get it working. Image is stacked exactly above player. If I put "pointer-events: none on image, it works (but not in some browsers). I think I've followed the above in my example, but perhaps I have missed something. In either case, fiddle should give a clearer picture of my intent. Just want click to go through to player. Will figure how to hide poster on play later. – aintnobody Jan 31 '15 at 02:55
  • That's great information, and I've dug into the code (much of which I recognize from the Youtube Player API reference) and created something close to what I'm trying to do here: http://jsbin.com/lalelonoyu/1/edit?html,js,output, but am I seriously misinterpreting that same YouTube reference page when it says right below player.playVideo() "Note: A playback only counts toward a video's official view count if it is initiated via a native play button in the player." That appears to me to be a warning that player:playVideo will not count toward views which is why I was trying ponter-events: none – aintnobody Jan 31 '15 at 18:29
  • I've swapped out the video in jsbin for one with no views so I could see if I could increment viewcount. So far, over 20 plays are not showing. I extended the timeout too to play the entire one minute video to make sure views weren't being tossed for being too short. Now maybe viewcount not increasing is due to a lag in reporting, I really don't know as I have been unable to find a straight answer anywhere as to when embed views (those that do count, anyway) are tallied. YT employee somewhere said specifically that initiating play via API is a no go for viewcount. Am I misinterpreting? – aintnobody Jan 31 '15 at 18:44
  • I think it's a lag of reporting, wait tomorrow, we will see – mpgn Jan 31 '15 at 19:24
  • 4-5 days later, and nope. No views registered via embed player. The warning in the YT demo page is directly beneath the part explaining player.playVideo() and appears to be a direct warning that that method (or any method involving API according to at least one YT employee) will not count. Wording may even be indicating that any play is invalid even if user clicks play button directly... if the player itself was generated via api instead of "native player.". In either case, this does not appear to be working which leads back to original question. – aintnobody Feb 04 '15 at 19:28
  • OK, I see now. Answer from other thread appended above. I wasn't scrolled up far enough to see that part. Got it. Looking into now. – aintnobody Feb 04 '15 at 21:50
  • I can't check on mobile at the moment, but without mouseover, wouldn't it still have poster in front for mobile? Actual sequence of events is a bit more complex. Animation already worked out for overlay play button to bounce and scale down, poster frame to gracefully fade out, etc... For several reasons don't want to see iframe until after click occurs... and don't want functionality to be any different between mobile and desktop. – aintnobody Feb 04 '15 at 22:00
  • @aintnobody so choose chromeless player and say "view count is not the most important thing regarding the design i want" – mpgn Feb 04 '15 at 22:04
  • Simplifying here. Views are the most important thing... and the ability to have a custom player with the right overlays (opt-in forms diving subscriptions, dynamic post-rolls, sharing options, etc) ultimately drives views MUCH more effectively than YT player ever could. There's all sorts of data on this. I already have most of those items and more worked out. It's just this issue of clickthrough that needs resolving. Ultimately, i think I need a way to pass clicks (propagation, pointer-events, or something functionally similar).. but poster image will still there when user clicks. – aintnobody Feb 04 '15 at 22:33
0

function myclick() { console.log("Click") } 
#front, #back {
  position:absolute;
  top:10px;
  left:10px; 
  border:1px solid black; 
  width:100px;
  height:100px;
  }
#front { 
  width:80px;
  border-radius:30px;
  z-index:1;
  border-color:red;
  }
<div id="back" onclick="myclick()" >
<div id="front"></div>
  </div>

<p id='this-tag'></p>
corn3lius
  • 4,857
  • 2
  • 31
  • 36
  • Isn't that using js to produce the click though? I'm thinking that might invalidate the play according to YT's formula. I'll look into this kind of solution to verify for sure whether it can be done if there is no simpler non-js solution. So there is no way to just make the div "invisible" so it clicks through? (versus registering the click, then using js to click the underlying div) – aintnobody Jan 20 '15 at 20:01
  • this solution uses propagation, click event is triggered at the front then the back. I only handle it in the back though. – corn3lius Jan 20 '15 at 20:08
  • I've been messing with this including this codepen: http://codepen.io/oompaLoompa/pen/QwqRER Problem is, I can get it to work with divs all day long, but the second I put a YT iframe as the item behind, it won't register. Doesn't matter what kind of image (or none) is in front. Any div in front will pass click to div behind, but not register if YT iframe behind. Is this a dead end due to different hosted domains? I see a couple tools out there to deal with xds issues, but seems they are no longer supported, etc. Or, is there some other issue at play here? – aintnobody Feb 04 '15 at 20:52
  • http://codepen.io/corn3lius/pen/xbXvWb this will try and get elements from the iframe. but there are security issues that happen from cross domain events. – corn3lius Feb 05 '15 at 03:36
  • I get the basics of the security issues, but I'm thinking this would be much simpler. I see in pen how click registers (although it also throws error message "Permission denied to access property 'document'". Ultimately, though, I don't actually need to read anything back from the iframe. API takes care of playerstate callbacks which is all I need from the iframe. The only thing I need to have happen without API is for the click above to trigger play beneath, which is not happening. I would have guessed that part alone would be much easier as it's seemingly the most straightforward bit. – aintnobody Feb 05 '15 at 17:47