Distinguish onbeforeunload for File Download vs Page Change

I have an onbeforeunload event that's supposed to get triggered any time a user goes to a new page. It works well enough, but I've found that it also gets triggered in Chrome any time a user downloads a file from the page they're on.

I'd like to be able to tell if the event is getting fired because it's being triggered by a file download. What's the best way to do that?

EDIT: As a clarification, I don't own the site that I'm listening to onbeforeunload on. The event is listened to by a Javascript snippet that's being installed on 3rd party sites.

Answers:

Answer

A javascript work around

That's the only "clean" work around I could think of & it seems to work just fine.


Some more code in your question showing how you actually use the "onbeforeunload" would be great.

But I will assume you are using something like the code below for the cursor "loading..." animation.

/* Loading Progress Cursor
 * 
 * Tested on:    IE8, IE11, Chrome 37, & Firefox 31
 * 
 * [1] the wildcard selector is not performant but unavoidable in this case
 */ 
.cursor-loading-progress,
.cursor-loading-progress * { /* [1] */
  cursor: progress !important;
}

The solution

1st step:

/* hooking the relevant form button
 * on submit we simply add a 'data-showprogresscursor' with value 'no' to the html tag
 */
$(".js-btn-download").on('submit', function(event) {
    $('html').data('showprogresscursor', 'no' );
});

2nd step:

/* [1] when page is about to be unloaded
 * [4] here we have a mechanism that allows to disable this "cursor loading..." animation on demand, this is to cover corner cases (ie. data download triggers 'beforeunload')
 * [4a] default to 'yes' if attribute not present, not using true because of jQuery's .data() auto casting
 * [4b] reset to default value ('yes'), so default behavior restarted from then on
 */
var pageUnloadOrAjaxRequestInProgress = function() {
    /* [4] */
    var showprogresscursor = $('html').data('showprogresscursor') || 'yes';  /* [4a] */
    if( showprogresscursor === 'yes' ){
        $('html').addClass('cursor-loading-progress');
    }
    else {
        $('html').data('showprogresscursor', 'yes' );  /* [4b] */
    }
}

$( window ).on('beforeunload', function() {    /* [1] */
    pageUnloadOrAjaxRequestInProgress();
});

Note that I use $('html').addClass('cursor-loading-progress'); as this is the expected CSS in my example but you can just do anything you like at this point.


Another couple of work arounds could be:

  • To open the file download page in a new tab
  • To trigger a page refresh once the file download is done
Answer

If you add download="[FILENAME]" to the a tag, it seems to prevent onbeforeunload from firing:

<a download="myfile.jpg" href="mysite.com">click me</a>

This is a much simpler solution. You can leave off the filename and just say 'download' to use the default filename. Let me point out this has the side effect of forcing redownload instead of using cache. I think this was added to chrome and ff in 2012. Not sure about safari or ie support.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.