How to access a main window element from an iFrame - javascript

This has been asked before but most answers seem to assume that the parent window is also an iframe that can be selected.
I have a DIV in my parent window:
That I want to display if an error happens in an iFrame embedded on the page.
Here is my iFrame javascript I have attempted:
if ( x == "" || y == ""){
parent.document.getElementById("error").style.display ="block";
parent.document.getElementById("error").style.transition ="all 0.5s ease";
parent.document.getElementById("error").style.opacity ="1";
parent.document.getElementById("error_write").innerHTML = "Oops, looks like you've missed an input field. Please ensure both fields are completed in order for the converter to work.";}
This doesn't seem to pull the "error" element from the parent window and display it. This code WORKS if not attempting to access element from another frame.
Please help.

I understand that you've searched this out, but the answer will always be the same .. The reasoning that you cannot do this is security related ... I understand you are trying to do something as benign as "passing an error"
However, Imagine this -- What if you were a malicious person, loading a login page for, say, a bank in an <iframe> on your page -- And you were allowed to pass login variables from the <iframe> to your parent page ... This of course is overly dramatic, however it is the reason most, if not ALL browsers disallow passing data between <iframe> and parent.

Related

Check if the element inside an iFrame has any content

So I've tried to do a bunch of research and can't seem to find the correct answer for my question so I wanted to reach out and see if anyone knows much.
What I'm attempting to achieve:
Check the contents inside an iFrame and return a boolean whether there is content or not.
Here is what I've attempted:
function check_iframe_body_content(element) {
let has_content = false;
let iframe = element.contents().find('body');
console.log(iframe);
if (iframe.length > 0) {
has_content = true;
}
return has_content;
}
The element is the iFrame return, which will be an array:
When the script tags are disabled, I get the following return:
When the script tags are enabled, I get the following return:
How can I properly determine if the <body> is empty and when it's not? I've tried to do .length on multiple different occasions and each time it comes back as has_content = true because it finds the body element, but it's actually empty.
All help will be appreciated!
You wont have access to the content inside iframe if it's loaded from another website as it's a major security breach.
if that was possible a website could add an iframe to google.com and get access to user personal information like their email address, name and etc.
depending on why you want to check content of iframe, there might be other workarounds.

Applying CSS to items outside of an iFrame (or other element)

