Frage

In einem Web-App arbeite ich an, ich bin onBeforeUnload Erfassung der Benutzer zu fragen, ob er wirklich will verlassen.

Nun, wenn er zu bleiben entscheidet, gibt es eine Reihe von Dingen Ich mag würde zu tun. Was ich versuche, herauszufinden, dass er wählte, um tatsächlich zu bleiben.

Ich kann natürlich eine SetTimeout für „x“ Sekunden erklärt, und wenn das feuert, dann würde es bedeuten, der Benutzer immer noch da ist (weil wir nicht bekommen entladen haben). Das Problem ist, dass der Benutzer eine beliebige Zeit in Anspruch nehmen kann, um zu entscheiden, ob sie bleiben oder nicht ...

ich zuerst hatte gehofft, dass während der Dialog wurde zeigt, SetTimeout Anrufe nicht feuern würde, so konnte ich ein Timeout für eine kurze Zeit, und es würde nur Brand gesetzt, wenn der Benutzer bleiben wollte. Allerdings Timeouts Feuer, während der Dialog angezeigt wird, so dass nicht funktioniert.

Eine weitere Idee, die ich versuchte, ist mouseMoves auf dem Fenster / Dokument zu erfassen. Während der Dialog angezeigt wird, in der Tat mouseMoves nicht ausgelöst, bis auf eine seltsame Ausnahme, die zu meinem Fall wirklich gilt, so dass auch nicht funktionieren.

Kann jemand denkt andere Art und Weise, dies zu tun?

Danke!


(Falls Sie neugierig sind, der Grund, die Erfassung nicht mouse ist nicht funktioniert, dass ich einen IFrame in meiner Seite haben, eine Seite aus einer anderen Domäne enthält. Wenn zum Zeitpunkt der Seite Entladen der Schwerpunkt innerhalb der ist IFrame, während der Dialog zeigt, dann bekomme ich das Mousemove-Ereignis feuern ONCE, wenn die Maus bewegt sich aus dem Inneren des IFrame nach außen (zumindest in Firefox). das ist wahrscheinlich ein Fehler, aber immer noch, es ist sehr wahrscheinlich, dass passieren wird in unserem Fall, so kann ich diese Methode nicht verwenden).

War es hilfreich?

Lösung

Was ich am Ende tun war für mein Dokument in das Click-Ereignis Einhaken, und sobald ich einen Klick erhielt als ich den Benutzer geblieben war.

Es ist keine gute Lösung, in den meisten Fällen (wenn Sie eine DiggBar sind) finden Sie viele falsch-negative Ergebnisse haben (Leute übernachtet haben wird, und Sie werden wissen, dass es nie), aber in unserem Fall machte es durchaus Sinn, weil die Menschen interagieren stark mit unserer Seite, nicht nur mit den gerahmten Seiten.

esentially, mein Code tut dies ...

function OnBeforeUnload() {
    Event.observe(document, "click", UserStayed);
    if (IConsiderTheIFrameMightBeTryingToPopOut) {
        return "The site is trying to escape. Do you want to stay?";
    }
}

function UserStayed() {
Event.stopObserving(document, "click", UserStayed);
    // New we know the user is still with us for sure.
}

Andere Tipps

Ich habe diese Frage online in den letzten Tage und die Antwort der Erforschung, immer, „nein“ Sie nicht, mit Sicherheit sagen können, dass ein Benutzer geblieben oder links (außer der Tatsache, dass Ihre Anwendung beendet arbeiten, wenn die Benutzer Blätter). Ich hasse „nein“ antwortet. Ich kam mit dem folgenden Nutzen auf.

var OnBeforeUnload = (function(){
    var
    FDUM = new Function,
    AFFIRM = function(){ return true; };

    var _reg = function(msg,opts){
        opts = opts || {};
        var
            pid = null,
            pre = typeof opts.prefire == 'function' ? opts.prefire : FDUM,
            callback = typeof opts.callback == 'function' ? opts.callback : FDUM,
            condition = typeof opts.condition == 'function' ? opts.condition : AFFIRM;

        window.onbeforeunload = function(){
            return condition() ? (pre(),setTimeout(function(){ pid = setTimeout(callback,20); },1),msg) : void 0; 
        }

        window.onunload = function(){ clearTimeout(pid); };

    }

    var _unreg = function(){ window.onbeforeunload = null;  }

    return {
        register : _reg,
        unregister : _unreg
    };

})();

