Обнаружение события закрытия окна в Firefox - PullRequest
3 голосов
/ 20 марта 2011

Я знаю, что это очень часто задаваемый вопрос, но, поверьте мне, я не могу найти ответ через Интернет.

Моя цель - вызвать окно сообщения, только если пользователь нажимает кнопку закрытия (X). Пользователь продолжает получать окно сообщения, если он нажимает кнопку «назад / вперед», а также, если он использует F5, CTRL + R, ...

Я не хочу связывать какие-либо другие действия, кроме щелчка по кнопке закрытия окна, поскольку за ним будет происходить уничтожение сеанса с Ajax. Поэтому недопустимо прерывать сеанс, если пользователь нажимает кнопку F5.

Вот мой код. Для информации я знаю, что в IE есть способ проверить объект события clientY, но это не работает в Firefox.

$("a").click(function () {
window.onbeforeunload = null;
});

window.onbeforeunload = function (e) {
var closewindowmessage="If you leave this page, your session will be definitely closed.";

  e = e || window.event;
  // For IE and Firefox
  if (e) {
    e.returnValue = closewindowmessage;
  }

  // For Safari
  return closewindowmessage;
};

1 Ответ

1 голос
/ 20 марта 2011

Нет определенного способа определить, почему / как страница выгружается.Вы могли бы перестроить свой сайт, чтобы использовать теперь очень популярный метод «привязки», который хранит данные в привязке HTML, например http://www.example.com/page#something=something.. Это, по крайней мере, обычно решает проблему с кнопками назад / вперед, но не тогда, когдапользователь перезагружает страницу.

Кроме этого, вы можете использовать различные ad hoc способы отслеживания действий мыши и клавиатуры до того, как пользователь попытается выгрузить страницу.Например, вы можете отследить, когда пользователь перетаскивает мышь по диагонали вправо - это, вероятно, означает, что он собирается закрыть окно / вкладку, поэтому сохраняйте сообщение.По диагонали вверх налево - это, вероятно, означает, что он просто собирается нажать кнопки «назад» вперед или, возможно, ввести что-то в поле адреса.Если вы действительно серьезны, проведите исследование того, как люди перемещают курсор, и сопоставьте это с тем, собираются ли они закрыть страницу или делают что-то «разрешенное».С другой стороны, на Mac кнопка закрытия находится в верхнем левом углу окна.И так далее.Это все еще будут лучшие предположения.

Вы также можете отслеживать движения мыши вверх и показывать большое красное сообщение в окне просмотра браузера (не всплывающее окно / предупреждение), чтобы предупредить пользователя, прежде чем он даже подумывает покинуть страницу..

Отслеживание событий клавиатуры немного более детерминировано, но все же требует некоторых кросс-браузерных и платформенных исследований.Я оставляю вас с этим кодом, который, я надеюсь, может послужить образцом.Он регистрирует нажатия клавиш и подавляет сообщение, если нажата клавиша F5 или Apple + R (Mac).В противном случае будет показано сообщение, содержащее список всех зарегистрированных нажатий клавиш.

Анализ требует тестирования и расширения;это было проверено только на Firefox Mac.Одна ошибка, на которую я сразу могу указать, заключается в том, что если вы нажмете Apple + R, R, вы все равно получите запрос, потому что экземпляр второй страницы никогда не записывал какое-либо событие нажатия клавиши для клавиши Apple - только для клавиши R.Также произойдет сбой, если пользователь нажмет что-то промежуточное, например, Apple + L, R.Возможно, вам будет достаточно просто проверить, была ли последняя нажатая клавиша R.

<script>
// Create an empty array.
window.keys = [];

// Log every key press
window.onkeydown = function (e) {
  var evt = window.event || e;

  var keyCode = e.keyCode || e.which;

  window.keys.push(keyCode)

}

function analyzeKeyPresses(){
  keys.reverse();   // Reverse the array so it's easier to handle.
  var doBlock = true;

  // Here we only apply certain checks if there are enough keys in the array. Don't want a JS error...
  switch(window.keys.length){
    case 0:
      doBlock = true;  // Redundant. If there are no key presses logged, assume we should prompt the user.
      break;
    default: // Two or more key presses logged.
      if(keys[0] == 82 && keys[1] == 224) doBlock = false;  // User pressed apple+r on a Mac - don't prompt!
      if(keys[0] == 82 && keys[1] == 17)  doBlock = false;  // User pressed ctrl+r on Windovs (untested) - don't prompt!

      // Note: No break! Intentional fall-through! We still want to check for F5!
    case 1:  // One or more key presses logged.
      if(keys[0] == 116) doBlock = false;   // User pressed F5 - don't prompt!
  }

  keys.reverse();   // Un-reverse the array in case we need to use it again. (Easier to read...)
  return doBlock;
}

window.onbeforeunload = function (e) {
  var closewindowmessage=window.keys.join(" ");

  var blockUnload = analyzeKeyPresses();

  if(blockUnload){
    e = e || window.event;
    // For IE and Firefox
    if (e) {
      e.returnValue = closewindowmessage;
    }

    // For Safari
    return closewindowmessage;
  }
};

</script>
<a href="#1">1</a> <a href="#2">2</a> 
...