21

Rewriting the question -

I am trying to make a page on which if user leave the page (either to other link/website or closing window/tab) I want to show the onbeforeunload handeler saying we have a great offer for you? and if user choose to leave the page it should do the normal propogation but if he choose to stay on the page I need him to redirect it to offer page redirection is important, no compromise. For testing lets redirect to google.com

I made a program as follows -

var stayonthis = true;
  var a;
  function load() {
   window.onbeforeunload = function(e) {
        if(stayonthis){
         a = setTimeout('window.location.href="http://google.com";',100);
         stayonthis = false;    
         return "Do you really want to leave now?";
        }
        else {
            clearTimeout(a);
        }

    };
    window.onunload = function(e) {
         clearTimeout(a);
    };
  }
  window.onload = load;

but the problem is that if he click on the link to yahoo.com and choose to leave the page he is not going to yahoo but to google instead :(

Help Me !! Thanks in Advance

here is the fiddle code

here how you can test because onbeforeunload does not work on iframe well

Rohit Agrawal
  • 5,372
  • 5
  • 19
  • 30
  • 18
    Users hate this. If they do not want to leave, they will not change the URL or close the tab. Why do you want to annoy them? – George Cummins May 22 '13 at 15:37
  • i know but its for learning purpose not for real project as ux – Rohit Agrawal May 22 '13 at 15:40
  • 4
    @GeorgeCummins The "confirm navigation" dialogue is welcome in some applications. In Google Docs, for instance, if the user tries to navigate before an auto-save can complete. I, for one, prefer to be bothered by a "confirm navigation" dialogue than to lose my work. – svidgen May 22 '13 at 16:50
  • 1
    @RohitAgrawal I'm really confused by this particular question though. If the user chooses to stay ... why send them somewhere else? (You're not working for Google, are you??) – svidgen May 22 '13 at 16:52
  • it can be any link someone from my site or any promotion page, the msg can be do you want to see an offer, stay on the page can take him to that offer page and leave should work normally – Rohit Agrawal May 22 '13 at 20:30
  • @all question updated – Rohit Agrawal May 23 '13 at 20:08
  • in firefox, you cannot set a custom message for obeforeunload dialog – A. Wolff May 29 '13 at 20:39
  • @roasted its ok with me but the rest should be done, I am unable to create logic for that – Rohit Agrawal May 29 '13 at 20:41

6 Answers6

8

This solution works in all cases, using back browser button, setting new url in address bar or use links. What i have found is that triggering onbeforeunload handler doesn't show the dialog attached to onbeforeunload handler. In this case (when triggering is needed), use a confirm box to show the user message. This workaround is tested in chrome/firefox and IE (7 to 10)

http://jsfiddle.net/W3vUB/4/show

http://jsfiddle.net/W3vUB/4/

EDIT: set DEMO on codepen, apparently jsFiddle doesn't like this snippet(?!) BTW, using bing.com due to google not allowing no more content being displayed inside iframe.

http://codepen.io/anon/pen/dYKKbZ

var a, b = false,
    c = "http://bing.com";

function triggerEvent(el, type) {
    if ((el[type] || false) && typeof el[type] == 'function') {
        el[type](el);
    }
}

$(function () {
    $('a:not([href^=#])').on('click', function (e) {
        e.preventDefault();
        if (confirm("Do you really want to leave now?")) c = this.href;


        triggerEvent(window, 'onbeforeunload');

    });
});

window.onbeforeunload = function (e) {
    if (b) return;
    a = setTimeout(function () {
        b = true;
        window.location.href = c;
        c = "http://bing.com";
        console.log(c);
    }, 500);
    return "Do you really want to leave now?";
}
window.onunload = function () {
    clearTimeout(a);
}
A. Wolff
  • 74,033
  • 9
  • 94
  • 155
  • clicking tryit and then leave the page should goto yahoo but its going to google – Rohit Agrawal May 29 '13 at 21:47
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/30899/discussion-between-rohit-agrawal-and-roasted) – Rohit Agrawal May 30 '13 at 11:20
  • Note that Firefox doesn't show custom message for onbeforeunload dialog. It always displays the default message. – Pavel Strakhov Jun 04 '13 at 06:26
  • @Riateche True! OP told this was not a problem for him. See comments in question. – A. Wolff Jun 04 '13 at 08:34
  • how can i perform function on leave the page button every thing is all fine but how can i fire up an event on leave the page button – Vicky Jun 24 '15 at 14:09
  • Hi @A.Wolff: Thanks for the code. Can i implement it on 'Leave page' instead of 'Leave Page' button? Which all changes i have to do? Can you please guide.. – shivshankar Jul 03 '15 at 10:37
  • @dirtyhandsphp I'm sorry, i'm not sure to understand your question§. Anyway, instead of asking question in comment, you have to post a new question on SO regarding your expected behaviour – A. Wolff Jul 03 '15 at 13:17
  • Hi @A.Wolff: Please check here: http://stackoverflow.com/questions/31239804/using-onbeforeunload-event-url-change-on-leave-page – shivshankar Jul 06 '15 at 07:17
2

It's better to Check it local.
Check out the comments and try this: LIVE DEMO

var linkClick=false; 
document.onclick = function(e)
{
    linkClick = true;
    var elemntTagName = e.target.tagName;
    if(elemntTagName=='A')
    {
        e.target.getAttribute("href");
        if(!confirm('Are your sure you want to leave?'))
        {
           window.location.href = "http://google.com";
           console.log("http://google.com");
        }
        else
        {
            window.location.href = e.target.getAttribute("href");
            console.log(e.target.getAttribute("href"));
        }
        return false;
    }
}
function OnBeforeUnLoad () 
{
    return "Are you sure?";
    linkClick=false; 
    window.location.href = "http://google.com";
    console.log("http://google.com");
}

