Can javascript running inside an iframe affect the main page? - javascript

Partial Code:
My below code pulls a query from my DB and then uses inner.HTML = to display the data inside a div. It works fine in it original use....
However the below version is called inside a iFrame as it is used to update the page.
The page has no errors and the JavaScript fires however the last line does not work...
I have just realized that perhaps since it is loading in the hidden iFrame it is trying to set the innerHTML of a div inside the iFrame and that of course will not work.
Is this what is happening? It doesn't make sense because I have another script that calls JavaScript at the end of it in the same manner and it works fine.
<?php
while ($row = mysql_fetch_array($result))
{
$p = $p.'<div id="left"><img src="http://www.sharingizcaring.com/bleepV2/images/thumbs/'.$row[image].'" /></div>';
$p = $p.'<div id="right"><h2>'.$row[artist].' - '.$row['title'].'</h2><br>'.$row['message'].'<br>';
$p = $p.''.$row[username].' '.$row[date].'</div>';
$p = $p.'<div style="clear: both;"></div>';
$p = $p.'<div id="dotted-line"></div>';
}
$p = addslashes($p);
?>
<script>
alert('posts are firing? ');
document.getElementById('posts').innerHTML = 'why doth this faileth?';
</script>

You can do it! Read here for more info
You can affect the document with contains the iframe by setting and getting variables from the window element:
// normally you use...
var whatever = "value";
// use the window object instead, which is shared
// between the iframe and the parent
window.whatever = "value";
The other thing you should know is that you can access the main document via the parent object
inside the iframe you can use...
parent.someattr;
// or try this
parent.getElementById('some_element');

I think what you want is:
parent.getElementById('posts').innerHTML = 'why doth this faileth?';

The part in the iframe isn't considered the same document.

you have to use parent.

Related

Access class name in a window element

var win = window.open('', '_blank', 'PopUp' + ',width=1300,height=800');
win.document.write(`
<div class="col-sm-24">
<p class="page-title headerLabel"></p>
</div>`);
I have a window element with the class headerLabel. In this paragraph tag I want to inject some data which is liable to change... I have tried
var heading = Some Heading;
win.document.write($('.headerLabel').html(heading));
but it's not working
Assuming win is a different window from the one containing this code, you need to tell jQuery to use the other document instead of its default one (the current window). You also don't want write, as you're modifying an existing element.
$(win.document).find(".headerLabel").html("The new content");
should do it, although if you're going to do anything complex with jQuery in another window, it's usually better to load jQuery in the other window and then call that copy.
You could also easily do this without jQuery, which removes that concern:
win.document.querySelector(".headerLabel").innerHTML = "The new content";
The problem is this line: win.document.write($('.headerLabel').html(heading));
// I don't know what is win. So, let's make an example thinking this is another window.
var win = window;
You're trying to write the result of $('.headerLabel').html(heading). So, just call the .html function.
var win = window; // I don't know what is win. So, let's make an example thinking this is another window.
win.document.write(`
<div class="col-sm-24">
<p class="page-title headerLabel"></p>
</div>`);
var heading = "Some Heading";
$('.headerLabel', win.document).html(heading)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

How to write JavaScript for iframe and not iframe (same content)

Setup
I will be accessing content on my page sometimes from an iframe and sometimes from the same content not in an iframe.
Problem
I'm trying to figure out a way to write javascript once and include both ways of accessing that content during the declaration of the var...
so far example
var $Holder;
if($('#MyHolder iframe').contents().length > 0) {
$Holder = $('#MyHolder iframe');
}
else {
$Holder = $('#MyHolder');
}
but I can't do this since if the content is in an iframe I need to access it this way:
$Holder.contents().find('#SomeButton').on('click',function(){});
and this doesn't work if the content is directly on the page. This also does not work if I add .contents().
If I understand the question correctly, you should be able to set your $Holder to the contents() of the iframe like so:
var $Holder;
if($('#MyHolder iframe').contents().length > 0) {
$Holder = $('#MyHolder iframe').contents();
}
else {
$Holder = $('#MyHolder');
}
Then you should be able to access elements in either case like so:
$Holder.find('#SomeButton').on('click',function(){});

jQuery load local iframe url with escaped characters for disqus commenting

