A way to determine file is loaded in iframe - javascript

I've got a problem: I would like to catch a moment when the Save File dialog is closed or my csv file generated on the server is loaded (to hide a spinner for loading). I know there is no such event in the Javascript. I definitely don't want to add cookies for such a minor issue on the backend so I would like to implement another workaround. The only way out I see is iframe but as far as I can see event listeners like onload doesn't work in case of attachment header in Chrome at least. I've also tried to implement a kind of timer checking for iframe status but it worked right after request for file was sent. File is generated on server in some seconds (10-20) so this solution doesn't fit my goals.
I'm using Angular on the frontend so any solution compatible (vanilla JS, jQuery, Angular itself) will be a great help for me. Hope to get any. Thank you, guys!

There is no DOM event, which am aware of here, which is fired when Save file UI dialog is opened or closed.
You can try utilizing focus event to catch when the Save file dialog is closed and window regains focus after calling .click() on <a> element having download attribute set, though the approach is not completely reliable.
// append or display spinner element here
var csvUrl = document.createElement("a");
csvUrl.href = url;
csvUrl.download = "csv_filename";
csvUrl.click();
window.onfocus = function () {
document.body.removeChild(csvUrl);
// remove or hide spinner element here
window.onfocus = null;
}

Related

Firefox Addon How to cannot access browser page DOM from the Popup JS?

