Reputation: 800
I try to add an button via Tampermonkey to websites. That button should only appear in the outer body and not in iframes.
So, for example, this is before the Tampermokey runs...
<html>
<head>...</head>
<body>
...
...
<iframe src="https://xyz.abc", id="myID">
<html>
<head>...</head>
<body>
...
...
</body>
</html>
</iframe>
</body>
</html
I try to add an button like this:
var zNode = document.createElement('div');
zNode.innerHTML = '<button id="myButton" type="button">' +
'submit</button>';
zNode.setAttribute('id', 'myContainer');
var first = document.getElementsByTagName('body')[0];
first.appendChild(zNode);
// add an event handler, etc...
But this piece of code is not ignoring the body tag in the iframe and my button appears in both body tags.
<html>
<head>...</head>
<body>
<div id="myContainer"><button id="myButton"
type="button">Clear Session</button></div>
...
<iframe src="https://xyz.abc", id="myID">
<html>
<head>...</head>
<body>
<div id="myContainer"><button id="myButton"
type="button">Clear Session</button></div>
...
</body>
</html>
</iframe>
</body>
</html
What I would like to archive is to add the button only in the outer body (not as part of the iFrame). Please notice, I cannot modify the webpage, I can only try to adapt my code by Tampermonkey... Are you able to support me here please? Thanks
Upvotes: 1
Views: 1097
Reputation: 43910
Update 2
If the pages are dynamically generated, varies in content, and/or what and how things are loaded cannot be controlled, etc., try adding the button with .insertAdjacentHTML()
method. Also adding elements to body
isn't the best choice of locations because it's at the top of the hierarchy of HTML and there should be only few elements there.
const win = document.querySelector('iframe');
win.insertAdjacentHTML('beforebegin', `<div class="box">
<button class='clr'>
Clear Session
</button>
</div>`);
<iframe srcdoc="<html><head></head><body>There's no button in this iFrame.</body></html>" width='200' height='100' frameborder='2'></iframe>
Update 1
.class
instead of #id
.#id
. #id
s must be unique on the page, meaning it is invalid HTML if there are more than one element assigned as #myContainer
for example. Under normal circumstances should there be more than one #id
, methods such as .querySelector()
or .getElementById()
will find the first element and ignore any other duplicates because it's assumed that there is only one #myContainer
.In the OP code there's a unusual layout where there is two #myContainer
s and they are in separate documents which inadvertantly makes them both behave as valid. But the OP code is invalid because iFrames syntax is very wrong:
OP Invalid HTML (iFrame is an just an inline element)
<iframe><html><body>...</body></html></iframe>
Valid HTML (iFrame src
attribute is a url of the page)
<iframe src='https://sub.dom.com/path/to/page.html'></iframe>
Valid HTML (iFrame source is htmlString
of srcdoc
attribute)
<iframe srcdoc='<html><body>...</body></html>'></iframe>
If the iFrame was valid, then everything within the iFrame couldn't be affected unless:
The content exists on the same host
Use of the .contentDocument
property
Op code has an invalid iFrame which is just an inline element with no special features.
.querySelector()
.getElementsByTagName('body')[0]
actually collects all body
elements and the bracket notation with the value of zero: [0]
indicates the first body
in the document, thus both body
s are affected.Check the HTML with F12 and make sure that zNode
(assuming zNode
is an element) is appended to the iframe. From what little code posted, it looks as if you couldn't have added anything to an iframe because there is an extra property needed:
document.querySelector('iframe').contentDocument;
In the example below the following is used to reference the body of parent document:
document.body
const mark = document.createElement('mark');
mark.textContent = 'This is in body of parent document';
document.body.appendChild(mark);
<iframe srcdoc="<!DOCTYPE html><html><head></head><body><p>Inside iFrame</body></html>" style='display: block; width: 50vw; height: 25vh; border: 3px inset grey; margin: 10px auto'></iframe>
Upvotes: 2