Search code examples
javascripthtmliframegreasemonkey

Accessing document inside <iframe> using JS. "contentWindow.document" and "contentDocument" doesn't work


What I'm trying to do is to hide some elements(divs that contain ads) from video player using JavaScript (not jQuery). I use Greasemonkey.

Video player is embedded into the site by < iframe > :

<iframe src="//www.mp4upload.com/embed-f9ntae302eec.html" scrolling="no" allowfullscreen="" width="765" height="431" frameborder="0">

My script as of right now:

function remove_iframe_ads(){
  var video_player_window = document.getElementById("player-block");
  if(video_player_window == null) return;

  var iframes = video_player_window.getElementsByTagName('iframe');
  if(iframes == null || iframes.length == 0) return;

  console.log(iframes[0]);        // for debugging

  var iframe_document = iframes[0].contentDocument || iframes[0].contentWindow.document;
  console.log(iframe_document);
};

setInterval(remove_iframe_ads, 1000);

Through debugging I found out that console.log(iframe_document); doesn't get to run.
Actually var iframe_document isn't even created (code execution stops as var iframe_document).

It seems that I can't access the "document" inside an iframes[0].
Is var iframe_document = iframes[0].contentDocument || iframes[0].contentWindow.document; simply wrong or is the iframe being somewhat "protected" against local changes?

I followed this doc to write "crossbrowser" solution.


Have been looking through Google and StackOverflow, but I didn't find any answers on "How to get element inside an iframe in JS" apart from what I used here.


Output of console.log(iframes[0]); (unfolded):

