Retrieve width of embedded video using javascript - javascript

I have a simple page with an embedded video. Below is an example. I want to retrieve the width of the embedded video's iframe, which can vary ( for example if the video is from youtube or vimeo ). Then I can put a div next to it, with some text, and adjust the width of the latter accordingly
<html>
<head>
</head>
<body onLoad = "resizeElements()">
<iframe width="420" height="315" src="http://www.youtube.com/embed/a34QTcpnKww" frameborder="0" allowfullscreen>
</iframe>
</body>
<script language="JavaScript" type="text/javascript">
function resizeElements()
{
var iframeVideos = document.getElementsByTagName("iframe");
for ( var i = 0; i < iframeVideos.length; i++)
{
video = iframeVideos[i];
alert ( ">" + video.style.width+ "<" );
video.style.width = "112px";
video.style.height = "63px";
alert ( ">" + video.style.width+ "<" );
}
}
</script>
</html>
The page is loaded, and the first alert ( which should have the width of the iframe ) only shows "><", without the width of the video in between.
I am sure that it's not because the video object is null. The following lines resize it as expected. After the resizing, the same alert brings up the correct width.
Is there anything I can do to have the width available straight away?
I am not a big fan of libraries such as jQuery, but happy to consider in case one of them gives a straight forward solution which doesn't make it more complicated than just parsing the string inside the tag. Just in case the page needs some maintenance in the future...
Thanks!

I think that you just need to set the style attribute to match your width and height attributes:
<iframe style="width:420;height:315" width="420" height="315" src="http://www.youtube.com/embed/a34QTcpnKww" frameborder="0" allowfullscreen>
</iframe>
Because in your function, you are working with the style attribute.

DOM: element.offset*
offsetWidth and offsetHeight should help, supported even in IE6 and all modern browsers.
alert ( ">" + video.offsetWidth + "<" );
Please take a look the jsFiddle Demo.
jQuery width()/height()
If you feel ready to use jQuery, check out .width() and height(). I am not a "fan" of jQuery either, but if you're tired of working around browser inconsistencies, need advanced event handling support (instead of your current inline event handlers) and great DOM helpers, it is an amazing tool to have.
Attributes
Another way would be to simply retrieve the HTML attribute's content (being width="420"). You can do that using .getAttribute(width) or .width (which accesses the DOM property).
alert ( ">" + video.width + "<" );
alert ( ">" + video.getAttribute(width) + "<" );

Related

Adobe XD embedded app-prototype causes page to 'jump' down to mid-page after loading

