HTML5 <video> width and height - html

I'm working to get a video on my webpage with the video tag.
I'm using FlareVideo to create my video tag. I can get the video to work on every browser that I need (IE 7/8/9, Firefox, Chrome, Safari).
The thing is, when I set the width and heigt, it looks like Safari and Chrome do not care at all and just put the right width, but a way too high height.
Also, with IE 7 and 8, the flash player used when HTML5 video is not supported by the browser is too small.
Hope somebody can help
Thanks
EDIT: added code
The HTML code
<div id="flarevideo" class="video-player" style="display:none;"></div>
The javascript code
function vidSwap(vidURL, awidth, aheight) {
var pwidth = 720;
var pheight = 406;
$("div.video-player").show();
fv = $("#flarevideo").flareVideo({
flashSrc: window.pathToFlashVideo,
width: pwidth,
height: pheight,
autobuffer: false,
preload: false
});
fv.load([
{
src: '[server address]' + vidURL +'.mp4',
type: 'video/mp4'
},
{
src: '{server address]' + vidURL + '.ogv',
type: 'video/ogg; codecs="theora, vorbis"'
}
]);
}
Note that the javascript is a bit different that what it should be (width and heigth here are hardcoded instead of using the two parameters of my function).
Also, the format of vidUrl is "/[name fo the video without extension"]
And, window.pathToFlashVideo is the path for the flash fallback, defined on my html page

Seems like the problem was coming from the div's CSS that contained the video. I removed the height:100% and now it's working fine.
Hope this helps anybody else with the same problem

Related

Embedding an iframe when iframe height is variable

I have an iframe that has a variable height which is not known in advance.
Currently, if the section in which the iframe loads is too small, the iframe loads with internal scroll bars. If the iframe happens to be a shorter iframe, there is empty space below the iframe before the footer begins.
Is there a solution available to this type of problem?
Well, adding simple JS code to get the iframe content height and setting the container height will do, as suggested by #relief.melone.
Other simple solution that can be of help, as an alternative :
https://github.com/davidjbradshaw/iframe-resizer
In reference to my comment. The first thing you have to solve is your cross origins problem. Most browsers will block requests to other websites if the response does not include the current host in their cross origins allow header. So in your case the header from your request to the iframe contents needs to include the header
Access-Control-Allow-Origin: http://159.89.229.184
and
Access-Control-Allow-Mehtods: GET
Also see https://de.wikipedia.org/wiki/Cross-Origin_Resource_Sharing for more info on this.
Now to the actual solution.
You need to determine the height of your iframes contents and then set the height accordingly. You can do this by adding a javascript function. In your head section add
<script>
const setHeight = (frame) => {
frame.style.height = `${frame.contentWindow.document.body.scrollHeight}px`
}
</script>
and your iframe needs to include the onload event
<iframe ... scrolling="no" onload="setHeight(this)" />
This should solve your problem. But as I mentioned just if you allow the cross origin access. Otherwise you access to the document of frame.contentWindow will get rejected with an error like
VM747:1 Uncaught DOMException: Blocked a frame with origin "http://159.89.229.184" from accessing a cross-origin frame.
I also made an example on glitch to demonstrate how it works (Click on Show to see it in action)
https://glitch.com/edit/#!/iframe-varialbe-height
I had s situation where the height of the iFrame content changed dynamically, and I told the parent frame (containing the iFrame) to change it's height accordingly using postMessage: like this
Parent window:
<section class="module">
<div class="row">
<!-- Content column start -->
<div class="col-sm-12" id="web-version-container">
<iframe id="web-version-frame" src="index.html" allowfullscreen=false frameborder="0" style="width:100%; height:100%;min-height:800px;">
</iframe>
</div>
</div> <!-- .row -->
</section>
<script>
window.addEventListener('message', function(event) {
// IMPORTANT: Check the origin of the data!
if (~event.origin.indexOf('https://yourdomain.com')) {
// The data has been sent from your site
if (event.data.messageName) {
switch (event.data.messageName) {
case "documentHeight":
if (event.data.messageValue && parseInt(event.data.messageValue) > 500);
var newHeight = parseInt(event.data.messageValue) + 50;
$("#web-version-frame").css("height",newHeight.toString() + "px");
break;
}
}
// The data sent with postMessage is stored in event.data
} else {
// The data hasn't been sent from your site!
// Be careful! Do not use it.
return;
}
});
</script>
Child window:
if (window.parent) {
window.parent.postMessage(
{
messageName: "documentHeight",
messageValue: $(".content-active").height()
},
"*"
);
}
https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
In the iframe that you have added in second example has the css property min-height as 1600px. Use a percentage for min-height or height to fix the issue. Added min-height: 275vh; and it fixed the issue.
.job-detail-iframe iframe{
width: 100%;
min-height: 275vh;
}
Check this out also as a reference.