And change your html code to this:

<body onbeforeunload="if(linkClick == false) {return OnBeforeUnLoad()}">
    <a href="http://yahoo.com">try it</a>
</body>
Siamak Motlagh
  • 5,028
  • 7
  • 41
  • 65
1

After playing a while with this problem I did the following. It seems to work but it's not very reliable. The biggest issue is that the timed out function needs to bridge a large enough timespan for the browser to make a connection to the url in the link's href attribute.

jsfiddle to demonstrate. I used bing.com instead of google.com because of X-Frame-Options: SAMEORIGIN

var F = function(){}; // empty function
var offerUrl = 'http://bing.com';
var url;


var handler = function(e) {
    timeout = setTimeout(function () {
        console.log('location.assign');
        location.assign(offerUrl);

    /*
     * This value makes or breaks it.
     * You need enough time so the browser can make the connection to
     * the clicked links href else it will still redirect to the offer url.
     */
    }, 1400);

    // important!
    window.onbeforeunload = F;

    console.info('handler');
    return 'Do you wan\'t to leave now?';
};

window.onbeforeunload = handler;
Bart
  • 17,070
  • 5
  • 61
  • 80
  • clicking on try it and then leave the page goes to bing.com instead of yahoo.com – Rohit Agrawal May 30 '13 at 07:48
  • That the unreliable part :-) You'll need to play with the timeout milliseconds to get a correct result. `1400` worked for me but maybe you need to set it to a higher value. – Bart May 30 '13 at 07:51
  • so that the same what i already did, i need to solve that and for higher values if choose to stay on page , it will go later to bing.com – Rohit Agrawal May 30 '13 at 07:52
0

Try the following, (adds a global function that checks the state all the time though).

var redirected=false;
$(window).bind('beforeunload', function(e){
    if(redirected)
        return;
    var orgLoc=window.location.href;
    $(window).bind('focus.unloadev',function(e){
        if(redirected==true)
            return;
        $(window).unbind('focus.unloadev');
        window.setTimeout(function(){
            if(window.location.href!=orgLoc)
                return;
            console.log('redirect...');
            window.location.replace('http://google.com');
        },6000);
        redirected=true;
    });
    console.log('before2'); 
    return "okdoky2";
});

$(window).unload(function(e){console.log('unloading...');redirected=true;});
WhyMe
  • 535
  • 2
  • 13
  • didnt worked ,I used you code http://jsfiddle.net/pb7th/20/show/ click on the try it and say leave the page will lead to the google.com instead of the link url :( – Rohit Agrawal Jun 05 '13 at 09:15
  • still the same error i clicked on try it then leave the page it should go to yahoo.com but instead going to google.com – Rohit Agrawal Jun 05 '13 at 13:51
  • It was a timing issue. I rewrote the whole thing.. in jquery. Hope that helps now it works for me every time... you can change the time to wait for 10 secs, and would probably allow it to be more rubust... http://jsfiddle.net/pb7th/41/ – WhyMe Jun 05 '13 at 16:07
  • if u increase the time a lot then clicking on try it and a click on stay on the page will go to google after 10 sec, so use will think that there no action to perform, same problem which i was initially having related to timer – Rohit Agrawal Jun 06 '13 at 05:51
  • You can just add an indicator on the screen, that will say "redirect in... secs.." and it is true in any case. (Close and all). Hope that helps. – WhyMe Jun 06 '13 at 07:20
-1
<script>
        function endSession() {
            // Browser or Broswer tab is closed
            // Write code here
            alert('Browser or Broswer tab closed');
        }
</script>

<body onpagehide="endSession();">
Raidri
  • 17,258
  • 9
  • 62
  • 65
Tareq
  • 1
-2

I think you're confused about the progress of events, on before unload the page is still interacting, the return method is like a shortcut for return "confirm()", the return of the confirm however cannot be handled at all, so you can not really investigate the response of the user and decide upon it which way to go, the response is going to be immediately carried out as "yes" leave page, or "no" don't leave page...

Notice that you have already changed the source of the url to Google before you prompt user, this action, cannot be undone... unless maybe, you can setimeout to something like 5 seconds (but then if the user isn't quick enough it won't pick up his answer)

Edit: I've just made it a 5000 time lapse and it always goes to Yahoo! Never picks up the google change at all.

Ayyash
  • 4,257
  • 9
  • 39
  • 58
  • I didn't say it can't be done... but anyway your solution when i click Internal, nothing happens... the other link is a simple click event, which isn't what the question was about. – Ayyash Jun 05 '13 at 10:39
  • internal link point to div element (bottom of same page), it is an internal link using hash '#'. It is just there to prove you can still use internal links. If you click on link 'try it' you'll see this is exactly what OP is looking for... – A. Wolff Jun 05 '13 at 10:44
  • mmm, if the question was about handling a simple click then why use "onbeforeunload" at all? your example really, really mate, does nothing when i click internal. – Ayyash Jun 05 '13 at 10:50
  • http://jsfiddle.net/W3vUB/4/show/ Hope it will be more easy to understand now... – A. Wolff Jun 05 '13 at 11:02
  • I think i understand my mix-up, I use 1900px resolution, so the internal link really, really did nothing :) anyways, what you did is divide the problem into two separate parts and treated links differently from browser closing, which is pretty smart, but I thought the asker was doing it for research purposes to see if it is at all doable. – Ayyash Jun 06 '13 at 07:28
  • Ok, i understand it better your internal link behaviour :) Thx for the input – A. Wolff Jun 06 '13 at 08:28