I have tried in JSFiddle, on my local server, and on a production server, and I cannot figure out what is wrong with my event handler. It never fires. Also, when I run in Google Chrome I get no errors, when I run in Safari, I get:
Blocked a frame with origin "http://www.youtube.com" from accessing a frame with origin "http://jsfiddle.net". Protocols, domains, and ports must match.
What am I missing?
Code:
<script src="http://www.youtube.com/player_api"></script>
<iframe
id="player"
width="426"
height="240"
src="http://www.youtube.com/embed/21eGxOKUxeM?enablejsapi=1&origin=*"
frameborder="0"
allowfullscreen></iframe>
<script>
function player_state_changed(state) {
alert('state changed');
}
document.getElementById('player').addEventListener(
'onStateChange', player_state_changed
);
</script>
Example in JS Fiddle
@Justin -- in response to your comment, here's some code and a short explanation. There are two things to watch out for ... first of all, I generally load the iFrame API library like this:
<script>
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
This way, it won't load until the page is loaded, which is key to the second step -- when the code loads, it will automatically call the function onYouTubeIframeAPIReady
, which you need to define. It's within this function that you can create your bound player object. If you try to do it outside this callback function, you A) run the risk of creating your player object before the iframe API library loads which means it couldn't trigger any player functions, and B) can't bind to elements that already exist on the page as they might not yet be loaded. It looks like this:
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player("ytplayer", {
events: {
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING) {
alert("now playing ...");
}
}
</script>
This assumes I've given my iframe the id of ytplayer, and that I've appended "?enablejsapi=1" to the URL of the iframe's src attribute.
Here's a working fiddle: http://jsfiddle.net/jlmcdonald/PQy4C/261/
I was able to get it working by including the video via JavaScript instead of an <iframe>
. Still not sure why it wouldn't work if I had the <iframe>
added myself... but this does work:
http://jsfiddle.net/Mm88p/4/
<div id="player"></div>
<script src="https://www.youtube.com/player_api"></script>
<script>
// YouTube API
player = new YT.Player('player', {
height: '240',
width: '426',
videoId: '21eGxOKUxeM',
events: {
'onStateChange': onPlayerStateChange
}
});
function onPlayerStateChange(state) {
alert('state changed');
}
</script>