html2canvas: img tag with data src not being rendered in IE

Using html2canvas with IE-11 is not capturing img tags that have data srcs, but it works in Chrome.
html2canvas($target, {
...
allowTaint: false,
onrendered: function(canvas) {
...
}
});
Part of the img tag
<img src="data:image/svg+xml;base64,...">
This works fine in Chrome but not in IE:
http://jsfiddle.net/difftech/f4dtd5f9/1/
If I change the allowTaint to true, it works in IE. Why? Chrome accepts it either way. I need the allowTaint to be false so other content gets rendered from my page.
Is there a way to allow some content to use allowTaint or another way to handle this?

load image asynchronous

If I have an image tag like the following:
<img src="myimage.jpg" />
and if I add "async" to it:
<img async src="myimage.jpg" />
will the image load asynchronous?
The way to async load (lazy load) the content is to not set the 'src' attribute and then execute a script that loads the images once DOM-ready is launched.
<img data-lazysrc='http://www.amazingjokes.com/images/20140902-amazingjokes-title.png'/>
and with jQuery (or possible with plain JavaScript too) use below code (as suggested here):
<script>
function ReLoadImages(){
$('img[data-lazysrc]').each( function(){
//* set the img src from data-src
$( this ).attr( 'src', $( this ).attr( 'data-lazysrc' ) );
}
);
}
document.addEventListener('readystatechange', event => {
if (event.target.readyState === "interactive") { //or at "complete" if you want it to execute in the most last state of window.
ReLoadImages();
}
});
</script>
var img = new Image(),
url = "myimg.jpg",
container = document.getElementById("holder-div");
img.onload = function () { container.appendChild(img); };
img.src = url;
This would start loading an image as soon as you request it in-script, and whenever the image was done loading, it would grab and add the image to it.
There are lots of other ways of doing this...
This is just a dead-simple example of async loading of a single image.
But the moral is this:
For async loading to work, either load it in JavaScript and use the onload, or include the image tag on the page, without the src attribute (specify the width and height in HTML), and go back at some point, in JS, and set the image URL.
The modern way to do this is with the loading attribute for images and iframes.
Attribute: loading=lazy
This will defer loading of the content until the element reaches a calculated distance from the viewport (that just means, it's got quite likely that the user will scroll it into view).
<img src="defer.png" loading="lazy" alt="An Awesome Image" width="500" height="400">
Setting the attribute to lazy invokes the new behaviour.
This is already in Chromium since v76, but might not hit non-Chromium browsers until it goes through the usual specification shennanigans.
If you are going to defer loading using a script, it would be worth writing the image with the lazy attribute and polyfilling the behavior as opposed to working off of a class name, etc. That way, you can allow the native version to take over as it becomes available.
Forced Eager Loading
Automatic lazy loading may become a feature of lightweight browsing, in which case, you may want to do the inverse and force an image to load. You can use the same loading attribute with a value of eager to ask the browser to grab the image even if it might otherwise choose not to.
<img src="defer.png" loading="eager" alt="An Awesome Image" width="500" height="400">
Further reading
View the pull request for the WHATWG spec
Fallback JavaScript with notes about perhaps not using fallbacks
An alternate way to async load an image is by using Promise in javascript, which serves the purpose of doing things asynchronously.
function asyncImageLoader(url){
return new Promise( (resolve, reject) => {
var image = new Image()
image.src = url
image.onload = () => resolve(image)
image.onerror = () => reject(new Error('could not load image'))
})
}
// then use it like this
var image = asyncImageLoader(url)
image.then( res => {
console.log(res)
})
<img async src="myimage.jpg" />
The image tag doesnt supports any async attribute.
http://www.w3.org/TR/html5/embedded-content-0.html#the-img-element
While several other answers highlight ways to fetch images asynchronously, it may also be helpful to know that the <img /> tag supports an attribute that serves as a hint to the browser that may result in images being be decoded asynchronously. It doesn't appear to be supported by Internet Explorer.
<img src="myimage.jpg" decoding="async"/>
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Img#attr-decoding
https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/decoding
https://github.com/whatwg/html/issues/1920
If you're using jQuery, I did something simple, yet effective, like this:
HTML
<div data-lazy-load-image="/Images/image-name.png" data-image-classname="pop-in"></div>
JavaScript
$(function () {
$("[data-lazy-load-image]").each(function (index, element) {
var img = new Image();
img.src = $(element).data("lazy-load-image");
if (typeof $(element).data("image-classname" !== "undefined"))
img.className = $(element).data("image-classname");
$(element).append(img);
});
});
CSS
#-webkit-keyframes pop-in {
0% { opacity: 0; -webkit-transform: scale(0.5); }
100% { opacity: 1; -webkit-transform: scale(1); }
}
#-moz-keyframes pop-in {
0% { opacity: 0; -moz-transform: scale(0.5); }
100% { opacity: 1; -moz-transform: scale(1); }
}
#keyframes pop-in {
0% { opacity: 0; transform: scale(0.5); }
100% { opacity: 1; transform: scale(1); }
}
You could extend this to include additional optional attributes for each image, but you get the idea.
This will wait until the DOM is ready, then dynamically (async) load the images into the element that you mark with the data-lazy-load-image attribute. I included the CSS to make the images "pop in" when they are loaded.
While #Norguard's example is quite simple and easy enought for an image or two, I have found echo.js pretty handy for lazy-loading, https://github.com/toddmotto/echo.
It does lazy-loading images with data-* attributes and comes with some neat other things too.
<img data-echo="img/photo.jpg">
<script src="dist/echo.js"></script>
<script>
echo.init();
</script>
I have used the following approach with jQuery.
First, don't use a "src" attribute in the image tag, but put your source into a different attribute, like this:
<img async-src="/mydirectory/myimage.jpg" />
Then, within the jQuery document-ready function, I use this code to copy the element's async-src to the element's actual src:
$("img[async-src]").each(function(index) {
$(this).attr("src", $(this).attr("async-src"));
});
Notes:
jQuery's .each function may process the tags in the sequence they are coded in the HTML/DOM, but image sizes and network issues may mean that images don't actually load sequentially. In other words, your third async-src image might visually appear onscreen before the first has finished loading.
If your page layout relies on the pixel dimensions of that image file — e.g. you're not defining the image's dimensions via tag attributes, CSS, or a parent element — then you may have to use a "src" attribute on the original file pointing to a blank white or clear GIF of the dimensions you want.
Finally, if you want to process some code after the async loading of the image — for example, to handle a fading effect or change a CSS tag relevant to the element — expand the jQuery like this:
$("img[async-src]").each(function(index) {
$(this).load(function() {
// code to run after loading
});
$(this).attr("src", $(this).attr("async-src"));
});
It might be too late of an answer but recently was facing the same issue and the "lighthouse" in the console suggested that I should follow what's mentioned here in the link:
enter link description here
Basically, I did the following as suggested and it works really well:
<script src="lazysizes.min.js" async></script>
<!-- Images End -->
</body>
You may download the lazysizes.min.js from https://raw.githubusercontent.com/aFarkas/lazysizes/gh-pages/lazysizes.min.js
and source it locally.
Then, add the class lazyload to images that should be lazy loaded. In addition, change the src attribute to data-src.
For example:
<img data-src="images/flower3.png" class="lazyload" alt="">
You may be wondering why it is necessary to change the src attribute to data-src. If this attribute is not changed, all the images will load immediately instead of being lazy-loaded. data-src is not an attribute that the browser recognizes, so when it encounters an image tag with this attribute, it doesn't load the image. In this case, that is a good thing, because it then allows the lazysizes script to decide when the image should be loaded, rather than the browser.
Visit the reference for better understanding.
Hopefully it'll be of help to someone :)
You can read more about lazyload attribute:
<img src="myimage.jpg" alt="some description" lazyload/> - with default values
or you can prioritize:
<img src="myimage.jpg" alt="some description" lazyload="1"/>
<img src="myimage.jpg" alt="some description" lazyload="2"/>

