Trying to add css styling to iframe with JavaScript - javascript

Trying this on Wordpress:
Inside my iframe I have a ._2p3a class I want to change its width to ._2p3a {width: 100% !important;}.
With CSS its not possible to access that class so I am trying with JavaScript:
MY JS CODE:
function hello() {
let myiFrame = document.getElementById("iframe-css");
let doc = myiFrame.contentDocument;
doc.body.innerHTML = doc.body.innerHTML + '<style>._2p3a{width: 100% !important;}</style>';
}
//the iframe id > "iframe-css"
code Source: https://redstapler.co/how-to-apply-css-to-iframe/
The error:
land_page.js?ver=1.0:4 Uncaught TypeError: Cannot read property 'body' of null
at hello (land_page.js?ver=1.0:4)
at HTMLIFrameElement.onload ((index):539)
underlined code:
.body.innerHTML = doc.body.innerHTML + '<style>._2p3a{width: 100% !important;}</style>';
Tried: Using CSS to affect div style inside iframe
(got errors with all examples "None worked").
I am running this function with onload="hello(this)" on my iframe.
Any other suggestions how I can edit that class to make its width 100%??

please try bellow code ... I hope you get result:
let myiFrame = document.getElementById("iframe-css").contentWindow;
let doc = myiFrame.document;
doc.body.innerHTML = doc.body.innerHTML + '<style>._2p3a{width: 100% !important;}</style>';

Adding a <style> element isn't the best way to do this. However, even if it was, you should try to avoid adding elements via innerHTML. It is better to use Document.createElement (document is an instance of Document) and Element.appendChild (all elements are instances of the Element class).
The best way to do this is by directly modifying the style of the elements in the class.
function hello() {
let myiFrame = document.getElementById("iframe-css");
let doc = myiFrame.contentDocument ?? myiFrame.contentWindow?.document ?? new Document();
let elements = doc.getElementsByClassName("2p3a");
for(let i = 0; i < elements.length; ++i) {
elements[i].style.width = "100%";
}
}
Also, the onload attribute sometimes doesn't work on an iFrame. You may have to use the DOM like this:
document.getElementById("iframe-css").onload = hello;
On a side note, you should generally stick to 2 or 4 spaces of indentation in JavaScript, but you chose 3.

Decided to use a different plugin since using the facebook iframe was causing some trouble. With this new plugin everything is working fine so yea.
Thanks to anyone who put effort to answering, I appreciate your help.

Related

get a dynamic id from an iframe in an iframe

