I am using JavaScript to make a small iframe application, and I cannot seem to figure out a way to update the URL in my URL bar I made when someone clicks a link inside the iframe.
It needs to be instantaneous, and preferably without checking every millisecond whether or not the value of document.getElementById('idofiframe').src has changed.
I can't seem to find a simple property to tell when the url has changed, so if there is not one, then solving this programmatically will work as well.
Thanks for the help!
This will be difficult to do because it is considered xss and most browsers block that.
There are most likely some workarounds involving AJAX.
First of all, what you want to do will be possible only if the source of your iframe points to the same domain as the parent window. So if you have a page page.html that iframes another page iframed.html, then both of them have to reside on the same domain (e.g. www.example.com/page.html and www.example.com/iframed.html)
If that is the case, you can do the following in the iframed.html page:
<script type="text/javascript">
window.onload = function() {
var links = document.getElementsByTagName('a');
for (var i=0, link; link = links[i]; i++) {
link.onclick = function() {
window.parent.location.href = '#' + encodeURIComponent(this.href);
}
}
}
</script>
This will make it so that whenever you click on a link in iframed.html, the url bar will put the url of the link in the "hash tag" of the url (e.g. www.example.com/page.html#http%3A%2F%2Fwww.example.com%2FanotherPage.html)
Obviously, you would have to have a script like this on every page that is to appear inside the iframe.
Once this is in place, then you can put this snippet inside of page.html, and it will make the iframe automatically load the url in the hash tag:
window.onload = function() {
var url = window.location.hash.substr(1);
if (url) {
document.getElementById('iframe').src = url;
}
}
I unfortunately haven't run this code to test it, but it is pretty straight forward and should explain the idea. Let me know how it goes!
You could add an onload event to the iframe and then monitor that - it'll get thrown whenever the frame finishes loading (though, of course, it could be the same URL again...)
Instead, can you add code to the frame's contents to have it raise an event to the container frame?
In IE, the "OnReadyStateChanged" event might give you what you want.
Related
Imagine the situation, where I have an iframe of a website.
Inside that website there is a button in which I want to click via javascript.
After looking into the HTML of the website, I noticed that the button is actually a div, with class like.
So I tried this:
function likeFunction()
{
var iframe = document.getElementById("myFrame");
var elmnt = iframe.contentWindow.document.getElementsByTagName("div")[10];
elmnt.click();
}
or
function likeFunction()
{
var iframe = document.getElementById("myFrame");
iframe.contentWindow.document.getElementsByTagName("div")[10].click();
}
and my final attempt was giving that div an ID='ex'
function likeFunction()
{
var iframe = document.getElementById("myFrame");
iframe.contentWindow.document.getElementById("ex").click();
}
But in the end, nothing really did it for me, any ideas?
Thanks in advance!
Your solution should work, as long as the iFrame is on the same domain. If it is not, you should get an error on this line
iframe.contentWindow.document.getElementsByTagName("div")[10].click();
So you would probably have noticed.
My only thoughts are:
you might be using the wrong selector,
you might be running the posted script on the iframe itself, not on the parent scope
you might be running this before the iFrame is loaded. Maybe running this onDocumentComplete on the parent document or some other way.
The click listener might be on on different element than the one you are progamatically clicking on.
But in the scenarios I mentioned, you should be getting an error, which you didn't mention.
Otherwise, the general approach works on my tests.
Say I have a simple script
var i = 0;
test();
function test() {
console.log(i++);
setTimeout(test, 1000);
}
I put it in a Google Chrome console. How do I make it continue to run after the page navigates to another (should continue to print out numbers when browsing the web)?
Maybe save the variable 'i' in onbeforeunload() function, and launch a new script with that saved variable?
How do I make it continue to run after the page navigates to another
you can't, the script cannot continue on another page, it's the browser that runs the javascript in the page, and that will stop it when moving to another page.
(or) should continue to print out numbers when browsing the web?
you have yourself answered this. You can certainly save the counter in localstorage and resume counting on the next page, provided this next page contains the same or similar script and the logic to restore the counter from localStorage.
Or, you can move part of this logic to a server-side script.
I suppose this script is an example and displaying numbers is not really what you want to do.
If you are looking for something to run script even when you have left the browser, I suggest you take a look at Service workers.
If you want more resources, you can check Jake Archibald's blog. He is a chrome developer and he is always talking about service workers. An introduction here.
I didn't see any good suggestions posted already for what I was trying to do but I came up with something that worked for me. I wanted to add a navigation element on the page and not have it go away after navigating. This was on a website that was not managed by me. I removed the innerHtml of the body of the page, added an iframe and pointed it at the page I was on, set it to 100% width and height and removed the border. Then I could navigate within the iframe, but still have my script function run in a set timeout to add the navigation element back to the page after it navigated. Something like this:
document.body.innerHTML = ''
iframe = document.createElement('iframe');
iframe.setAttribute('id', 'iframe');
document.body.appendChild(iframe);
iframe.setAttribute('src', window.location.href);
iframe.style.height = "100%";
iframe.style.width = "100%";
iframe.style.border = "0";
function addContent(){
setTimeout(()=>{
elementToAddTo = iframe.contentWindow.document.getElementById('my-element-id')];
contentToAdd = document.createElement('div');
contentToAdd.innerHTML = `<p>My new content</p>`
elementToAddTo.insertBefore(contentToAdd, elementToAddTo.childNodes[0]);
}, 1000);
}
addContent()
Then in that new content somewhere I had an onchange event which would navigate and call the addContent function by saying window.top.addContent();
onchange="window.location.href = window.location.href.replace(/(param1=.*)/, 'param1='+myNewParamValue); window.top.addContent();">
I Understand this approach makes a lot of assumptions about what you're trying to do and maybe it is only working for me because I'm only changing a param value, but I want to leave this hear in case it helps somebody trying to figure out how to do something similar.
What I need is just like How can I open a link in the default web browser from an HTA?, but with the restriction that the link sits inside an iframe.
The iframe's loads a page in our server.
Idea: can the iframe's redirect be detected & prevented, so then we'd run code like in https://stackoverflow.com/a/185581/66372. How?
Update 1
To be clear: the problem we're trying to solve is that when the user clicks on any link, it opens in the default browser.
One option similar to mplungjan's answer, is to capture the click event for all links in the iframe's DOM. Is there a more generic option that works at the iframe, document or body level? (and thus also works with delayed loads and any other tricks)
Something like this, which should be perfectly allowed in an HTA which has elevated rights
window.onload=function() {
window.frames["iframe_in_this_document"].onload=function() {
var links = this.document.getElementsByTagName("a");
for (var i=0;i<links.length;i++) {
url = links[i].href;
if (url) links[i].onclick=function() {
var shell = new ActiveXObject("WScript.Shell");
shell.run(this.href);
return false;
}
}
}
I want to list an iframe with a classified ad in it. Sometimes the vendors redirect the page to their homepage when the item is no longer available. I want to be able to identify this so I can de-index the item assuming it has sold. What is the best method to accomplish this?
You can use jQuery's load function that fires onload or reload.
http://api.jquery.com/load/
You will need to store the number of times the iframe has reloaded.
Something like,
var reloaded = 0;
$("#iframe_id").load(function(){
reloaded++;
});
You can not detect the location of the iframe when it is in a different domain unless they have the proper headers set for CORS.
The only way to do it without worrying about the other domain is to have your serverside code run a check on the page and see if it redirects.
On the frame load, detect what the URL is:
var frameLoadCount = 0;
var firstURL;
$('iframe').load(function() {
if (frameLoadCount === 0) {
firstURL = $(this).attr('src');
} else {
if (firstURL !== $(this).attr('src')) {
// The iframe has been redirected.
}
}
});
Basically the above code runs everytime the iframe has loaded, checks if it's the first time, if it is, assign the URL to a variable. If it has loaded more than once, check if the original url matches the current url.
This has benefits from just checking if it's loaded more than once, because you can target specific sources etc.
I'm trying to append the url of the parent page an iframe is located in based on the current url within the iframe.
This is all taking place on the same domain, so I don't think there should be any security issues.
EDIT:
My code now looks like the following:
function locator_url() {
var iframeUrl = alert(document.getElementById("dealer- locator").documentWindow.location.href);
var iframeUrlSplit = iframeUrl.split('/locator/');
window.location.hash = '#' + iframeUrlSplit[1];
};
$(document).ready(function(){
document.getElementById("dealer-locator").contentWindow.onload = locator_url();
});
Now the default src for the iframe is http://localhost/meade/locator/
The page the iframe is on is http://localhost/meade/dealerlocator/
The code works for the initial page load, the parent url is appended to localhost/meade/dealerlocator/#
However, when I click a link inside the iframe the parent url doesn't change, even though the href value in the iframe has.
The parent url should have it's hash updated to something like:
localhost/meade/dealerlocator/#results_list.php?showonly=US&tab=US&zip=&distance=10&state=&city=&name=
But that's not happening.
What am I missing?
Did you try:
document.getElementById("dealer-locator").contentWindow.onload = locator_url;
Well, if you need click events in your iframe, then you could do it this way:
Car.com
Then locator_url() gets called in the parent page. Same goes for using load events (I mean, load events that occur in the iframe context).