I'm trying to inject some css to the body of my SharePoint webpage for a background image. The .js is essentially this:
document.getElementsByTagName( "Body" )[ 0 ].style.backgroundImage = <My Image URL>
document.getElementsByTagName( "Body" )[ 0 ].style.backgroundSize = "50%"
document.getElementsByTagName( "Body" )[ 0 ].style.backgroundPosition = "50% 50%"
And it works as I expect, unless there's an iFrame in the middle (or any other 'body' tag). Then the image gets put inside the iFrame as well as the body of my page. These iFrames are essentially popups that come up whenever you need to upload documents, change some settings on the site, etc. They're not up all the time but I don't want the image there, regardless.
When I call document.getElementsByTagName('Body') I always get the Body tag of whatever iFrame is currently up, or I'll get the document's main body. But it's always an HtmlCollection array of 1 item. Same thing happens if I use document.body
All of the body tags have the same generic setup ( <body class="ms-backgroundImage" style="..." spellcheck="false"> ) regardless of if they're the site's actual Body tag or if it's the iFrame's body.
Is there a way with Javascript to say "Apply to the main body, but not to any others"?
Your description contradicts the documentation (see https://developer.mozilla.org/en-US/docs/Web/API/Document/body). Are you really sure it behaves as you described? Your described behavior is nothing I have ever experienced as a developer.
Can you check again and maybe updates this question?
First, the reason you're getting an HtmlCollection when calling getElementsByTagName is because that function returns an array regardless of whether it matches zero, one or many items (observe the plural "s" in "Elements").
The different JS web api "get"-functions are pretty self explanatory that way, in that
getElementById (no plural s) returns a single DOM-node, whereas getElementsBy[Name|ClassName|TagName] all return an array of nodes.
Now to your main question:
By iFrames I take it you mean modal dialogs?
Modal dialogs in SharePoint have one thing in common, which is that they all have the url parameter "&IsDlg=1". This means you can check whether you're in a dialog or not, and have your code act accordingly.
Here's the code you're looking for, which will apply your style to all non-modal pages.
// could have used GetUrlKeyValue("IsDlg") === "1",
// but not sure if sp.js is loaded, so this is safer
var isDialog = document.location.search.indexOf("IsDlg=1") > -1;
// for non-dialog pages
if(!isDialog) {
var docBody = document.body;
// if for some crazy reason document.body returns an array??
if(document.body.length) { docBody = document.body[0] }
// styling
docBody.style.backgroundImage = "[Your Image URL]";
docBody.style.backgroundSize = "50%";
docBody.style.backgroundPosition = "50% 50%";
}
PS: Customizing the master page is not reccomended practice in newer (>2007) versions of SharePoint.
There are several other methods (CustomActions, for instance) of customizing the platform without touching the out-of-the box master page, which you should familiarize yourself with if you want to work professionally with sharepoint.
To make the change I was trying to do, I just had to add an image to the "Look and Feel" of the page via Site Settings -> Look and Feel. Quick and easy, doesn't require any code... Thankfully.

JS know the current distance to the top of an object

I want to know, how can I get the distance that a div is from window top, by it's id attribute.
I've already tried
var pubID = "#pub_<?php echo $_GET['pub']; ?>";
alert($(pubID).scrollTop());, and this alert return me "NULL".
I want to use this, when I'am on a determinate page and click on a notification, it redirects the user to another page, and should scroll the new page to the position of the div mentioned on the notification.
Help please,
Gonçalo Ribeiro
Your best bet would be to use jQuery, because offsetTop / offsetLeft don't work consistently in all browsers.
So, assuming you've included jQuery on the page, you could use:
$('#element').offset().top
Also, if you're so inclined, have a read here on the subject here and here.
Edit
Thinking about your problem, would linking to an anchor name (i.e. Adding a hash to the URL) not be easier than trying to work out the position like this?
One link to rule them all

auto update function results on a page

Ok, first off. No jquery, no ajax, just pure javascript.
I have the following code on a page called text.html.
<html><body>
<script>
function live(ID,txt2) {
var a = document.getElementById(ID);
a.innerHTML = (txt2);
}
setInterval(live, 250);
a.innerHTML =(txt2);
</script>
<div id="txt1">Live</div><p />
</body></html>
I have the following code on live2.html
<html>
<body>
<p />
<iframe width="400" height="50" src="text.html" name="frameA" id="frameA"></iframe><p />
<input type="button" value="Live" onClick="document.getElementById('frameA').contentWindow.live('txt1','L I V E')">
<input type="button" value="Rebroadcast" onClick="document.getElementById('frameA').contentWindow.live('txt1','Rebroadcast')"><br />
text
</body>
</html>
The current code works exactly as I wanted it to by updating the information in an iframe. My issue is this. If someone visits text.html directly, I want them to be able to see whatever I've changed that document to.
Example:
I click on a button and the text in the iframe now says rebroadcast.
Someone else visits text.html and they also see rebroadcast. If while they are looking at text.html, I hit the live button, the text.html page will update with the word live.
I can do PHP scripting on this as well. I have tried jquery and have issues with getting it to work correctly and I don't really have the knowledge or access to implement much of anything else.
This is an on-going project. The end result, I hope, will be an iframe that I can update while not actually being on the same page that the frame is located on. (same domain tho) The content will be anything from images, to youtube embeds and pictures. I'm trying to get a more comprehensive idea of how this language works and that's why I'm taking it one step at a time. I have no issue with visiting tutorials or looking at pre-made solutions. Thanks for your help. :)
I think I'm probably missing something. Users will always see the text "Live" because that's what's hard-coded in text.html. It doesn't matter if you change the text through JavaScript since it will only affect the browser that you're seeing. You need to save it to a persistence storage (ie. database) and dynamically display it on the page.
live2.html can use AJAX to send the changes to the server, which can then update live.html. But this is a poor way to do it, since it means that the contents of live.html are updated outside of your version control and/or content management system. It's better to use a real database and generate the page dynamically, as suke said.
First off this is what happens when someone learning programming languages doesn't fully comprehend what a language can and can't do. The original idea was to let a specific group of people know when it was a re-broadcast or when the show was live. I wanted the control of when to change that information to only be available to an admin of sorts. In the end the entire idea got scrapped and entirely impractical. The solution, essentially, doesn't exist in the context of the way I wanted to accomplish this. Years later...
The solution is to have live and rebroadcast inside div tags with CSS. Then use a JavaScript function to change the attributes of the divs to either be hidden or shown. The button or or link would need to exist on the same page as the live or rebroadcast text. This would also mean that there is no need for a separate frame. To have this element controlled from outside the page it's on could only be done by storing a value somewhere else and having that value periodically checked.
JSFiddle
The Script:
var x = document.getElementById("txt1");
var y = document.getElementById("txt2");
function htext() {
x.style.visibility = 'visible';
y.style.visibility = 'hidden';
}
function stext() {
x.style.visibility = 'hidden';
y.style.visibility = 'visible';
}
function ctext() {
var z = getComputedStyle(x).getPropertyValue("visibility");
if (z != 'hidden') {
stext();
} else if (z != 'visible') {
htext();
}
}
The CSS:
#txt1 {
visibility: hidden;
margin-left:0px;
}
#txt2 {
visibility:visible;
margin-left:0px;
}
The HTML:
<span id="txt1">Live</span>
<span id="txt2">Rebroadcast</span>
<br />
click
To be honest. I'm not entirely sure of the programming needed to store information somewhere else and have a check to see if certain conditions are true. The program above will essentially hide and show a div. I could probably go a step further and use JQuery to create and remove the actual div itself. In the end this is essentially close to the solution I ended up using and then later on discarding and giving up on the project.

document.getElementById coming back with null for a known element - why?

I'm using the Google Chrome JavaScript console and I was just looking at the Gmail page and just practicing manipulating the DOM. However, when I do the following it just comes back as null:
document.getElementById('gbx3');
There is a div element in the page that has an id of 'gbx3' - so why is it returning null? What would/could be causing this? The same thing occurs using the Firefox web console.
If you try and access the 'gb' id (this is the main top toolbar) in the same Gmail page it comes back null, but if you access this element at google.com it will come back with the element.
GMail is composed of frames. This one works:
frames[3].document.getElementById('gbx3');
In general, if you know the ID of the iframe element, the contentDocument property can be used (provided that you don't have same-origin problems, and the document is loaded):
document.getElementById('hist_frame').contentDocument.getElementById('gbx3');
As per my comment:
My best bet is that gbx is inside the iframe that contained the search
result, and document.getElementById works on the same scope as your
console
You can search all the frames to find what you need:
for(var i = 0; i < frames.length; i++) {
var curDoc = frames[i].document;
if(curDoc.getElementById('gbx')) console.log(curDoc.getElementById('gbx'));
}

Categories