So ein Anruf wie

OnBeforeUnload.register('Hello!',{ 
    condition:function_that_returns_true_to_fire_event_false_to_ignore,
    prefire:function_to_call_on_page_exit_attempt, 
    callback:function_to_call_if_user_stays
});

wird Bedingung innerhalb der Handler aufgerufen werden, um zu sehen, ob es aktivieren soll oder nicht. Wenn ja, wird ausgeführt Vorausstoßen vor dem Popup dem Benutzer angezeigt wird (vielleicht möchten Sie ein Video pausieren) und Rückruf wird nur auftreten, wenn der Benutzer bleibt.

Meine Logik war einen setTimeout im Körper der Event-Handler zu initiieren. Die setTimeout wird nicht ausgeführt, bis der Benutzer eine der Tasten drückt. Nachdem sie das tun, feuert es sofort. Die SetTimeout in diesem Fall nicht den Rückruf nennen, aber eine Proxy-Funktion, die eine andere Zeitüberschreitung für den Rückruf mit einer Verzögerung von 20 ms ausgeführt wird. Wenn der Benutzer auf der Seite bleibt, führt der Rückruf. Wenn nicht, dann wird ein anderer Handler onUnload angebracht, die das Timeout löscht, die den Rückruf rufen, um sicherzustellen, dass der Rückruf nie aufgerufen. Ich hatte nur die Chance, es zu überprüfen, in Firefox, IE und Chrome, aber es hat in allen drei ohne Stottern bisher gearbeitet haben.

Ich hoffe, diese Menschen so frustriert hilft, wie ich durch das Patent „nein“ allgemein auf diese Frage war. Dieser Code kann nicht perfekt sein, aber ich denke, es ist auf dem richtigen Weg.

Dies ist der Top-Hit für diese Art von Frage, und ich kenne den konkreten Fall (ab 8 Jahren) könnte diese Lösung nicht verwenden, da es in einem iFrame, aber alle zukünftigen Ankömmlinge werden wahrscheinlich mehr geholfen werden durch die Antwort unten als oben:

Sie können ganz einfach sagen, wenn sie mit einem Body-Ereignis-Listener übernachtet habe, denke ich mousemove- und keyDown sollte genug kombiniert werden.

sagen, ob sie nach links, Sie gehen einige Server-Seite Sachen müssen.

Alles in allem, es in etwa so aussehen werde (Sie werden in den Ajax-Aufrufe an den Server selbst füllen)

window.addEventListener("beforeunload", function(event){
    //tell your server they are attempting to leave
    var tryLeaveID = serverLogAttempToLeave();

    //an element with giant letters and warning text, because you can no longer set text on the alert box
    var unsavedWarning = document.getElementById("unsavedChangesWarning");
    unsavedWarning.style.display = "block";

    var onStay = function() {
        //if they stay, tell your server so
        serverRevokeAttemptToLeave(tryLeaveID);
        unsavedWarning.style.display = "none";
        document.body.removeEventListener("mousemove", onStay);
        document.body.removeEventListener("keydown", onStay);
    }

    document.body.addEventListener("mousemove", onStay);
    document.body.addEventListener("keydown", onStay);


    var dialogText =  "undisplayed text";
    event.returnValue = dialogText;
    return dialogText;
});

Auf der Serverseite, wirst du etwas hässlich, einen Timer zu verwenden haben. Machen Sie einen Stapel von Versuchen zu verlassen, und entfernen Sie sie entweder als auf Aufenthalt auf Wunsch oder nach einer Minute oder so als bestätigter lassen. Ich kann keinen Fall vorstellen, wo zu wissen, ob der Benutzer links mehr Zeit empfindlich als ein paar Minuten, aber wenn Sie eine haben, bitte kommentieren, weil ich darüber nachdenken möchte.

Warum nicht einfach die Methode verwenden, die Stackoverflow tut, wo Sie ein Popup-Fenster, die Sie die Wahl treffen können:

  

Sind Sie sicher, dass Sie von dieser Seite weg navigieren?

     

Sie haben damit begonnen, zu schreiben oder bearbeiten Post.

     

Klicken Sie auf OK, um fortzufahren, oder Abbrechen auf der aktuellen Seite bleiben

Dann spielt es keine Rolle, wie lange sie dauern. Wenn sie einen Knopf klicken, sie zu verlassen. Wenn sie die anderen klicken, sie bleiben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top