Vimeo Froogaloop API not recognizing an event - javascript

I'm trying to recognize the onPlay, onPause, and onFinish event for vimeo using the froogaloop API. I've tried everything I could imagine with this thing, and no luck.
I get this error on Firefox:
And in Chrome:
Importing froogaloop from the CDN:
<script src="http://a.vimeocdn.com/js/froogaloop2.min.js"></script>
My JS:
$(function(){
var vimeoPlayer = document.querySelector('iframe');
$f(vimeoPlayer).addEvent('ready', ready);
function ready(player_id) {
froogaloop = $f(player_id);
function setupEventListeners() {
function onPlay() {
froogaloop.addEvent('play',
function(data) {
console.log('play event');
});
}
function onPause() {
froogaloop.addEvent('pause',
function(data) {
console.log('pause event');
});
}
function onFinish() {
froogaloop.addEvent('finish',
function(data) {
console.log('finish');
});
}
onPlay();
onPause();
onFinish();
}
setupEventListeners();
}
})
My HTML:
<iframe src="http://player.vimeo.com/video/3718294?api=1" width="623" height="350" frameborder="0" id="iframe-video"></iframe>

After hours and hours of frustration... I have found the solution.
Since I was using an ID on the iframe... apparently the vimeo API forces you to add the parameter to the URL you are fetching (player_id=iframe-id).
So the iFrame should look like this:
<iframe src="//player.vimeo.com/video/3718294?api=1&player_id=promo-vid"
width="623" height="350" frameborder="0"
id="promo-vid">
</iframe>
Special thanks to Drew Baker for pointing this out: http://vimeo.com/forums/topic:38114#comment_5043696

Got an error creating the player element when selecting the iframe with jQuery.
var iframe = $('#player1');
var player = $f(iframe);
Results in
TypeError: d[f] is undefined
Solution for me was to select the first element in the jQuery ID selector
var iframe = $('#player1')[0];
var player = $f(iframe);

I think you're violating the Same Origin Policy. You'll notice here that where you're doing a lot of event handling, they are using special froogaloop API calls.
I've never used froogaloop so I'm probably wrong. But that's my guess. The errors seem to suggest that the iframe is attempting to modify the URL in your browser, and that's now allowed by Same Origin. That's why the API wraps up window.postMessage for you.

I had a similar issue, but in this case after replacing Froggaloop with the Vimeo.Player, it still it was a new restriction in chrome. I was getting the error "play() failed because the user didn't interact with the document first...". After further research it looks like Chrome added some restrictions see here. The solution in my case was to add allow="autoplay" to the iframe.

Having had a similar issue, with Froggaloop2 - it appears that if the video is cached, the ready event will fire only once (on the initial load). The solution is to retrieve the iframe with changing src, as:
$(iframe).attr('src', $(iframe).attr('src') + '#timestamp='+(new Date()).getTime());

Related

YT iframe API throwing an error when subscribing to events using addEventListener

