Remake page while loading - javascript

I'm writing an extension for chrome. The problem is I need to insert an iframe of loading page into DOM instead of loading itself.
Here is a code of the content script which is not working:
window.stop();
var body = document.createElement("body");
body.src = window.location.href;
document.documentElement.appendChild(body);
Why browser generate body in DOM but don't show it on the page?

Have got no idea why is it happen, but window.stop blocks the DOM from changes after calling. In order to reset this state I should do this:
document.documentElement.innerHTML = "";
And as a bonus head and body will be appended automatically)

Related

Terminate an HTML script element

My site has a page loading system to load only the necessary content of the next page that the user is navigating to, and it keeps the top navigation and footer, and only fetches the new content. In order to execute the script tags that are in the new HTML content that's loaded with fetch(), all the script tags are appended with document.body.appendChild(scriptElementToRun). The script elements are added to an array so that they can be removed when the user navigates to another page which will require different scripts. The problem is that removing the script elements from the DOM is not enough to terminate them. They still continue to execute. Is it possible to stop the execution of only the scripts that are in the array, even asynchronous code such as setInterval, setTimout, WebSockets etc. that don't run in the main event loop, without adding anything to the script tags I want to stop?
This is the code that adds the scripts:
let result = new TextDecoder("utf-8").decode(data); // decode the binary response data
$('mn').innerHTML = result; // a div that contains the main body content of the page
for (script of $('mn').getElementsByTagName('script')) {
let activeScriptElement = document.createElement('script');
pageScripts.push(activeScriptElement);
if (script.src) {
activeScriptElement.src = script.src;
console.log('run script: ' + script.src);
} else { // inline script
activeScriptElement.appendChild(document.createTextNode(script.innerHTML));
console.log('run script: inline');
}
document.body.appendChild(activeScriptElement);
}
I then remove the scripts when loading a new page:
for (script of pageScripts){
script.remove();
}
EDIT:
What I ended up doing is putting all the page HTML content in an iFrame and communicating between the iFrame and the parent window with window.postMessage()
It would be helpful to see the code you're talking about. I'm guessing that you are using event listeners, which will still be active, even if you remove script-tags from the DOM.
You can remove events like this:
document.getElementById("your-elements-id").removeEventListener();
var myTimeout = setTimeout(...);
clearTimeout(myTimeout);
var myInterval = setInterval(...);
clearInterval(myInterval);

How can I check if the contents inside an iframe is fully loaded and the src url is not down(404/not available) using angular?

I have an angular app which is having an iframe that loads a chat bot from an external url.I need to check if the url is fully loaded and the url is not down.
The iframe is initially not loaded on the dom and is only loaded after the user clicks on an icon.Since the iframe takes some time to load initially the iframe space will be empty.I tried showing a loader by setting it as background to the div that contains the iframe but the loader was always running even after the iframe is loaded.
Can somebody please guide me? Im new to angular.Im using agular 5.TIA
The simplest way to do this is to check onload events on iframe. ContentDocument of type Document, readonly, checks this frame contains, if there is any and it is available, or otherwise it will return null.
//Get reference of the iframe with reference variable and call
// onload event on it
iframe.onload = function(){
var that = $(this)[0];
try{
that.contentDocument;
}
catch(err){
//TODO
}
}

Use parent jquery library in child Iframe

I have a two Iframe in my HTML page. I want to use one single jquery file which is loaded on parent page. The code give below is working fine every browser but it has one issue with chrome with ctrl+f5 key. When page is loading first time and when we are pressing ctrl+f5 the it is giving error in chrome otherwise it is working fine. Here is some snapshot. Parent page and iframe are in same domain.
if (typeof(jQuery) == "undefined") {
var iframeBody = document.getElementsByTagName("body")[0];
var jQuery = function (selector) { return parent.jQuery(selector, iframeBody); };
var $ = jQuery;
}
Add the jQuery script in both pages to avoid race condition. When one is loaded, the other will be retrieved from the browser cache.

How to force an iFrame to reload once it loads

I have numerous iframes that load specific content on my pages. Both the parent and iframe are on the same domain.
I have a scrollbar inside the iframe that doesn't seem to load correctly in all browsers. But when I refresh the iframe it loads perfect. I have no idea why it does this.
I have used the meta refresh, which works but I don't want the page to refresh constantly, just once.
The solution I'm looking for will reload the iFrame content after the iFrame is opened, with a minimal delay.
Edit
I realized that my page loads all of my iframes when the index is loaded. The iframes appear in a jQuery overlay, which is also loaded but visibility:hidden until called. So on this call is when I would want the iframe to be reloaded.
Could anyone help me come up with a Javascript function that reloads the iFrame when I click the link to the iFrame? I've gotten close but I know nothing about js and I keep falling short. I have a function that reloads the page, but I can't figure out how to get it called just once.
I have this so far:
<script type="text/javascript">
var pl;
var change;
pl=1;
function ifr() {
if (pl=1) {
document.location.reload([true]);
alert("Page Reloaded!");
change=1;
return change;
}
change+pl;
}
So basically it uses the document.location.reload which works to reload the page. I'm trying to then make pl change to something other than 1 so the function doesnt run again. I've been calling this JS from the body with onLoad.
All the leads on this went dead, but I did find a code snippet that worked. Not written by me, and I don't remember where it came from. Just posting to help someone should they ever have the same question.
<div class="overlay-content"> //Content container needed for CSS Styling
<div id="Reloader">
//iFrame will be reloaded into this div
</div>
//Script to reload the iframe when the page loads
<script>
function aboutReload() {
$("#Reloader").html('<iframe id="Reloader" height="355px" width="830px" scrolling="no" frameborder="0" src="about.html"></iframe>');
}
</script>
</div>
Basically just loads the iFrame source when the window with the iFrame opens, as opposed to the iFrame loading when the original page loads.
Beyond the scope of the original question, however this jQuery snippit works with cross domain iframe elements where the contentDocument.location.reload(true) method won't due to sandboxing.
//assumes 'this' is the iframe you want to reload.
$(this).replaceWith($(this).clone()); //Force a reload
Basically it replaces the whole iframe element with a copy of itself. We're using it to force resize embedded 3rd party "dumb" widgets like video players that don't notice when their size changes.
On the iframe element itself, set an onload:
iframe.onload = function() {this.contentWindow.location.reload(); this.onload = null;};
(Only works if the iframe's location is in the same domain as the main page)
Here's a complete solution to the original question:
<iframe onload="reloadOnce(this)" src="test2.html"></iframe>
<script>
var iframeLoadCount = 0;
function reloadOnce(iframe) {
iframeLoadCount ++;
if (iframeLoadCount <= 1) {
iframe.contentWindow.location.reload();
console.log("reload()");
}
}
</script>
The updated question is not really clear (what's "the link to the iFrame" and where is it in your snippet?), but you have a few issues with the code:
"calling this JS from the body with onLoad", assuming you mean an iframe's body, means the variable you're hoping to use to avoid infinite reloading will get clobbered along with the rest of the iframe's page when it's reloaded. You need to either load a slightly different URL in the iframe (and check the URL on iframe's onload before reloading) or put the flag variable in the outer page (and access it with parent.variableName - that should work I think)
if (pl=1) { should use ==, as = is always an assignment.
change+pl; has no effect.

Telling when an iframe is on a new URL

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.

Categories