I'm loading a custom page type that is just comments for a post. This is so I can use Disqus threads for easier usability when multiple loop posts are on a single page.
When loading an iFrame with the following structure I keep getting this syntax error. Are my escape characters wrong?
$(".boxyComments a").click(function (event) {
event.preventDefault();
var post_id = $(this).attr("rel");
$(".commentsIframeBig")
.get(0).contentWindow.location.href =
$("<?php echo get_site_url(); ?>","\/ajax-post-fold\/",post_id);
What's happening is the get retrieves the Wordpress hook to print the site url (in this case it prints http://whateverdomainex.com for the 1st call, 2nd should print /ajax-post-fold/ and the last call should print the post ID so the entire url ends up printing as http://whateverdomanex.com/ajax-post-fold/2825.
Instead my Chrome console gives me the following message:
Uncaught Error: Syntax error, unrecognized expression: /ajax-post-fold/
Update
I've put this variable into place and called it rather than the $("<?php echo get_site_url(); ?>","\/ajax-post-fold\/",post_id); as the get reference:
var postLink = $("<?php echo get_site_url(); ?>"+"\/ajax-post-fold\/"+post_id);
Implemented as such:
$(".boxyComments a").click(function (event) {
event.preventDefault();
var postLink = $("<?php echo get_site_url(); ?>"+"\/ajax-post-fold\/"+post_id);
var post_id = $(this).attr("rel");
$(".commentsIframeBig")
.get(0).contentWindow.location.href = postLink;
Which gives me the following Chrome message:
Uncaught Error: Syntax error, unrecognized expression: http://www.theciv.com/ajax-post-fold/28448
The URL that should be in the src attribute for the iFrame looks like it should be fine and good to go, so why is this syntax error still being output?
UPDATE
var postLink = "<?= site_url('\/ajax-post\/'); ?>"+post_id;
$(this).closest(".boxy").find(".commentsIframeBig")
.css("display","block")
.animate({height: "100%"}, 500)
.get(0).contentWindow.location.href = postLink;
With the proper structure above, the custom page is now loading in the iFrame. However the additional construct of +page_id which includes the rel attribute containing the post's id isn't loading properly.
Moreover when calling the new url as it's original custom page template, then adding the post's id does not load the correct page with post id. Confused yet? Read it again. Took me awhile to write that sentence.
In any case, now my mission to have the post id load when adding the custom page and the post_id as an added string for the iFrame's url to load properly.
update
Here is final working code to load Disqus comments into same page, pseudo multiple times.
Basically this is pushing a post id to the end of a custom page type, resulting in the post's content and attributable elements being loaded into the custom page template.
When stripping that custom page template down to just show the comments for the page, you can create a load/unload reaction whereby you are only calling Disqus once, removing that instance and then loading it again when another Load Comments button is clicked within a subsequently loaded post on the same page. Yay. Multiple Disqus commenting on one page with minimal Ajax loading.
Here is the structure et al that is almost working for me. Only 2 bugs left. First is the secondary load when emptying, then reloading the new Disqus page into the Ajax element using the .ajaxComplete() callback function.
What's happening now is the callback is basically not being fired at all. As far as I can tell. Clicking on it a second time however, does make the call. But this is due to the class parameters being met for the else statement.
Second bug left is I'm having a hard time figuring out how to get the appropriate elements to enlarge, while leaving the others the same size.
// Load comments and/or custom post content
$(".boxyComments a").click(function (event) {
event.preventDefault();
$.ajaxSetup({cache:false});
var post_id = $(this).attr("rel"); var excHeight = $(this).closest('.boxy').find('.initialPostLoad').height();
var postHeight = $(this).closest('.boxy').find('.articleImageThumb').height();
var postWidth = $(this).closest('.boxy').find('.articleImageThumb').width();
// close other comments boxes that may already be open
if($('.commentsOpen').length ) {
console.log('comments are open');
$('.bigBoxy').closest('.boxy')
.animate({height:(postHeight + excHeight)}, 500);
$('.showComments')
.removeClass('bigBoxy')
.removeClass('commentsOpen');
$('.commentsAjax')
.empty(function(){
$(this).closest(".boxy").find(".showComments")
.addClass("commentsOpen")
.addClass("bigBoxy");
$(".bigBoxy").find(".commentsAjax ")
.css("display","block")
.animate({height: "500px"}, 500)
.load("http://<?php echo $_SERVER[HTTP_HOST]; ?>/ajax-post/",{id:post_id});
$(this).closest(".boxy")
.ajaxComplete(function() {
var excHeight = $(this).closest('.boxy').find('.initialPostLoad')
.height();
var postHeight = $(this).closest('.boxy').find('.articleImageThumb')
.height();
$(this).closest(".boxy").animate({height: (postHeight + excHeight)}, 500)
});
});
} else {
$(this).closest(".boxyComments").find(".showComments")
.addClass("commentsOpen")
.addClass("bigBoxy");
$(this).closest(".boxy").find(".commentsAjax")
.css("display","block")
.animate({height: "500px"}, 500)
.load("http://<?php echo $_SERVER[HTTP_HOST]; ?>/ajax-post/",{id:post_id});
$(this).closest(".boxy")
.ajaxComplete(function() {
var excHeight = $(this).closest('.boxy').find('.initialPostLoad')
.height();
var postHeight = $(this).closest('.boxy').find('.articleImageThumb')
.height();
$(this).closest(".boxy").animate({height: (postHeight + excHeight)}, 500)
});
}
});
Okay, here's full working code to do what you want. You'll have to swap out a few placeholders for your actual code:
<script>
jQuery(document).ready(function($){$(".boxyComments a").click(function (event) {
event.preventDefault();
var post_id = $(this).attr("rel");
var postLink = "<?= site_url('/path/'); ?>"+post_id;
$("#myFrame").attr('src', postLink);
});
});
</script>
And sample divs & iFrame:
<div class='boxyComments'>
<a href='#' rel='some-url'>test link</a>
</div>
<div class=".commentsIframeBig">
<iframe id='myFrame' height="500px" width="800px" src=''>
</iframe>
</div>
Tested it locally and it worked no problem. You might have been running into issues with it not properly accessing the iFrame. If you can give the iFrame an id that makes it easier.
It's because you're declaring var postlink as a jQuery object. You just need to get it as a string that you can then pass to the iframe.
var post_id = $(this).attr("rel");
var postLink = "<?= site_url('/ajax-post-fold/'); ?>"+post_id;
UPDATE 2
Looks like the string shouldn't be included within the <?= get_site_url() ?> after all.
Instead I've created a few vars to affect it. Code updated below with answer:
var postDir = "\/ajax-post-fold\/";
var postLink = "<?= get_site_url(postDir); ?>"+"\/ajax-post-fold\/"+post_id;

Reload iframe src / location with new url not working in Safari

I have a page that loads with initially just a form within an iframe, something like this:
<iframe id="oIframe" ...src='somePage>'
<form ... />
</iframe>
When you click a button in the form, some javascript is invoked that builds a url and then I want to do the following:
frame.src = 'somePage?listId=1';
This works in IE to "reload" the frame with the new contents.
However, in Safari this does not work.
I have jQuery available, but I don't want to replace the existing iframe because there are events attached to it. I also can not modify the id of the iframe because it is referenced throughout the application.
I have seen some similar issues but no solutions that seem to work well for my exact issue.
Any assistance anyone can provide would be great!
Some browsers don't use "src" when calling the javascript object directly from the javascript hierarchy and others use "location" or "href" instead of "src" to change the url . You should try these two methods to update your iframe with a new url.
To prevent browser cache add a pseudo-random string like a number and timestamp to the url to prevent caching. For example add "new Date().getTime()" to your url.
Some calling examples:
document.getElementById(iframeId).src = url;
or
window.frames[iframeName].location = url;
I recommend the first option using document.getElementById
Also you can force the iframe to reload a page using
document.getElementById(iframeId).reload(true);
So the answer is very simple:
1. put a <div id="container"> </div> on your page
2. when reload needed use following jQuery:
$("#container").empty();
$("#container").append("<iframe src='" + url + "' />");
and that's it.
Of course there is more elegant way of creating DOM with jQuery but this gives the idea of "refreshing" iframe.
Works in FF18, CH24, IE9, O12 (well it's jQuery so it will work almost always :)
I found a better solution (albeit not paticularly eloquent) for this using jQuery.ajax:
jQuery.ajax({
type: 'GET',
url: "/somePage?someparms",
success: function() {
frameObj.src = "/somePage?someparms";
}
});
This forces the DOM to be read within the frame object, and reloads it once the server is ready to respond.
Try this
form.setAttribute('src', 'somePage?listId=1');
Well, I was able to find what appears to be a feasible solution -- it's a work in progress, but this is basically what I ended up doing:
var myFrame = document.getElementById('frame'); // get frame
myFrame.src = url; // set src attribute of original frame
var originalId = myFrame.id; // retain the original id of the frame
var newFrameId = myFrame.id + new Date().getTime(); // create a new id
var newFrame = "<iframe id=\"" + newFrameId + "\"/>"; // iframe string w/ new id
myFrameParent = myFrame.parentElement; // find parent of original iframe
myFrameParent.innerHTML = newFrame; // update innerHTML of parent
document.getElementById(newFrameId).id = originalId; // change id back
I ran into this issue using React, passing the key as props.src solved it
const KeyedIframe = ({children, ...props}) => <iframe key={props.src} { ...props}>
{children}
</iframe>

goto HTML document location dynamically

My page adds # to the html programatically and have this in the tag
function InsertTag(){
//Add <a name="spot"></a> to the middle of this document
}
window.addEventListener('load', InsertTag, false);
my question is how can I make the document then jump to #spot?
Here's a suggestion: use id's instead. If you have:
<div id="something">
Then page.html#something will take you straight to that div. It doesn't have to be a div, it can be used on any element. If you can manipulate the DOM to add that anchor, I am pretty sure you'll be able to do this.
Now... To get there, you can use:
// this approach should work with anchors too
window.location.hash = 'something';
// or scroll silently to position
var node = document.getElementById('something');
window.scroll(0, node.offsetTop);
See it in action here: http://ablazex.com/demos/jump.html
There are subtle differences between the methods. Eg: The first one will cause the location on the address bar to be updated, the second one won't.
If you want it to look nicer you can use a jQuery plugin, like ScrollTo.
Try
window.location = currentUrl+'#spot';
where currentUrl is a variable having the address of the current url
You can try this.
var el = document.getElementById('spot');
var eloffsetTop = el.offsetTop;
window.scroll(0,eloffsetTop);

Categories