I stumbled upon an issue when using YT iframe API.
I have an YT iframe already set-up, and right after it I load the iframe API script:
<div class="youtube-wrapper">
<iframe
class="youtube"
src="https://www.youtube.com/embed/{{youtube_id}}?controls=1"
frameborder="0"
allowfullscreen
enablejsapi="true">
</iframe>
<script src="//www.youtube.com/iframe_api" async></script>
</div>
I don't need to support older browsers, so I opted to load it like this.
In document head I have this defined:
window.onYoutubePlayerStateChange = console.log;
window.onYouTubeIframeAPIReady = function() {
window.ytPlayers = $('iframe.youtube[enablejsapi]')
.map(function(youtubeIframe) {
return new YT.Player(youtubeIframe);
})
.get();
window.ytPlayers.forEach(function(ytPlayer) {
ytPlayer.addEventListener('onStateChange', 'onYoutubePlayerStateChange')
})
};
This breaks on adding event listener with Uncaught type error: Cannot read property 'subscribe' of null. Looking at where it breaks, it's in www-widgetapi.js:107:7 where in
this.f.subscribe(a,c)
this.f is null.
I also tried adding the event listener only when the API is ready, with
var player = new YT.Player(ytIframe, {
events: {
'onReady': function(e) { e.target.addEventListener(...); }
}
});
, and I tried adding an onStateChange event handler there, but those handlers simply never get called.
Any idea what might be happening?
It seems that contrary to documentation, setting the iframe enablejsapi="true" doesn't work, and only when you add enablejsapi=1 query param to iframe src, player is set-up properly.
(I also didn't help myself by misusing the jQuery.map method which gives index of the element as the first param to the callback)

Remove id from iframe

I have an iframe of a certain page from a site that I'm using, but I don't want all the parts of that page to be displayed with the iframe. Particularly, there's a navigation sidebar on the page that I don't want to be in the iframe. I'm trying to achieve this with the javascript seen below, but I can't quite figure it out.
<iframe width="800" height="800" src="scores/new?site_id=193">
<script>
var element = document.getElementById("sidebar-wrapper");
element.parentNode.removeChild(element);
</script>
</iframe>
For security reasons you can't run javascript through iframes. There are some exceptions if you're on the same domain but for the most part you should really avoid it.
If the iframe isn't a site you can control then there's pretty much nothing you can do. If you do control the other site and it's a different domain you might be able to work with the postMessage functions.
Edit: Check out the docs that Mozilla has up here https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
You'd need to create a listener on the inside that handles a message and hides your sidebar. Then on the parent send a message to the iframe to trigger that function.
Parent:
var iframe = document.getElementById('#iframeID');
iframe.contentWindow.postMessage('iframeTrigger');
Iframe:
window.addEventListener('iframeTrigger', hideSidebar);
function hideSidebar() {
//do stuff
}
You can insert a control in the iframed page
//inside the iframed page
var iframe = (function() {
try {
return window.self !== window.top;
} catch (e) {
return true;
}
})();
if(iframe === true) {
var element = document.getElementById("sidebar-wrapper");
element.parentNode.removeChild(element);
}
Hope this could suit your need.
This should work theoretically, and it works in console. But this doesn't work in the HTML, although you are trying it from the same domain, because of security reasons. I just wanted to tell my view and I tried this:
<iframe src="http://output.jsbin.com/figujeyiyo" frameborder="0" id="ifrm">
Sorry, iframes not supported.
</iframe>
<script>
console.log(document.getElementById("ifrm").contentDocument.documentElement.getElementsByTagName("div"));
e = document.getElementById("ifrm").contentDocument.documentElement.getElementsByTagName("div")[0];
console.log(e);
e.parentNode.removeChild(element);
</script>
You need to execute the code when the page loads, you can do it like this:
document.addEventListener('DOMContentLoaded', function() {
var element = document.getElementById("sidebar-wrapper");
element.parentNode.removeChild(element);
});

OnReadyStateComplete is not fired

I try to add CRM javascript web resource and try to manage iframe elements, but iframe OnReadyStateComplete event is not fired. Below, the first alert works but the second does not.
function hello()
{
var audioPath= Xrm.Page.data.entity.attributes.get("new_audiopath").getValue();
//var myAudio = document.createElement('audio');
//myAudio.setAttribute('src', audioPath);
// myAudio.play();
var IFrame = Xrm.Page.ui.controls.get("IFRAME_Play");
alert(audioPath);
//var myAudio =Xrm.Page.ui.controls.get("audioSource");
IFrame.OnReadyStateComplete=function(){
alert('iframe ready');
}
}
I had similar problem, but only with iframe content from other domians. I think it's the security restrictions, not allowing to raise events.
We worked around it with a aspx-page on the server, which downloaded the content, and recreated it for the xrm script.
The IFrame control does not have an OnReadyStateComplete property or event. The SDK documentation only hints at the menu-option that is available in the form designer.
However, it is actually possible to attach a function to the onload event of the IFrame in a supported way:
var iFrameElement = Xrm.Page.getControl("IFRAME_Play").getObject();
iFrameElement.addEventListener("load", function() {
alert("IFrame Play loaded!");
}
Function getObject returns an IFrame object giving you access to the iFrame's window and the document it contains through its contentWindow and contentDocument properties. (See also HTML DOM IFrame Object.)

Using Vimeo's api after video called by ajax

I'm using the garnish theme for a site and when the visitors clicks on an item in the folio, it loads the post's content. The post is made of one or more videos from vimeo, called via iframe like this:
<iframe id="player_0" src="http://player.vimeo.com/video/57038297?title=0&byline=0&portrait=0&color=FF9A00&api=1&player_id=player_0" frameborder="0" width="632" height="356" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen=""></iframe>
I already have used vimeo's froogaloop to stop/unload videos from an external link (here's a very basic test). Here's the code for the control:
var vimeoPlayers = document.querySelectorAll('iframe'),
player;
for (var i = 0, length = vimeoPlayers.length; i < length; i++) {
player = vimeoPlayers[i];
$f(player).addEvent('ready', ready);
}
function addEvent(element, eventName, callback) {
if (element.addEventListener) {
element.addEventListener(eventName, callback, false);
}
else {
element.attachEvent(eventName, callback, false);
}
}
function ready(player_id) {
var container = document.getElementById(player_id),
froogaloop = $f(player_id);
$("a.stopvid").on('live', function(){ froogaloop.api('unload'); });
}
But this time i can't seem to manage to use the api as the video loads after an ajax call.
I've tryed to include the code above within an $(document).ajaxComplete(function(event, xhr, settings) { ... }); but with no luck.
Here's a test site to see it. The portfolio link in the menu, then click the first item. It'll load the content and a little cross on the top right corner that should stop the video, but doesn't.
Help would be highly appreciated, i'm pretty lost.
The first thing to do is to check if you don't have any javascript errors on your page.
Your iframe selector may be to generic and you may catch other iframe used by other "plugins" such as Facebook.
To work, the froogaloop ready fonction require an id on the iframe. If there is no id on the iframe, your ready event won't receive anything and the player_id will be undefined.
Since you are using JQuery, change the first line of your script by :
var vimeoPlayers = $("iframe#player_0"), player;
With this line you will be sure to select only the iframe you want.

Capture iframe load complete event

Is there a way to capture when the contents of an iframe have fully loaded from the parent page?
<iframe> elements have a load event for that.
How you listen to that event is up to you, but generally the best way is to:
1) create your iframe programatically
It makes sure your load listener is always called by attaching it before the iframe starts loading.
<script>
var iframe = document.createElement('iframe');
iframe.onload = function() { alert('myframe is loaded'); }; // before setting 'src'
iframe.src = '...';
document.body.appendChild(iframe); // add it to wherever you need it in the document
</script>
2) inline javascript, is another way that you can use inside your HTML markup.
<script>
function onMyFrameLoad() {
alert('myframe is loaded');
};
</script>
<iframe id="myframe" src="..." onload="onMyFrameLoad(this)"></iframe>
3) You may also attach the event listener after the element, inside a <script> tag, but keep in mind that in this case, there is a slight chance that the iframe is already loaded by the time you get to adding your listener. Therefore it's possible that it will not be called (e.g. if the iframe is very very fast, or coming from cache).
<iframe id="myframe" src="..."></iframe>
<script>
document.getElementById('myframe').onload = function() {
alert('myframe is loaded');
};
</script>
Also see my other answer about which elements can also fire this type of load event
Neither of the above answers worked for me, however this did
UPDATE:
As #doppleganger pointed out below, load is gone as of jQuery 3.0, so here's an updated version that uses on. Please note this will actually work on jQuery 1.7+, so you can implement it this way even if you're not on jQuery 3.0 yet.
$('iframe').on('load', function() {
// do stuff
});
There is another consistent way (only for IE9+) in vanilla JavaScript for this:
const iframe = document.getElementById('iframe');
const handleLoad = () => console.log('loaded');
iframe.addEventListener('load', handleLoad, true)
And if you're interested in Observables this does the trick:
import { fromEvent } from 'rxjs';
const iframe = document.getElementById('iframe');
fromEvent(iframe, 'load').subscribe(() => console.log('loaded');
Note that the onload event doesn't seem to fire if the iframe is loaded when offscreen. This frequently occurs when using "Open in New Window" /w tabs.
Step 1: Add iframe in template.
<iframe id="uvIFrame" src="www.google.com"></iframe>
Step 2: Add load listener in Controller.
document.querySelector('iframe#uvIFrame').addEventListener('load', function () {
$scope.loading = false;
$scope.$apply();
});
You can also capture jquery ready event this way:
$('#iframeid').ready(function () {
//Everything you need.
});
Here is a working example:
http://jsfiddle.net/ZrFzF/

Categories

Resources