iframe
​
accessKey: ""
​
accessKeyLabel: ""
​
align: ""
​
allowFullscreen: true
​
allowPaymentRequest: false
​
assignedSlot: null
​
attributes: NamedNodeMap(6) [ src="//www.mp4upload.com/embed-f9ntae302eec.html", scrolling="no", allowfullscreen="", … ]
​
baseURI: "https://shinden.pl/episode/45069-gate-jieitai-kanochi-nite-kaku-tatakaeri-2/view/137211#column-one-inner"
​
childElementCount: 0
​
childNodes: NodeList []
​
children: HTMLCollection { length: 0 }
​
classList: DOMTokenList []
​
className: ""
​
clientHeight: 431
​
clientLeft: 0
​
clientTop: 0
​
clientWidth: 765
​
contentEditable: "inherit"
​
contextMenu: null
​
dataset: DOMStringMap(0)
​
dir: ""
​
draggable: false
​
firstChild: null
​
firstElementChild: null
​
frameBorder: "0"
​
height: "431"
​
hidden: false
​
id: ""
​
innerHTML: ""
​
innerText: ""
​
isConnected: true
​
isContentEditable: false
​
lang: ""
​
lastChild: null
​
lastElementChild: null
​
localName: "iframe"
​
longDesc: ""
​
marginHeight: ""
​
marginWidth: ""
​
name: ""
​
namespaceURI: "http://www.w3.org/1999/xhtml"
​
nextElementSibling: <form action="http://player.shinden.eu" method="post" target="_blank" style="text-align:right; margin: 10px 20px">​
nextSibling: #text "
"
​
nodeName: "IFRAME"
​
nodeType: 1
​
nodeValue: null
​
offsetHeight: 431
​
offsetLeft: 5
​
offsetParent: <div class="player-online box" style="">
​
offsetTop: 10
​
offsetWidth: 765
​
onabort: null
​
onanimationcancel: null
​
onanimationend: null
​
onanimationiteration: null
​
onanimationstart: null
​
onauxclick: null
​
onblur: null
​
oncanplay: null
​
oncanplaythrough: null
​
onchange: null
​
onclick: null
​
onclose: null
​
oncontextmenu: null
​
oncopy: null
​
oncuechange: null
​
oncut: null
​
ondblclick: null
​
ondrag: null
​
ondragend: null
​
ondragenter: null
​
ondragexit: null
​
ondragleave: null
​
ondragover: null
​
ondragstart: null
​
ondrop: null
​
ondurationchange: null
​
onemptied: null
​
onended: null
​
onerror: null
​
onfocus: null
​
onfullscreenchange: null
​
onfullscreenerror: null
​
ongotpointercapture: null
​
oninput: null
​
oninvalid: null
​
onkeydown: null
​
onkeypress: null
​
onkeyup: null
​
onload: null
​
onloadeddata: null
​
onloadedmetadata: null
​
onloadend: null
​
onloadstart: null
​
onlostpointercapture: null
​
onmousedown: null
​
onmouseenter: null
​
onmouseleave: null
​
onmousemove: null
​
onmouseout: null
​
onmouseover: null
​
onmouseup: null
​
onmozfullscreenchange: null
​
onmozfullscreenerror: null
​
onpaste: null
​
onpause: null
​
onplay: null
​
onplaying: null
​
onpointercancel: null
​
onpointerdown: null
​
onpointerenter: null
​
onpointerleave: null
​
onpointermove: null
​
onpointerout: null
​
onpointerover: null
​
onpointerup: null
​
onprogress: null
​
onratechange: null
​
onreset: null
​
onresize: null
​
onscroll: null
​
onseeked: null
​
onseeking: null
​
onselect: null
​
onselectstart: null
​
onshow: null
​
onstalled: null
​
onsubmit: null
​
onsuspend: null
​
ontimeupdate: null
​
ontoggle: null
​
ontransitioncancel: null
​
ontransitionend: null
​
ontransitionrun: null
​
ontransitionstart: null
​
onvolumechange: null
​
onwaiting: null
​
onwebkitanimationend: null
​
onwebkitanimationiteration: null
​
onwebkitanimationstart: null
​
onwebkittransitionend: null
​
onwheel: null
​
outerHTML: "<iframe src=\"//www.mp4upload.com/embed-f9ntae302eec.html\" scrolling=\"no\" allowfullscreen=\"\" width=\"765\" height=\"431\" frameborder=\"0\"></iframe>"
​
ownerDocument: HTMLDocument https://shinden.pl/episode/45069-gate-jieitai-kanochi-nite-kaku-tatakaeri-2/view/137211#column-one-inner
​
parentElement: <div id="player-block" class="player-container">​
parentNode: <div id="player-block" class="player-container">
​
prefix: null
​
previousElementSibling: null
​
previousSibling: #text "
"
​
referrerPolicy: ""
​
sandbox: DOMTokenList []
​
scrollHeight: 431
​
scrollLeft: 0
​
scrollLeftMax: 0
​
scrollTop: 0
​
scrollTopMax: 0
​
scrollWidth: 765
​
scrolling: "no"
​
shadowRoot: null
​
slot: ""
​
spellcheck: false
​
src: "https://www.mp4upload.com/embed-f9ntae302eec.html"
​
srcdoc: ""
​
style: CSS2Properties(0)
​
tabIndex: 0
​
tagName: "IFRAME"
​
textContent: ""
​
title: ""
​
width: "765"
​
<prototype>: HTMLIFrameElementPrototype { getSVGDocument: getSVGDocument(), src: Getter & Setter, srcdoc: Getter & Setter, … }

Solution

  • The iframe on a different origin, hence fiddling with the <iframe> element on the parent page won't permit you to view anything inside the child.

    While it would be possible to set up a userscript to run on both the parent page and the child page, and then communicate between the iframe and its parent window with postMessage, you probably only need to run the script inside the iframe. Change your metadata block to include the child page instead (mp4upload.com), and then you can remove the ads from there.

    As a side note, polling with setInterval to hide elements is a bit inelegant - if you want to hide certain elements, you might be able to just insert a CSS stylesheet instead. For example, the ad-removal script could be something like the following:

    document.body.appendChild(document.createElement('style')).textContent = `
    .ad-container {
      display: none;
    }
    `;
    

    where you replace .ad-container with the selector(s) of the ad containers, of course. Then there won't be need for any other Javascript, the stylesheet can take care of it all.