How to disable default controls on a full screen HTML5 video?

I have a video of a specified width and height, double clicking on which makes it go full screen using videoElement.webkitRequestFullScreen().
By default the video does not have any controls. But for some reason, on going full screen, the default controls pop up. Here is what I'm doing :
<video id="videoId" width="320" height="240" autoplay="autoplay" ondblclick="enterFullScreen('videoId')" src="Blah.mp4"></video>
And the enterFullScreen(...) function is defined as :
function enterFullScreen(elementId) {
var element = document.getElementById(elementId);
element.webkitRequestFullScreen();
element.removeAttribute("controls");
}
As you can see, I've already tried removing the controls in the function. But to no avail.
Could someone tell me how to prevent this auto insertion of default controls from happening?
This is possible to solve with CSS, as described here: HTML5 video does not hide controls in fullscreen mode in Chrome
video::-webkit-media-controls {
display:none !important;
}
Finally, I found a way around this.
As Alexander Farkas suggested, I wrapped the video in another div, and I set this parent div to go full screen, after which I set the height and width of the video to screen.height and screen.width respectively. And I restored the original properties of both the divs on exiting full screen.
Pseudo Code :
HTML :
<div id="videoContainer" style="position:absolute;background-color:black;">
<video id="videoId" style="height:240;width:320;" ondblclick="enterFullScreen('videoId')" src="movie.mp4"></video>
</div>
JavaScript :
function enterFullScreen(id) {
var element = document.getElementById(id);
element.parentNode.webkitRequestFullScreen();
element.style.height = screen.height;
element.style.width = screen.width;
}
document.addEventListener("webkitfullscreenchange", function () {
if(!document.webkitIsFullScreen) {
// Restore CSS properties here which in this case is as follows :
var element = document.getElementById('videoId');
element.style.height=240;
element.style.width=320;
}
}, false);
If a video goes fullscreen, the user agent should show the controls, also if controls attribute is absent.
Newer user agents also support fullscreen API on any element. Therefore you can try the following:
element.parentNode.webkitRequestFullScreen();
You can find the id of div containing the controls and disable it using javascript.
e.g if id of div that is containing the controls is "controldiv"
then in your function you can write
var ctrls = document.getElementById("controldiv");
ctrls.disabled="true";
Normally the following should work:
var videoPlayer = document.getElementById('videoId');
videoPlayer.controls = false;
But I'm not sure if jumping into full screen mode will override it.
A CSS only solution:
video::-webkit-media-controls-fullscreen-button {
pointer-events: none;
opacity: .5;
}

