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.
Related
Recently I added an iFrame using the following code I found online:
"<iframe id=“personio-iframe” style=“border: none;” src=“my website address is here” width=“100%” onload=“window.top.scrollTo(0,0);“> window.addEventListener(‘message’, function(e) { var iframe = document.querySelector(‘#personio-iframe’); var eventName = e.data[0]; var data = e.data[1]; switch(eventName) { case ‘setHeight’: iframe.style.height = data + ‘px’; window.scrollTo({ top: 0, behavior: ‘smooth’ }); break; } }, false);"
I noticed whenever I click on any part inside an iFrame the page scrolls up.
I can see the two lines in the code that mention scrolling up, but when I tried to delete them the frame doesn't show properly, it's displayed as a narrow bar on the page.
Can you please let me know how can I modify this code to successfully get rid of the scrolling up without damaging the iFrame itself?
Please try this line:
<iframe id="personio-iframe" style="border: none;" src="your website address is here" width="100%" height="600px">
This is optional for your css, with it the iframe will not go over 90% of screen height
#personio-iframe {max-height:90vh;}
I am making a directive to set the height of a div equal to the height of the browser if the height of the div is less than the height of the browser.
I have created the following directive:
(function() {
var directive = function ($log, $window) {
function evaluate(element) {
var height = element.prop("offsetHeight");
var pageHeight = $window.innerHeight;
if (height < pageHeight)
{
$log.info("element height is less than page height, changing element height.");
element.css("height", pageHeight);
}
}
return {
restrict: "A",
link: function (scope, element, attrs)
{
//call it one time on load to handle first display
evaluate(element);
$window.addEventListener("resize",
function() {
$log.info("Resize directive called: evaluating window size.");
//window size changed, check if we need to adjust the height
evaluate(element);
});
//add a watch to trigger when the inside of the div changes
scope.$watch(function() { return element[0].childNodes.length }, function(values) {
evaluate(element);
});
}
}
};
angular.module('bootstrapApp')
.directive('fullSize', ["$log", "$window", directive]);
})();
and it is used in the following way:
<body>
<fullsize-background-image-1></fullsize-background-image-1>
<navbar-1></navbar-1>
<div class="container-fluid">
<div class="row">
<left-sidebar-1></left-sidebar-1>
<right-sidebar-1></right-sidebar-1>
<div class="col-xs-12 main" id="main" full-size>
<div ng-view="" autoscroll="true"></div>
<footer-1></footer-1>
</div>
</div>
</div>
....
</body>
My problem is, on page load, thing was working perfectly (without the scope.$watch statement). However, when angular routed to a different page, that content replaced what is in the div#main element. Sometimes the height of the new page is greater than the height of the previous page, causing my hidden <left-sidebar-1> to show.
What I need to do is, on initial page load have my full-size directive evaluate what the height of main should be. Then, when the page changes, have it re-evaluate it and remove the property if the content is bigger.
thanks.
I have a Html page which has anchor tag, I Need to remove certain style applied already in html page for anchor tag while the html page is opened throw Iframe.
HTML Content as below:
<html>
<body>
<div>some content<a href="http://www.website.com" name="test1"/> some content </div>
</body>
</html>
I tried as below:
a[name^="test1"]:before{
content:"[prefix text]";
display:inline;
color:red;
}
a[name^="test1"]:after{
content:"suffix text";
display:inline;
color:green;
}
iframe a[name^="test1"]:before{
display:none;
}
iframe a[name^="test1"]:after{
display:none;
}
But inside "iframe" also these styles has been applying.
You have to first detect if your page is rendered inside an iframe and in that case apply an alternative CSS. It' can't be done with vanilla CSS then it has to be done with some JavaScript:
<script type="text/javascript">
function getTopWindow() {
try {
return window.top;
} catch {
// If we can't access window.top then browser is restricting
// us because of same origin policy.
return true;
}
}
function isRendererdInFrame() {
// If top window is null we may safely assume we're in iframe
return window.self !== getTopWindow();
}
function loadCss(location) {
if(document.createStyleSheet) {
document.createStyleSheet('http://server/stylesheet.css');
} else {
var styles = "#import url('" + location + "');";
var newSS=document.createElement('link');
newSS.rel='stylesheet';
newSS.href='data:text/css,'+escape(styles);
document.getElementsByTagName("head")[0].appendChild(newSS);
}
}
</script>
Code to load CSS from JavaScript is from How to load up CSS files using Javascript?.
With all that code you may simply write (even just after that inside <script> block):
var cssToLoad = isRendererdInFrame() ? "iframe.css" : "not-iframe.css";
loadCss("http://server/" + cssToLoad);
Of course same technique can be applied to patch CSS with iframe specific styles:
if (isRenderedInFrame())
loadCss("http://server/iframe-patch.css");
i dont know how to detect if page is opened in iframe or not, but there is one possible(not very nice) workaround, you can set iframe to width which is not commonly used by devices (example 463px) and then set media query for this resolution which apply when content is shown in this iframe. This is really nasty way since its not 100% and i would not recommending that.
I have a iframe inside a div. I want the size of iframe to be exactly the size of its parent div. I used following code to set the width and height of iframe.
<iframe src="./myPage.aspx" id="myIframe"
style="position: relative;
height: 100%;
width: 100%'
scrolling='no'
frameborder='0'">
But width of iframe is not same as div, also both horizontal and vertical scrollbar are displayed.
you have a lot of typos.
a correct markup should be like:
<iframe src="./myPage.aspx" id="myIframe" scrolling="no" frameborder="0"
style="position: relative; height: 100%; width: 100%;">
...
</iframe>
also, if this frame already has an ID, why don't you put this in CSS like this (from a separate stylesheet file):
#myIframe
{
position: relative;
height: 100%;
width: 100%;
}
and HTML
<iframe src="./myPage.aspx" id="myIframe" scrolling="no" frameborder="0" > ... </iframe>
mind that scrolling & frameborder are iframe attribute, not style attribute.
Since we are in the age of CSS3, you can do this by using viewport units. These units allow you to specify sizes in terms of percentages of the viewport width and viewport height. This is the user's viewport, also known as screen. However, in all major browsers I've tried it, if you put an iframe inside a div, which is inside another div and positioned relative, the viewport units are relative to this div. And since 100 viewport height units mean 100% height, you can do like this:
<div id="parent">
<div id="wrapper" style="position:relative">
<iframe style="position:absolute;top:0px;width:100%;height:100vh;" src="http://anydomain.com"></iframe>
</div>
</div>
I find this to be the best solution possible, since it is cross-domain, and displays exactly like you want it without any javascript or other complex stuff.
And most importantly, it works on all browsers, even mobile ones (tested on android and iphone)!
To set dynamic height -
We need to communicate with cross domain iFrames and parent
Then we can send scroll height/content height of iframe to parent window
1 For communication
I prefer - https://ternarylabs.github.io/porthole/
2 Implementation
To detect iframe height change - Uses https://marcj.github.io/css-element-queries/
<script src="https://raw.githubusercontent.com/marcj/css-element-queries/master/src/ResizeSensor.js"></script>
<script src="https://raw.githubusercontent.com/ternarylabs/porthole/master/src/porthole.min.js"></script>
For rest of the implementation refer gist -
https://gist.github.com/mohandere/a2e67971858ee2c3999d62e3843889a8
Parent window:
(function(){
'use-strict';
//This soultion we have used - https://ternarylabs.github.io/porthole/
// example -
var iFrameId: 'guestFrame',
window.onload = function(){
// Create a proxy window to send to and receive
// messages from the iFrame
var windowProxy = new Porthole.WindowProxy(
'http://other-domain.com/', iFrameId);
var $viewPort = $('#'+iFrameId);
// Register an event handler to receive messages;
windowProxy.addEventListener(function(messageEvent) {
if( messageEvent.data.height == $viewPort.height() ){
return;
}
$viewPort.height(messageEvent.data.height);
});
Porthole.WindowProxyDispatcher.start();
};
})();
iframe window:
(function(){
'use-strict';
/**
* Iframe to Parent window communication
* sample iframe- <iframe id="guestFrame" name="guestFrame" src="http://other-domain.com/">
* </iframe>
* Uses https://ternarylabs.github.io/porthole/
* Uses https://marcj.github.io/css-element-queries/
*/
window.onload = function(){
var proxy = window.proxy = new Porthole.WindowProxy('http://parent-domain.com/');
proxy.addEventListener(function(messageEvent) {
// handle event
});
//Height setup
var iframeHeight = 0;
var element = document.getElementsByTagName("BODY")[0];
new ResizeSensor(element, function() {
var scrollHeight = $('body').outerHeight();
if (iframeHeight === scrollHeight) return false;
iframeHeight = scrollHeight;
proxy.post({
height: scrollHeight,
});
});
Porthole.WindowProxyDispatcher.start();
};
})();
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;
}