I use Squarespace for my portfolio site. They have a "block" that allows me to use embedded Adobe XD code (below) to show my app prototype. The prototype works fine but when the page loads, it automatically shifts half way down the page to the prototype. link to page
<center>
<iframe id="nautilab" width="414" height="736" src="https://xd.adobe.com/embed/afb3c48a-11a6-4296-73d9-068cd5b0c5ef-d982" allowfullscreen" frameborder="0">
</iframe>
</center>
I would like for my page to remain at the top when fully loaded instead of jumping down mid-page to the prototype. I've tried countless solutions such as using sandbox, lazy loading, and loading on scroll view. I've tried using "data src=""" as well among other options.
Unfortunately none of these solutions worked. The only time it doesn't jump down to the prototype is when it doesn't load at all (which happened with lazy loading, loading on scroll). How can I fix this? I'm able to use HTML, CSS, and JavaScript as well.
My best guess is to delay loading the prototype until it's in view. The only other option would be placing the prototype at the top of the page, which is not what I want (it messes up the flow of the project).
Any help is greatly appreciated!
Option 1: Use the "sandbox" attribute.
This appears to be a known issue within the Adobe Community site, with a solution proposed using the sandbox iframe attribute.
<iframe id="nautilab" width="414" height="736" src="https://xd.adobe.com/embed/afb3c48a-11a6-4296-73d9-068cd5b0c5ef-d982" allowfullscreen" frameborder="0" sandbox="allow-same-origin allow-forms allow-scripts"></iframe>
Or, possibly even more restrictive (which may cause the iframe not to work):
<iframe id="nautilab" width="414" height="736" src="https://xd.adobe.com/embed/afb3c48a-11a6-4296-73d9-068cd5b0c5ef-d982" allowfullscreen" frameborder="0" sandbox></iframe>
Option 2: Use the "onload" attribute with "scroll()"
If neither of the above work, you could try using the onload attribute to force the scroll position:
<iframe id="nautilab" width="414" height="736" src="https://xd.adobe.com/embed/afb3c48a-11a6-4296-73d9-068cd5b0c5ef-d982" allowfullscreen" frameborder="0" onload="scroll(0,0);"></iframe>
Option 3: Load the iframe only when in view.
If neither option 1 or 2 work, you could only load the iframe once it is already in view for the user (once they have scrolled down). For browsers that don't support IntersectionObserver, keep the external link as you have it. For browsers that do, hide the link and load the iframe. Insert the following via a code block above the image block that has your external link:
<iframe id="nautilab" width="0" height="0" frameborder="0" allowFullScreen></iframe>
Then insert the following via sitewide footer code injection
<script>
(function() {
var target,
io,
ioCallback,
ioOptions,
linkBlock;
// Exit if id "nautilab" not found.
target = document.querySelector('#nautilab');
if (!target) {
return;
}
// Check for IntersectionObserver Support: https://github.com/w3c/IntersectionObserver/issues/296#issuecomment-452230176
if (!('IntersectionObserver' in window) ||
!('IntersectionObserverEntry' in window) ||
!('intersectionRatio' in window.IntersectionObserverEntry.prototype)) {
target.style.display = "none";
return;
}
// Because IntersectionObserver is supported, hide external link to prototype.
linkBlock = document.querySelector('#block-yui_3_17_2_1_1574114822673_377170');
linkBlock.style.display = "none";
// Loads the iframe when the 'target' is in view.
ioCallback = function(entries, observer) {
entries.forEach(function(entry) {
if (entry.intersectionRatio) {
observer.disconnect();
target.height = "736"
target.width = "414";
target.src = "https://xd.adobe.com/embed/afb3c48a-11a6-4296-73d9-068cd5b0c5ef-d982";
}
});
};
ioOptions = {
root: null,
rootMargin: "0px",
threshold: 1
};
// Observe for 'target' to be in view.
io = new IntersectionObserver(ioCallback, ioOptions);
io.observe(target);
})();
</script>
You'll still have to center the prototype using CSS, which shouldn't be too difficult.

Removing Youtube branding, title text etc. from an embedded iframe after it goes into fullscreen mode

A pleasant good day to you all :)
I'm trying to remove the youtube branding from an iframe after it goes into fullscreen mode. You can see a sample of what I am attempting here: https://codepen.io/emjaisthebest/pen/ZmaKGv
HTML
<p><img data-video="XqC05_Oommw" alt="Play this video" src="http://img.youtube.com/vi/Y7d42LJfkqQ/0.jpg"></p>
CSS
div:fullscreen .ytp-title-text .ytp-title-link .yt-uix-sessionlink .ytp-title .ytp-title-channel-logo .ytp-title-text .ytp-watch-later-icon .ytp-button .ytp-settings-button .ytp-hd-quality-badge .ytp-title-expanded-title .ytp-youtube-button .ytp-button .yt-uix-sessionlink .ytp-menuitem-label .ytp-menuitem-content .ytp-play-button .ytp-progress-list .ytp-scrubber-button .ytp-swatch-background-color .ytp-time-duration .ytp-time-separator .ytp-time-current /Not sure if you want to hide the current time, babe/ .ytp-share-icon .ytp-pause-overlay .ytp-related-title .ytp-pause-overlay .ytp-suggestions .ytp-expand-pause-overlay .ytp-fullscreen-button .ytp-progress-bar-padding .ytp-progress-bar .admin-bar .ytp-title-channel .ytp-title-beacon .ytp-chrome-top .ytp-show-watch-later-title .ytp-share-button-visible .ytp-show-share-title {
display: none !important;
}
Javascript
if (!Element.prototype.requestFullscreen) {
Element.prototype.requestFullscreen = Element.prototype.mozRequestFullscreen || Element.prototype.webkitRequestFullscreen || Element.prototype.msRequestFullscreen;
}
// Listen for clicks
document.addEventListener('click', function (event) {
// Check if clicked element is a video thumbnail
var videoId = event.target.getAttribute('data-video');
if (!videoId) return;
// Create iframe
var iframe = document.createElement('div');
iframe.innerHTML = '<p>x</p><iframe width="560" height="315" src="https://www.youtube.com/embed/' + videoId + '?rel=0&autoplay=1" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>';
var video = iframe.childNodes[1];
// Replace the image with the video
event.target.parentNode.replaceChild(video, event.target);
// Enter fullscreen mode
video.requestFullscreen();
}, false);
I know the css classes for all the elements I want to hide, but every time I try, it just does NOT work.
Is there anyone out there who can help me remove the ugly youtube branding? If yes, please help me as this is my first website and I would really love to make it aesthetically pleasing.
Edit #1: Someone was suggesting that my question was a possible duplicate of another question found here on stackoverflow, but that has nothing to do with removing the youtube branding from an iframe itself or modifying the iframe while it is in fullscreen mode. I, myself was trying to change it using the :fullscreen pseudo-class with no success. Could someone please tell me what I am doing wrong?
What might work for you is the modestbranding=1 parameter. For example:
src="https://www.youtube.com/embed/' + videoId + '?rel=0&autoplay=1&modestbranding=1"
You can read more about it here: https://developers.google.com/youtube/player_parameters#modestbranding

