I'm using the iframe-resizer package to dynamically change the size of an iframe depending on content.
However, before even trying any dynamic resizing, I run into an issue with the basic iframe: it's always 300px in width. Whatever content I place inside the iframe, the width is always 300px. Will not move; overflow is hidden if I add something >300px and still takes up 300px if my content is smaller than that.
EDIT: To be clear, My problem is that I want to dynamically change the width of an iframe (cross-domain), but it always renders at 300px and will not change. I'm using the iframe-resizer package to successfully dynamically change the height, but that's nto working on the width.
In the parent site, I'm embedding the iframe as follows:
<script type="text/javascript"
src="https://cdn.jsdelivr.net/npm/iframe-resizer#4.2.11/js/iframeResizer.min.js">
</script>
<script type="text/javascript">
var i = new URLSearchParams(window.location.search).get("openWidget"); document.write('<iframe id="inlineFrameExample" title="Inline Frame Example" style="position: fixed; zIndex: 1000; bottom: 0; right: 0" frameBorder="0" scrolling="no" src="http://localhost:3001?openWidget=' + i + '"></iframe>');
window.iFrameResize({ log: true }, '#inlineFrameExample')
</script>
And the content in my for my framed site, I have the following elements and styling:
<div className="App" id="App2">
{openWidget && <div className="button">OK</div>}
{showMessage && <section>This is a message</section>}
<div>
<button className="button" onClick={() => setShowMessage(!showMessage)}>
Msg
</button>
<button className="button" onClick={() => setOpenWidget(!openWidget)}>
{openWidget ? "-" : "+"}
</button>
</div>
</div>
.App {
text-align: center;
float: right;
}
.container {
display: flex;
justify-content: flex-end;
float: right;
}
section {
background-color: mediumseagreen;
color: white;
width: 500px;
}
.button {
width: 100px;
height: 100px;
background-color: mediumseagreen;
color: white;
text-align: center;
float: right;
}
Note that there's nothing in there about width being 300px. There are other widths, but the iframe seems to ignore them and always set itself to 300px.
I also made two code sandboxes, and embedded one site in the other via an iframe. Unfortunately the iframe is hidden for some reason, but if you inspect and look for the iFrame with id="inlineFrameExample" (and not code sandbox's button iframe) you'll see it's 300px wide: https://exzts.csb.app/
The code for the parent site is here: https://codesandbox.io/s/eloquent-flower-exzts?file=/index.html
The code for the framed site is here: https://codesandbox.io/s/iframe-test-ss8fs
UPDATE: I also removed all css styling from both the parent site and the framed site. Still always stuck at 300px. I also viewed the CSS specs which says default will be default set to 300px under certain conditions, but I cannot figure out how to dissatisfy those conditions so that the 300px rule doesn't apply.
I want the iframe to resize based on width. The current set up works perfectly on height, and I understand there's something in the default specs for iframes that sets them to 300px if x conditions are met: w3.org/TR/CSS2/visudet.html#inline-replaced-width What I need is whatever styling/setting/attribute will disable this, so the width will act in the same way as the height (i.e. completely dynamic).
The iframe-resizer doesn't resize iframe width by default. You have to explicitly specify it using sizeWidth setting.
window.iFrameResize({
log: false,
sizeWidth: true,
checkOrigin: false,
widthCalculationMethod: "rightMostElement",
heightCalculationMethod: "lowestElement"
}, "#myFrame");
body { background-color: wheat;}
iframe { border: 3px dashed green; }
span { font-size: 1.5rem;}
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/iframe-resizer#4.2.11/js/iframeResizer.min.js"></script>
<div>Following iframe grows automatically!</div>
<iframe id="myFrame" scrolling="no" src="https://mvyom.csb.app/"></iframe>
<span>😵😜🤪</span>
The iframe content is animated so it affects iframe's width and height according to the specified width and height calculation methods. And the iframe-resizer updates dimensions on every animations start and end event.
Also, the iframe source is from codesandbox and the parent document is this StackOverflow answer page, so we need to set checkOrigin: false as well.
Note: Had to set log: false because the animations are happening very fast creating ton of logs in console.
You can provide your own size calculations form inside the iframe.ref:
<script>
window.iFrameResizer = {
widthCalculationMethod: function () {
return document.querySelector(".one").clientWidth;
}
};
</script>
In following demo the iframe resizes exactly to the width of green box.
window.iFrameResize({
log: false,
sizeWidth: true,
checkOrigin: false,
widthCalculationMethod: "rightMostElement",
heightCalculationMethod: "lowestElement"
}, "#myFrame");
body { background-color: wheat;}
iframe { border: 3px dashed green; }
span { font-size: 1.5rem;}
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/iframe-resizer#4.2.11/js/iframeResizer.min.js"></script>
<div>Following iframe grows automatically!</div>
<iframe id="myFrame" scrolling="no" src="https://mvyom.csb.app/custom.html"></iframe>
<span>😵😜🤪</span>
Refer implementation of custom.html for better understanding. You can implement similar method for heightCalculationMethod.
Not sure if I understand the question. I think you've made an App and a page. On the page you want to use an iframe to show your App and the iframe should be scaled by default to the size of the app. Did I get that right?
I think JavaScript might by your solution. Get the content from the iframe, check in the content for a class App en that's the width you want to use for your iframe.
const iframe = document.querySelector("#inlineFrameExample");
const iWindow = iframe.contentWindow;
const iDocument = iWindow.document;
const iElement = iDocument.querySelector(".App");
iframe.style.width = iElement.style.width;
A problem with this script is that it can only be executed after the content from the iframe was loaded. So make sure you wait for that with a timer,delay, promise, or something. If you don't want to show the resizing to your visitors make sure the iframe has visibilty: hidden and add visibilty: visible of the iframe to the end of the script above.
#crevulus, the inner content of iframe has no impact on the dimensions of it's parent iframe by design
Also, as far as I remember, 300x150px is the common default width and height applied by browsers to any «iframe» element faced in html code on parsing incoming html and building the DOM stages, when the dimentions have been not predefined explicitely
The thing is a browser requires the dimentions of any visible element (i.e. any element that takes space in page layout - for simplicity, let's say any element except those where «display» property has been set to «none») either to be strictly predeclared with «width» and «height» properties (via element attributes with the same names, via internal / external css rule or css rule applied to element directly thru «style» attribute - the way doesn't matter) or to be calculable thru initial (default) values defined in html / css standards (again, for simplicity, if «div» element has no dimentions set, but all the neighbours do, its width will be calculated by browser as all available horizontal space between the left and right neighbours of the element, i.e. the «div» will always have initial width, defined by standard, which equals 100%; similary, the height of this «div» will be calculated as sum of heights of all its internal elements) - the dimentions are strictly required because w/o concrete values for every visible element on page a browser won't be able to render the page content for the current viewport correctly
So, when a browser parses incoming html code and faces «iframe» elements with no predefined dimentions (via attributes, css et cetera), to allocate the space for the element in page layout and thus to be able to move on to parse / render the whole page, a browser assumes the dimentions of the «iframe» as common defaults, which, as I mentioned above, equals square figure 300x150px («recumbent skyscraper»)
To override this behaviour, you should predeclare in any convenient way initial values, which will be suitable for your case
<iframe id="frame1" width="100%" height="250px" />
or
<style>
#frame1 {
width: 100%;
height: 250px;
}
</style>
<iframe id="frame1" />
et cetera, and then, when a page is rendered, if needed, use JavaScript to tune the dimensions of this iframe accoring to the width and height of its content (or any other condition on your choice), like
var frame1 = document.getElementById('frame1')
var width1 = parseFloat(frame1.style.getPropertyValue('width')) | 0
var height1 = parseFloat(frame1.style.getPropertyValue('height')) | 0
/*
* some stuff to define the conditions for iframe dimentions tuning and
* to calculate new width and height and to assing calculated values
* to width1 and height1 variables respectively
*/
frame1.style.setProperty('width', width1 + 'px')
frame1.style.setProperty('height', height1 + 'px')
As a postscript I'd like to note the above is the working concept, 'cause a few month ago I've designed and developed the close scheme to force the iframe of TinyMCE editor, built in Magento 1.9.x admin backend, to keep editor's width always equal to the width of CMS page on site's frontend and to expand / shrink editor's height dynamically accoring to the height of CMS page content being edited
The goal was to simplify and optimise the working process for the content department by making CMS pages in Magento admin area always look in TinyMCE editor exactly the same as on site's frontend
Unfortunately, the whole 1st gen of Magento, up to the last 1.9.4.5 release, is supplied with unspeakable outdated release of TinyMCE editor - 3rd gen of TinyMCE, published in early 2014 even before html5 officially arrived, in comparison even with it's own current 5th gen (which, in turn, frankly, is much inferior to alternative modern lightweight apps of WYSIWYG class) for 2022 feels like the Stone Age, a clumsy craft developed with stone axe by cave dwellers, both in terms of stability and functionality
In other words, that TinyMCE is missing the lion's share of useful builtin APIs / plugings, including the modern one to maintain the editor's dimentions in nominally simplified way, so the only way to achieve the goal I've researched has been to utilize onInit and onChange events provided by TinyMCE3, and to maintain the whole routine with custom JavaScript handlers over the editor, applying the dimentions directly to iframes on the parent level in Magento admin page code, which Magento core utilizes as containers for TinyMCE3 instances
Anyway, the experiment has been successful, so please feel free to ask any additional practical questions or to request some tech details on routines
The good news
If the page loaded by the iframe is on the same domain as yours, then you can easily find out the initial state by defining an onload attribute to the iframe and then access the contentWindow of the iframe and do some measurements and then apply them on your main page. But, as you said, the content of the iframe is from another origin. Bad luck, read on.
Some hope
Well, we know that you cannot directly access the content of the iframe. But, the content of the iframe may let you know when certain events happen. If the content inside the iframe does send messages, then you can addEventListener for message type events and specify the origin to be the site you are using inside the iframe. More info here: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
So, the site inside the iframe does some messaging? Maybe yes. But probably not. If it does not message you at the time of events of interest, then read on.
The bad news
Modern browsers do not allow you to directly run Javascript at other origins due to security reasons. One obvious example for this is that cookies can be read for a page and you absolutely do not want some third-party sites to mess with your cookies while you are doing a banking transactions or something of the like.
Some glimmer of hope
You may be able to somehow determine the current state of the iframes content. For example you may have access to API functions or something of the like that you can ask about your status. If those are leaking direct information about your situation inside the iframe (was the button clicked already, for instance?), then you may be able to poll such a source and see whenever a size changing event happens and if so your code could adapt your view accordingly. This way you would use another source of information to find out what is happening inside the iframe.
Sad but true
In general, the answer to your main question is NO. The explanation is that it is not allowed due to security reasons.
You may have some workarounds in your specific situation that may work out for you, but such workarounds are rarely available, most websites are working without providing supports for other websites that would like to use them in iframes. If the workarounds are not available for you, then you may want to reach out to the owner of the website shown in your iframe and see whether he/she is okay with providing support for this. Otherwise you will have to accept that the situation is beyond repair. Is it? If you are not satisfied yet, read on.
Desperation
If you really, really need to resolve this, then here's what you can do:
create a page in the same domain as your main page
from the browser's point of view both your main page and the page inside the iframe are using the very same domain, so they can reach each-other via Javascript
this new page will request the site to be shown in the iframe where the page of the other domain was shown previously (you don't create a further nested iframe, you just change its src)
and it will display it
but you add a little bit of Javascript, doing some measurements
and of course you adjust resource URLs accordingly, changing all relative URLs into absolute URLs
This might work, but it's very cumbersome and you will always need to adjust the given page whenever the site you are to use changes.
I'd like to display a thumbnail in a popover when I hover over text (a camera emoji) in our Django Admin view. The code I have works, but displays the image inline, which disrupts the rest of the layout of the site
I'm by no means a Django expert, so there might be something easy I'm missing. I'm totally open to using other libraries to help if that's the best path forward, but am not sure of how to appropriately load them in to django admin. I'm also open to pure js/css solutions - whatever works best!
Here's the code that I have
def image_column(self, obj):
format_html(foo + " " + \
'''<a href="{}"" target="_blank"
style="font-size: 18pt"
onmouseover="document.getElementById('{}_img').style.display='block';"
onmouseout="document.getElementById('{}_img').style.display='none';">📷
<img id="{}_img" style="display:none" src="{}" />'''.format(img_url, img_id, img_id, img_id, img_url)
I'd love any thoughts or suggestions on the best way to make it 'popover' instead of display inline. Thank you!!
EDIT:
Things are working now, with the exception of the camera emoji displaying over the pop over. The image in the background is a map (which should be on top). The camera image is from the row beneath it
That might only be an issue to do with the position property of the image, if it is position: relative, then it will fix itself among the other elements, you have to set it to position: absolute and from here you should give it top and left, for example: top: 0px; left: 0px; relative to the parent element which I guess is the <a> element ... And you should also apply position: relative to the parent element: which again I think is <a> or whichever parent element is to the <img> element
I have written some jsp/ajax pages and they work as expended.
I have a need, when particular link is clicked, to dim the page with exception of particular
<div id="showAllRooms"> <div>
area.(put the page in the "shadows" except of one div)
I am perry geen in JavaScript; could you advise what would be the best approach to this task?
Thank you.
Create a layer (div) that is as large as the body (position:absolute, all corners to postion 0, no padding, no margin)
keep it hidden (display:none)
give it a darker backgroundcolor
give it a higher z-index property
[otionally] give it an opacity value (opacity:0.5)
give the div you want to show a higher z-index than the created div
show the created layer (display:block)
Or use one of the many frameworks for it, like jquery lightbox
Good luck!
If I understand what you need. You need put the page in the "shadows" except of one div.
It can be done easily with jQuery ui and it's Model widget.
preview
Im looking for a way to change the background image of a div using jQuery BUT only amending it, not totally changing it.
Let me explain.
Im using http://jqueryui.com/demos/sortable/#portlets to show some div's that open and close. Now when you click the portlet header it opens and closes the content below.
Inside the portlet header i have a child div which shows an arrow (either up or down) depending on the current state of the content. I need a way of changing the background image on this child div by adding on "-visible" onto the end of the url for the background image.
I wouldnt even know where to start with doing this, but i have added some code below for you to look at.
http://jsfiddle.net/45jZU/
From the fiddle there, i need to alter the background image of the portlet-arrow div inside portlet header. I can not simply change the background image all together, but i have simplified it down to post on here.
I hope this isnt too narrow to not be of use to anyone else on stackoverflow.
Thanks
Maybe I'm missing something here, but can't you use the .css attribute modifier for the selected jQuery object? Something like:
var current_background = $("#my-div").css("background-image");
$("#my-div").css("background-image", current_background + "-visible");
If you're looking to modify the class names themselves, you can try mess around with the .toggleClass(), .hasClass(), .addClass() and .removeClass() methods in jQuery.
I hope this helps, but let me know if I've missed the mark here completely!
I would personnaly go for using css classes to change the background image. If you decide to change the image afterwards, you won't have to alter your javascript. It is a better solution to use javascript to code the behavior of the widget, not the visual aspect.
So you have the following css:
.portlet-header {
background-image: url(<an image>);
}
.portlet-header.collapsed {
background-image: url(<an other one>);
}
Add this line to your javascript to toggle the collapsed class:
$(".portlet-header").click(function() {
...
$(this).parent().toggleClass('collapsed');
});
If you widgets starts collapsed, initially add the class.
DEMO
I have a small popup window with dynamic contents. Nothing too complex. It has just a table with some text in it.
How do I find the height and the width of a window so that its content will show entirely?
The problem with using arbitrary, static values for the window's dimension is that it can be way off depending on the browser's font settings.
If this is not possible, what are the common practices?
Thanks.
Copy the HTML contents you want to put in the popup into a div that's positioned off the page, measure it, then remove the div. I don't know dojo, sorry, but this is a way to do it in jQuery:
var measuringDiv = $('<div class="sameAsPopupContainer" style="position:absolute; left:9999px; top:0px"></div>');
$('body').append(measuringDiv);
measuringDiv.html(theHtmlForTheTable);
heightOfContent = measuringDiv.width();
widthOfContent = measuringDiv.height();
measuringDiv.remove();
I assume dojo has similar methods. It's important that the off-page div you're creating maintains the same style rules as the popup container, which can be a little tricky.