How can I use document.createElement(“iframe”) and place that iframe within the div I’m running the js in when it has no id/class etc?
eg.
<div>
<script>
var newiframe = document.createElement("iframe")
....
</script>
</div>
How can I use document.createElement(“iframe”) and place that iframe within the div I’m running the js in when it has no id/class etc?
eg.
<div>
<script>
var newiframe = document.createElement("iframe")
....
</script>
</div>
Stating the obvious, but you would need another way to target it, maybe relative to a parent with an id or class.
As an example something like this perhaps…
<body>
<div></div>
<div id='section1'> <!-- targeting section1 as parent -->
<div></div> <!-- [0] first div -->
<div><!-- [1] second div -->
<script>
const iframe = document.createElement('iframe')
const thisDiv = document.querySelectorAll('#section1 div')[1] // [second div inside section]
const script = thisDiv.querySelector('script') // get the child element script
// replace this script with the iframe
thisDiv.replaceChild(iframe, script)
</script>
</div>
</div>
</body>
Daft question, but is there a reason the script has to be inside a particular div?
The problem is I have no idea about divs outside the unnamed div that I’m wanting to add this iframe into. It has to be inside this div as it’s containing the iframe.
Can you give the script a unique id?
<body>
<div></div>
<div id='section1'>
<div></div>
<div>
<script data-id='appendIframe'>
const iframe = document.createElement('iframe')
const script = document.querySelector("script[data-id='appendIframe']")
// replace this script with the iframe
script.parentNode.replaceChild(iframe, script)
</script>
</div>
</div>
</body>
Unfortunately not as this code is out of my hands. These are embeddable on remote webpages. I just have access to the div around the iframe I’m inserting.
Ok, learning exercise here
I’m not sure how reliable this is. Other contributors may have a better idea
<body>
<div></div>
<div>
<script>
// empty script here
</script>
<div></div>
<div id='target-div'> <!-- just so I can see when I inspect element -->
<script>
const iframe = document.createElement('iframe')
// get all scripts to this point of the rendered page
const scripts = document.querySelectorAll('script')
// pick the last one
const thisScript = scripts[scripts.length-1]
// replace this script with the iframe
thisScript.parentNode.replaceChild(iframe, thisScript)
</script>
</div>
</div>
<script>
// Another script here
</script>
</body>
FWIW, it won’t work if the script is getting loaded asynchronously… there’s also document.currentScript
, which works for async
scripts as well but not for old IE. ^^
That works thanks. In terms of getting it to work if called async, is there a way to detect and serve alternative code to suit? Or detect old IE instead?
Also, do you know how to set the no borders and scollbars attributes on an iframe? This doesn’t work: iframe.setAttribute(‘style.border’, 0);
EDIT: Fixed no borders with iframe.frameBorder = 0 and no scroll with iframe.scrolling =“no”
Iframes aren’t something I have used in about 20 years, so best someone else helps you there.
Not sure how to solve the async vs no async issue.
One option for isolating IE is to use <script src='iescript.js' nomodule>
and for modern browsers <script src='script.js' type='module'>
. MDN link
Or you might simply check if document.currentScript
is actually defined; if it’s not, do something else:
if (!document.currentScript) {
// Do something else
}
BTW note that when using type="module"
scripts, document.currentScript
won’t be defined either; in this case you have to use the import.meta
to find the current script:
const currentScript = [...document.scripts]
.find(script => script.src === import.meta.url)
… which again will only work if the code was not actually imported as a module. <:o)
JFTR this should have been:
iframe.setAttribute('style', 'border: 0')
Or better, since this will keep other existing other styles:
iframe.style.border = '0'
Thanks. iframe.frameBorder = 0 seems to work, is that OK to use?
In terms of async vs sync, is this OK:
if (document.currentScript.async) {
var thisScript = document.currentScript;
} else {
var scripts = document.querySelectorAll('script');
var thisScript = scripts[scripts.length-1];
}
Well, it’s actually deprecated and the MDN recommends to use border
styles instead.
This is a misunderstanding; document.currentScript
will work as expected for async
scripts – it will just not work for IE at all. So you could use the else
code as an IE fallback, but then again you might rather do nothing or display an error message if your script is possibly async
.
This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.