I am actually doing a tricky task, I have to create pack of resource(which are pages on the website), to do so I use iframe to display the content of the pages. But I can have multiples Iframes in one Iframe.
And I want to pass some style on those iframe in iframe, so i have to target them.
I have a special node id for each pages that allow me to return only the body.
So my question is how do I get to target the id of my iframe in my iframe which I tried to do with that line var get_iframe_inside = search_inside.getElementsByTagName("iframe".id); to then modify it's style.
I know that I am not using the right way for this line, but I have been scratching my head all this morning and can't find a way.
function test(id){
var iframe = window.parent.document.getElementById(id); //select my first iframe
get_iframe_inside(id); //call my function to get the iframe in the iframe
function get_iframe_inside (id){
var search_inside = (iframe.contentDocument) ?iframe.contentDocument : iframe.contentWindow.document;
//My goal is then to modify some properties
var get_iframe_inside = search_inside.getElementsByTagName("iframe".id);
$(get_iframe_inside).css({'padding':'0px 50px', 'background-color':'#cecece'});
}
}
Well it was kind of trivial my code was nearly working i just didn't tought at how to get thoses ids.
i just had to get them by tag and after that to do an iteration with for.
var get_iframe_inside = search_inside.getElementsByTagName("iframe");
var i;
for (i = 0; i < get_iframe_inside.length; i++){
get_iframe_inside[i].style.padding='0px 50px';

Add CSS to DIV in an Iframe

I have an Iframe with id="scorm_object".
<iframe id="scorm_object">...</iframe>
Inside this iframe i have a class called framewrap.
I am trying to add CSS to this class like so:
$(document).ready(function() {
$('#scorm_object').contents().find('.framewrap').css('opacity','.2');
});
but I can't seem to get it to work.
I know there are multiple iframe examples on here, but I am really looking for something nice and simple.
Thanks!
Update: Apologies, I have to make this work without jquery.
I have now tried the following:
var iframe = document.getElementsByTagName('iframe')[0];
iframe.addEventListener("load", function() {
window.frames[0].document.body.style.backgroundColor = "#fff";
});
but I get the :
iframe is undefined
error.
Your are firing the JavaScript when the DOM of the parent document is ready. This is likely to happen before the document in the frame is ready.
Waiting for the load event to fire fixed that when I tested it.
Use $(window).on("load", function() { instead of $(document).ready(function() {.
I think this one will work. Change the CSS after iframe loaded
$('#scorm_object').load(function() {
$('#scorm_object').contents().find('.framewrap').css('opacity','.2');
});
If you want to do it in pure javascript you should do something like this. Create an style element and add necessary styles using textContent property and add that style to the of iframe.
var iFrame = document.getElementById("scorm_object");
var style = document.createElement("style");
style.textContent =
'#framewrap{' +
' opacity: 0.2;' +
'}' +
'h1 {' +
' color: green;' +
'}'
;
iFrame.addEventListener ("load", function () {
iframe.contentDocument.head.appendChild(style);
});
The above method doesn't work with cross-domain.
You check this out window.postMessage

Calling two functions from same onclick failure

I have a problem when calling 2 JS functions that work fine separately. I am not well versed in JS: I took the scripts from some posts here and adapted them, and I cannot make them work together. My goal is to make appear the side panel and to change the color of a box within that panel when clicking on the related link in the main text (and to undo it by clicking again on it).
This is the function that I use for showing the side panel:
function showRightPanel() {
var elem = document.getElementById("right-panel");
if (elem.classList) {
console.log("classList supported");
elem.classList.toggle("show");
} else {
var classes = elem.className;
if (classes.indexOf("show") >= 0) {
elem.className = classes.replace("show", "");
} else {
elem.className = classes + " show";
}
console.log(elem.className);
}
}
And this is the function for changing the color:
var els = document.getElementsByClassName('change-color'),
target = document.getElementById('footnotes'),
changeColor = function() {
target.style.backgroundColor = this.getAttribute('data-color');
};
for(var i=els.length-1; i>=0; --i) {
els[i].onclick = changeColor;
}
And this is the html that calls both functions it:
<a href="#footnote1-chapter1" class="change-color" data-color="#E0FFC2"
onclick="showRightPanel();changeColor();"></a>
And this is the box that has to appear and change color:
<div id="footnotes"><p class="footnote" data-id="footnote1-chapter1">
</p></div>
Both scripts are in separate .js files that are referred to in the header, and I know this might be the problem for the second script, as it was mentioned that:
"You should put the javascript at the end of your body (just before ), or wrap it in a function listening load or DOMContentLoaded event (e.g. using addEventListener). If not, document.getElementById is executed before the element is loaded to the DOM, so it return null. – " in this post change background color of div.
But I do not know how to "wrap it in a function listening load or DOMContentLoaded event".
Can someone please help me?
Thank you for your help in advance!
You could wrap your code in an on load function, but the general consensus seems to suggest putting your scripts at the end of the body tag instead, according to this StackOverflow answer and the YUI team. This accomplishes the same thing as wrapping your code, and might fix your problem if it's related to DOM dependencies.
So I would recommend you put your scripts at the end of your body tag instead of in your head tag, and see if that helps.
As Nathan mentioned, your anchor has the attribute onclick as onclick="showRightPanel();changeColor();"
But your javascript replaces this attribute, see: els[i].onclick = changeColor;
So only changeColor function will be called.
[update]
As in the comments, the accepted answer:
els[i].onclick = function(){showRightPanel();changeColor.apply(this);}

How can I scroll content of <webview> tag from JavaScript?

atom-shell: https://github.com/atom/atom-shell
version: v0.20.2
I am using <webview> tag to embed a page. <webview> tag has shadow-root which has one tag, <object id="browser-plugin-1 ...>. So I tried to set scrollTop value for this tag like this.
var webView = document.getElementById('webview tag id');
var elm = webView.shadowRoot.firstChild; // elm is object tag
console.log(elm.scrollTop); // 0
elm.scrollTop = 100;
console.log(elm.scrollTop); // 0
But nothing happend...
Is it possible to control <webview> tag scroll position from outside?
Yes, do this instead:
var webView = document.getElementById('webview tag id');
webView.executeJavaScript("document.querySelector('body:first-child').scrollTop=100");
It's possible to execute any kind of javascript via the WebView.executeJavaScript(code) function which will evaluate the code inside the WebView.
To access your element you would first have to wait for the WebView to load, and then execute the javascript.
var webView = document.getElementById('webView');
webView.addEventListener('did-finish-load', scrollElement );
function scrollElement(){
var code = "var elm = document.querySelector('body:first-child'); elm.scrollTop = 100;";
webView.executeJavaScript(code);
}
Note: Haven't tested this code, it may have syntax errors.
Source (AtomShell's WebView tag documentation)

How to disable div blocks having a certain id pattern?

I would like to write a greasemonkey script to disable a div on a certain page.
On any given load of the page I don't know where in the DOM the div will be but I know it's always called <div id = "alertPanel"> ....</div>
How would I go about disabling this div?
My intial thoughts were something along the lines of:
var myDivs= document.getElementsByTagName('div');
for (i=0; i<myDivs.length; i++)
{
if (myDivs[i].<get id property somehow> = "alertPanel")
myDivs[i].style.visibility = 'hidden';
}
but as you can tell I'm stuck at accessing the id property for an equality check.
Incidently, I'm using a text editor to write this - I guessing that a standard javascript editor would give an autocompletion list after typing in myDivs[i].
If it has an id, you can use document.getElementById:
var div = document.getElementById("alertPanel");
Then if it exists, you can either remove it (probably a bad idea) or hide it:
if (div) {
div.style.display = "none"; // Hides it
// Or
// div.parentNode.removeChild(div); // Removes it entirely
}
Update: Re your comment on another answer:
thanks for your answer. Does your statemt apply to a page with iframes too. The div in question is in an iframe. I've tried ypur solution and it didn't work unfortunately. maybe a link to the page will help: tennis.betfair.com the div i want to disable is the one with id: minigamesContainer
If the element is in an iframe, then you have to call getElementById on the document that's in the iframe, since iframes are separate windows and have separate documents. If you know the id of the iframe, you can use document.getElementById to get the iframe instance, and then use contentDocument to access its document, and then use getElementById on that to get the "minigamesContainer" element:
var iframe, div;
iframe = document.getElementById("the_iframe_id");
if (iframe) {
try {
div = iframe.contentDocument.getElementById("minigamesContainer");
if (div) {
div.style.display = "none";
}
}
catch (e) {
}
}
(The try/catch is there because of a potential security error accessing the content of the iframe; I don't know Greasemonkey well enough to know whether the SOP applies to it. I tend to assume it doesn't, but better safe...)
If you don't know the id of the iframe or if it doesn't have one, you can just loop through all of them by getting them with document.getElementsByTagName and then looping:
var iframes, index, iframe, div;
iframes = document.getElementsByTagName("iframe");
for (index = 0; index < iframes.length; ++index) {
iframe = iframes[index];
try {
div = iframe.contentDocument.getElementById("minigamesContainer");
if (div) {
div.style.display = "none";
break;
}
}
catch (e) {
}
}
References:
DOM2 Core
DOM2 HTML
DOM3 Core
HTML5 Web Applications APIs
In valid HTML you can have only element with certain ID. So:
document.getElementById('alertPanel').style.visiblity = 'hidden';
But if you still need to iterate all div's and check their ID's, then this should work:
if (myDivs[i].id == "alertPanel") myDivs[i].style.visibility = 'hidden';

Categories