Having custom controls still apply when go fullscreen on a HTML5 video?

I've made custom controls for my HTML5 video but I don't know how to have that CSS still apply when I go fullscreen.
Here's the [website] I've based my controls on.
On this site, you'll notice that when you click the fullscreen button the custom controls get lost and the video reverts to the default <video> controls.
Does anyone know how to have these custom controls styling/CSS still apply when you go fullscreen?
i answered my own question, the key is that the custom controls are inside the <div> that includes the video that you want to take full screen. In my code below, this <div> is called "videoContainer".
Here's the link I used to figure this out.
http://developer.apple.com/library/safari/#documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/ControllingMediaWithJavaScript/ControllingMediaWithJavaScript.html
here's the JS code for both entering and exiting fullscreen mode in webkit and mozilla browsers:
var $video=$('video');
//fullscreen button clicked
$('#fullscreenBtn').on('click', function() {
$(this).toggleClass('enterFullscreenBtn');
if($.isFunction($video.get(0).webkitEnterFullscreen)) {
if($(this).hasClass("enterFullscreenBtn"))
document.getElementById('videoContainer').webkitRequestFullScreen();
else
document.webkitCancelFullScreen();
}
else if ($.isFunction($video.get(0).mozRequestFullScreen)) {
if($(this).hasClass("enterFullscreenBtn"))
document.getElementById('videoContainer').mozRequestFullScreen();
else
document.mozCancelFullScreen();
}
else {
alert('Your browsers doesn\'t support fullscreen');
}
});
and here's the HTML:
<div id="videoContainer">
<video>...<source></source>
</video>
<div> custom controls
<button>play/pause</button>
<button id="fullscreenBtn" class="enterFullscreenBtn">fullscreen</button>
</div>
</div>
Show custom controller
#customController{
-------------------;
-------------------;
-------------------;
z-index: 2147483647;
}
Hide native controller
video::-webkit-media-controls {
display:none !important;
}
video::-webkit-media-controls-enclosure {
display:none !important;
}
Here's a solution that uses the modern Fullscreen API, which is supported on all major browsers today.
// `container` is the element containing the video and your custom controls
const toggleFullscreen = () => {
if(document.fullscreenElement) {
document.exitFullscreen();
} else {
container.requestFullscreen();
}
};