How to pause a YouTube player when hiding the iframe?

I have a hidden div containing a YouTube video in an <iframe>. When the user clicks on a link, this div becomes visible, the user should then be able to play the video.
When the user closes the panel, the video should stop playback. How can I achieve this?
Code:
<!-- link to open popupVid -->
<p>Click here to see my presenting showreel, to give you an idea of my style - usually described as authoritative, affable and and engaging.</p>
<!-- popup and contents -->
<div id="popupVid" style="position:absolute;left:0px;top:87px;width:500px;background-color:#D05F27;height:auto;display:none;z-index:200;">
<iframe width="500" height="315" src="http://www.youtube.com/embed/T39hYJAwR40" frameborder="0" allowfullscreen></iframe>
<br /><br />
<a href="javascript:;" onClick="document.getElementById('popupVid').style.display='none';">
close
</a>
</div><!--end of popupVid -->
The easiest way to implement this behaviour is by calling the pauseVideo and playVideo methods, when necessary. Inspired by the result of my previous answer, I have written a pluginless function to achieve the desired behaviour.
The only adjustments:
I have added a function, toggleVideo
I have added ?enablejsapi=1 to YouTube's URL, to enable the feature
Demo: http://jsfiddle.net/ZcMkt/
Code:
<script>
function toggleVideo(state) {
// if state == 'hide', hide. Else: show video
var div = document.getElementById("popupVid");
var iframe = div.getElementsByTagName("iframe")[0].contentWindow;
div.style.display = state == 'hide' ? 'none' : '';
func = state == 'hide' ? 'pauseVideo' : 'playVideo';
iframe.postMessage('{"event":"command","func":"' + func + '","args":""}', '*');
}
</script>
<p>Click here to see my presenting showreel, to give you an idea of my style - usually described as authoritative, affable and and engaging.</p>
<!-- popup and contents -->
<div id="popupVid" style="position:absolute;left:0px;top:87px;width:500px;background-color:#D05F27;height:auto;display:none;z-index:200;">
<iframe width="500" height="315" src="http://www.youtube.com/embed/T39hYJAwR40?enablejsapi=1" frameborder="0" allowfullscreen></iframe>
<br /><br />
close
Here's a jQuery take on RobW's answer for use hiding /pausing an iframe in a modal window:
function toggleVideo(state) {
if(state == 'hide'){
$('#video-div').modal('hide');
document.getElementById('video-iframe'+id).contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}', '*');
}
else {
$('#video-div').modal('show');
document.getElementById('video-iframe'+id).contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*');
}
}
The html elements referred to are the modal div itself (#video-div) calling the show / hide methods, and the iframe (#video-iframe) which has the video url as is src="" and has the suffix enablejsapi=1? which enables programmatic control of the player (ex. .
For more on the html see RobW's answer.
Here is a simple jQuery snippet to pause all videos on the page based off of RobW's and DrewT's answers:
jQuery("iframe").each(function() {
jQuery(this)[0].contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}', '*')
});
Hey an easy way is to simply set the src of the video to nothing, so that the video will desapear while it's hidden an then set the src back to the video you want when you click on the link that opens the video.. to do that simply set an id to the youtube iframe and call the src function using that id like this:
<script type="text/javascript">
function deleteVideo()
{
document.getElementById('VideoPlayer').src='';
}
function LoadVideo()
{
document.getElementById('VideoPlayer').src='http://www.youtube.com/embed/WHAT,EVER,YOUTUBE,VIDEO,YOU,WHANT';
}
</script>
<body>
<p onclick="LoadVideo()">LOAD VIDEO</P>
<p onclick="deleteVideo()">CLOSE</P>
<iframe id="VideoPlayer" width="853" height="480" src="http://www.youtube.com/WHAT,EVER,YOUTUBE,VIDEO,YOU,HAVE" frameborder="0" allowfullscreen></iframe>
</boby>
Since you need to set ?enablejsapi=true in the src of the iframe before you can use the playVideo / pauseVideo commands mentioned in other answers, it might be useful to add this programmatically via Javascript (especially if, eg. you want this behaviour to apply to videos embedded by other users who have just cut and paste a YouTube embed code). In that case, something like this might be useful:
function initVideos() {
// Find all video iframes on the page:
var iframes = $(".video").find("iframe");
// For each of them:
for (var i = 0; i < iframes.length; i++) {
// If "enablejsapi" is not set on the iframe's src, set it:
if (iframes[i].src.indexOf("enablejsapi") === -1) {
// ...check whether there is already a query string or not:
// (ie. whether to prefix "enablejsapi" with a "?" or an "&")
var prefix = (iframes[i].src.indexOf("?") === -1) ? "?" : "&";
iframes[i].src += prefix + "enablejsapi=true";
}
}
}
...if you call this on document.ready then all iframes in a div with a class of "video" will have enablejsapi=true added to their source, which allows the playVideo / pauseVideo commands to work on them.
(nb. this example uses jQuery for that one line that sets var iframes, but the general approach should work just as well with pure Javascript if you're not using jQuery).
I wanted to share a solution I came up with using jQuery that works if you have multiple YouTube videos embedded on a single page. In my case, I have defined a modal popup for each video as follows:
<div id="videoModalXX">
...
<button onclick="stopVideo(videoID);" type="button" class="close"></button>
...
<iframe width="90%" height="400" src="//www.youtube-nocookie.com/embed/video_id?rel=0&enablejsapi=1&version=3" frameborder="0" allowfullscreen></iframe>
...
</div>
In this case, videoModalXX represents a unique id for the video. Then, the following function stops the video:
function stopVideo(id)
{
$("#videoModal" + id + " iframe")[0].contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}', '*');
}
I like this approach because it keeps the video paused where you left off in case you want to go back and continue watching later. It works well for me because it's looking for the iframe inside of the video modal with a specific id. No special YouTube element ID is required. Hopefully, someone will find this useful as well.
You can stop the video by calling the stopVideo() method on the YouTube player instance before hiding the div e.g.
player.stopVideo()
For more details see here: http://code.google.com/apis/youtube/js_api_reference.html#Playback_controls
RobW's way worked great for me. For people using jQuery here's a simplified version that I ended up using:
var iframe = $(video_player_div).find('iframe');
var src = $(iframe).attr('src');
$(iframe).attr('src', '').attr('src', src);
In this example "video_player" is a parent div containing the iframe.
just remove src of iframe
$('button.close').click(function(){
$('iframe').attr('src','');;
});
Rob W answer helped me figure out how to pause a video over iframe when a slider is hidden. Yet, I needed some modifications before I could get it to work. Here is snippet of my html:
<div class="flexslider" style="height: 330px;">
<ul class="slides">
<li class="post-64"><img src="http://localhost/.../Banner_image.jpg"></li>
<li class="post-65><img src="http://localhost/..../banner_image_2.jpg "></li>
<li class="post-67 ">
<div class="fluid-width-video-wrapper ">
<iframe frameborder="0 " allowfullscreen=" " src="//www.youtube.com/embed/video-ID?enablejsapi=1 " id="fitvid831673 "></iframe>
</div>
</li>
</ul>
</div>
Observe that this works on localhosts and also as Rob W mentioned "enablejsapi=1" was added to the end of the video URL.
Following is my JS file:
jQuery(document).ready(function($){
jQuery(".flexslider").click(function (e) {
setTimeout(checkiframe, 1000); //Checking the DOM if iframe is hidden. Timer is used to wait for 1 second before checking the DOM if its updated
});
});
function checkiframe(){
var iframe_flag =jQuery("iframe").is(":visible"); //Flagging if iFrame is Visible
console.log(iframe_flag);
var tooglePlay=0;
if (iframe_flag) { //If Visible then AutoPlaying the Video
tooglePlay=1;
setTimeout(toogleVideo, 1000); //Also using timeout here
}
if (!iframe_flag) {
tooglePlay =0;
setTimeout(toogleVideo('hide'), 1000);
}
}
function toogleVideo(state) {
var div = document.getElementsByTagName("iframe")[0].contentWindow;
func = state == 'hide' ? 'pauseVideo' : 'playVideo';
div.postMessage('{"event":"command","func":"' + func + '","args":""}', '*');
};
Also, as a simpler example, check this out on JSFiddle
This approach requires jQuery. First, select your iframe:
var yourIframe = $('iframe#yourId');
//yourId or something to select your iframe.
Now you select button play/pause of this iframe and click it
$('button.ytp-play-button.ytp-button', yourIframe).click();
I hope it will help you.
RobW's answers here and elsewhere were very helpful, but I found my needs to be much simpler. I've answered this elsewhere, but perhaps it will be useful here also.
I have a method where I form an HTML string to be loaded in a UIWebView:
NSString *urlString = [NSString stringWithFormat:#"https://www.youtube.com/embed/%#",videoID];
preparedHTML = [NSString stringWithFormat:#"<html><body style='background:none; text-align:center;'><script type='text/javascript' src='http://www.youtube.com/iframe_api'></script><script type='text/javascript'>var player; function onYouTubeIframeAPIReady(){player=new YT.Player('player')}</script><iframe id='player' class='youtube-player' type='text/html' width='%f' height='%f' src='%#?rel=0&showinfo=0&enablejsapi=1' style='text-align:center; border: 6px solid; border-radius:5px; background-color:transparent;' rel=nofollow allowfullscreen></iframe></body></html>", 628.0f, 352.0f, urlString];
You can ignore the styling stuff in the preparedHTML string. The important aspects are:
Using the API to create the "YT.player" object. At one point, I only had the video in the iFrame tag and that prevented me from referencing the "player" object later with JS.
I've seen a few examples on the web where the first script tag (the one with the iframe_api src tag) is omitted, but I definitely needed that to get this working.
Creating the "player" variable at the beginning of the API script. I have also seen some examples that have omitted that line.
Adding an id tag to the iFrame to be referenced in the API script. I almost forgot that part.
Adding "enablejsapi=1" to the end of the iFrame src tag. That hung me up for a while, as I initially had it as an attribute of the iFrame tag, which does not work/did not work for me.
When I need to pause the video, I just run this:
[webView stringByEvaluatingJavaScriptFromString:#"player.pauseVideo();"];
Hope that helps!
This is working fine to me with YT player
createPlayer(): void {
return new window['YT'].Player(this.youtube.playerId, {
height: this.youtube.playerHeight,
width: this.youtube.playerWidth,
playerVars: {
rel: 0,
showinfo: 0
}
});
}
this.youtube.player.pauseVideo();
A more concise, elegant, and secure answer: add “?enablejsapi=1” to the end of the video URL, then construct and stringify an ordinary object representing the pause command:
const YouTube_pause_video_command_JSON = JSON.stringify(Object.create(null, {
"event": {
"value": "command",
"enumerable": true
},
"func": {
"value": "pauseVideo",
"enumerable": true
}
}));
Use the Window.postMessage method to send the resulting JSON string to the embedded video document:
// |iframe_element| is defined elsewhere.
const video_URL = iframe_element.getAttributeNS(null, "src");
iframe_element.contentWindow.postMessage(YouTube_pause_video_command_JSON, video_URL);
Make sure you specify the video URL for the Window.postMessage method’s targetOrigin argument to ensure that your messages won’t be sent to any unintended recipient.

How to convert a youtube video url to the iframe embed code, using jQuery on page load?

I have a WYSIWYG textarea, and sometimes user's may enter a youtube url into the box. On the server side, there are html filters to prevent "harmful" code from being saved.
So instead, I'd like to just keep the server code as-is, and run a jQuery document ready event that searches a block of text for a youtube link, and converts it to the iframe embed code.
I'd imagine it would be regex based, but I'm absolutely horrid with regex's (at some point, I really need to sit down and study them).
Two types of youtube links:
http://www.youtube.com/watch?v=t-ZRX8984sc
or
http://youtu.be/t-ZRX8984sc
This regex will pick up the URLs and replace them with the embed markup (just an iframe according to what YouTube currently outputs).
str.replace(/(?:http:\/\/)?(?:www\.)?(?:youtube\.com|youtu\.be)\/(?:watch\?v=)?(.+)/g, '<iframe width="420" height="345" src="http://www.youtube.com/embed/$1" frameborder="0" allowfullscreen></iframe>');
jsFiddle.
However, this can mangle things such as event handlers attached with old school methods.
It is a bit more complicated, but the best way would be work with text nodes only.
That should look something like this...
$('body').contents().each(function() {
// Skip non text nodes.
if (this.nodeType !== 3) {
return true;
}
// Grab text
var matches = this.data.match(/(?:http:\/\/)?(?:www\.)?(?:youtube\.com|youtu\.be)\/(?:watch\?v=)?(.+)/g);
if (!matches) {
return true;
}
var iframe = $('<iframe width="420" height="345" frameborder="0" allowfullscreen />', {
src: 'http://www.youtube.com/embed/' + matches[1]
});
iframe.insertAfter(this);
$(this).remove();
});
Note that this inserts after the entire text node.
var yturl= /(?:https?:\/\/)?(?:www\.)?(?:youtube\.com|youtu\.be)\/(?:watch\?v=)?([\w\-]{10,12})(?:&feature=related)?(?:[\w\-]{0})?/g;
var ytplayer= '<iframe width="640" height="360" src="http://www.youtube.com/embed/$1" frameborder="0" allowfullscreen></iframe>';
str.replace(yturl, ytplayer);
Ensure proper operation at the organization of WYSIWYG editor

Detect Flash object click in JavaScript

Is there a way I can have JavaScript/jQuery know when a Flash object has been clicked (and still have Flash process the click)?
I tried putting a table on top of the object with position: fixed and a z-index and the object set to param name='wmode' value='transparent' so I could have my JavaScript detect which column was clicked using jQuery's click(), but the clicks were never intercepted by JavaScript (Chromium Linux).
Is there another way to accomplish this?
Thank you Marty Wallace and Darwin!
<div id='flash'>
<object>
<param name='wmode' value='transparent' />
<embed src='foo.swf' wmode=transparent allowfullscreen='true' allowscriptaccess='always'>
</embed>
</object>
</div>
<div id='output'></div>
<script type='text/javascript'>
$('#flash').mousedown(function (e){
$('#output').append('<br>X: ' + e.pageX + ' ; Y: ' + e.pageY);
});
</script>
After testing, the XY coordinates of any clicks on the Flash object will be accurately printed to the screen and mouse interaction with the Flash object will proceed as normal.
Now irrelevant:
Only if you have access to the flash source using ExternalInterface call. This is one of the reasons why flash for web is evil.

Categories