HiI am trying to develop small simple popup extension in Firefox, I am new to the Firefox extension development Framework.
I used this boilerplate to speed up this process
I Added a small button to the popup with an id = testid1 by overriding the popup.html file and adding this line
<a id="testid1" href="#" class="js-options">Test</a>
I added it the corresponding EventListener by overriding the popup.addEventListener in the popup.js file
popup.addEventListener("click", function (e) {
if (e.target && e.target.matches("#testid1 ")) {
var element_from_popup_html = document.getElementById("elementid1").value;
var element_from_web_page = document.getElementById("elementid2").value;
alert('it work');
}}
I made sure that this event lister triggers correctly and is working by using an Alert.
I am trying to get 2 elements from the DOM Element1(inside popup page), and Element2(Fromthe webbrowser)
I can't get the : element_from_web_page!!
and I have document.getElementById("elementid2") is NULL.
So After digging some more the : document here is the popup.html, How am I supposed to access this webbrowser browsed page. I used to use document keyword for this!!
Also found out that I can use the Javascript API from mozilla by using _ext2.default.and_put_the_chosen_api_here but I only need simple dom find by id?
I managed to solve my problem after reading some more about the Firefox Extensions. So basically what I was doing is managing the popup document not the webpage. In order to interact with the webbrowser current page I needed to change another type of js called a content script, which is different from the popup.js javascript file(similar to the background script) that I was editing.
So basically I had to use the communication between the background and content-script with regards to the documentation.
On the content_script.js , I interacted with the web-page using some eval function.

Triggering multiple individual JavaScript functions via URL without a page refresh

I'm building a simple webapp using NFC(near field communication), which involved certain tags being programmed with the URL of my website + a hash that will trigger a specific JavaScript function.
For example, "www.website.com/index.html#hide/one" will hide the element labeled "one" on the webpage. Simple enough, right? I thought it would be.
I've since learned that when you tap an NFC tag, it opens the URL in a new webpage/tab. I think this could be averted if my webpage checked to see if there are any other open pages and closes them, though.
If there's a better way to do this(trigger JavaScript functions on a webpage via a URL to that webpage), please let me know. It's important to note that there are 8 tags(elements) in total, and they all have to be triggered for the game/app to end, which requires it all to be done on the same page, preferably without refreshes(although I could probably rig something up using localstorage so it could be refreshed).
Thanks in advance, I'm just not sure how I would proceed here.
-Mitchyl
EDIT - I should mention that I already am using backbone.js for my routing needs. It's perfect for my situation at the moment,
What you need is a hash tag routing libary. http://projects.jga.me/routie/
This will run when your app page loads and read the hash, diverting the logic of your code to do something based on the hash tag, thus you make your items remove on the page in your code logic. No need for lots of pages.
But!
If the url launcher on the device launches new windows each time an item is detected, that is a problem since you can't close those windows, other than from the window itself.
Solution
The app has a main window for the game, each item is stored in local storage, You can use the local storage event system to detect if another page changes an item, and update the UI in real-time.
addEvent(window, 'storage', function (event) {
if (event.key == 'item1') {
item1.innerHTML = event.newValue;
}
});
When NFC launches a new window, display user feedback that states they have completed a task of the game then close it using a timeout.
Below that window will be the main page window with the update displayed.
Done properly it will work brilliantly. You can also add a nice x close button on the pop windows as tasks are completed.

Hidden iframe onload event

I've seen some similar issues on here regarding the iframe onload, but nothing is working for me.
I have a hidden iframe that I use only for users to download a PDF that is dynamically created on my server. When the user clicks a button, the PDF is created on my server by pointing to a controller/action along with a query string of parameters.
This works great. However, I show a spinner and disable the UI when they press this button (BlockAndSpin function). I want to turn the hide the spinner and re-enable the UI when the PDF has been downloaded.
My onload method is never hit when I debug in Chrome and Firefox. I also tried to add the onload attribute to the iframe itself, and that didn't work either. The file downloads, but the UI stays the same and the onload event doesn't fire.
js
function downloadPOS(id) {
var ifrm = document.getElementById(id)
BlockAndSpin(true);
ifrm.src = "/staticPOS/AddOrDownload" + GetPosQueryString();
ifrm.onload = function () {
BlockAndSpin(false);
}
}
html
<iframe id="dlFrame" onload="BlockAndSpin(false);" style="display: none"></iframe>
Apparently this can't be done. My response is a .pdf being downloaded by the user and not loading anything into the iframe itself, thusly it never fires the event. I'll have to revisit how this is done.
I ran into a similar issue attaching to messages on a hidden iframe. IE does not seem to like cross domain communication with "hidden" (display:none) iframes.
My workaround was to set the iframe to an absolute position with a left value of -9999px. Then it's effectively hidden and you can attach to it.

Does changing the src attribute of an image stop the image from downloading?

Let's say that I have two accordion tabs. The first one loads hundreds of images and is open when the page loads.
I want to be able to stop the images from downloading if the user clicks on the second accordion tab. Will changing the src attributes of the images via js stop the images from downloading? Or do the requests just continue until completion and not show up on the page?
I have a script that loads the SO logo in exactly 3 seconds that I had made for another question.
http://alexturpin.net/slowimage/slowimage.php
Using it, I tried to reproduce the problem:
var img = new Image();
img.onload = function() {
alert("loaded");
};
img.src ="http://alexturpin.net/slowimage/slowimage.php";
setTimeout(function() {
img.src = "";
}, 1000);
http://jsfiddle.net/Xeon06/RrUvd/1/
From what I gather, in Chrome, the onload doesn't get fired, but the browser keeps on showing a spinner and if I go on the network tab and find my image and check it's content, it's there. So my answer would be no, the image still loads, at least in Chrome.
This is an interesting problem, I suggest you try and test it in as many browsers as possible and write some kind of blog post on it.
Your browser asks for that image with a specific HTTP GET request, as
specificated in HTTP protocol. Once it asks for it, the http server
starts the transfer.
So, it is between the browser (as http client) and the http server.
Since http protocol does not takes into account the option to abort a
transfer, the browser should implement a out-of-standard mechanism to
programmatically abort the connection. But since this is not specified
in any standard, i think you won't find any way to do that with
javascript or any client side code.
You can try window.stop() to stop all requests, but not individual
ones.
If you wanted to stop a single request for a large image, what you
could do is load the image into a document within a hidden IFRAME. The
onload event of the IFRAME can be used to load the image into the main
document, by which time it ought to be cached (presuming you have the
caching directives configured to do so).
If the image is taking too long, then you can access the IFRAME's
contentWindow and issue a stop command to that.
You need to have as many IFRAME elements as there are images that can
be requested simultaneously.
Taken directly from here & here.
Not sure if it will, just like the other comments. But I can suggest am approach that will work well. Assuming not all the images are visible, just set the right src attribute when they become visible.
So default the url to myGray.gif when it is not visible and set it to myImage.jpg when it does come into view.
When you close the current accordion, you can set the image source back to your lightweight gif again. (this prevents a bug related with gc on some versions of the ipad).

Download binary without triggering onbeforeunload

I want to kick off a file download for a user when he clicks a link, but I have an onbeforeunload handler that I don't want to get invoked when the download begins. To downloads, I currently have an <a> with the href set to the file location but clicking it results in onbeforeunload being invoked in Chrome (not in FF, though).
I know I can set a private flag and check that in the onbeforeunload handler, but is there some way to kick off the download using ajax? I still want the user to see the usual dialogs when they download the file (Open/Save etc).
Ideas?
The best way to do this is indeed by constructing an iframe and triggering the download from there.
I have tested this in Chrome, IE6+ and Firefox and this approach seems to work in all of them.
Example code:
function DownloadFile(filePath) {
var downloadIframe = $('<iframe />',
{
id : 'downloadIframe'
}).appendTo('body');
downloadIframe.attr('src', filePath);
}
This will only work properly for a one off download (as we've hard coded an id), if you are triggering multiple downloads, then I suggest you reuse the iframe by storing it in a more widely accessible variable.
Add the download attribute to the a tag, which seems to prevent onbeforeunload from firing:
<a download href="mysite.com"></a>
From this answer.
I would guess using the target attribute on the link could do the trick.
download
Will not validate (unless using frameset doctype) but it might work.. It will create a new tab or window and then pop a file download (if the http header says it should), but it might leave the new tabs/windows open, or it might close them after saving...
On the other hand I think having a onbeforeunload handler that you sometimes do not want to trigger sounds suspicious, why do you need that anyway?
I know this answer is really late, but there's a simple solution. Create an iframe dynamically, and set the "src" of it to your download url via JavaScript. This'll kick off the download without triggering the unload event (I think).
The download attribute answer worked well for me, but before I noticed it, I tried this, which also works. Just in case it's useful in some other cases that aren't download links.
var linksThatDisableWarning = $('a'); // all links
linksThatDisableWarning.on('mousedown', () =>
window.isclicking = true);
linksThatDisableWarning.on('mouseup', () =>
setTimeout(() => window.isclicking = false, 200))
window.addEventListener('beforeunload', (event) => {
if (window.isclicking) return;
event.preventDefault();
event.returnValue = '';
});

Categories