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

Моя цель - вызвать окно сообщения, только если пользователь нажимает кнопку закрытия (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;
};
3
Youssef 20 Мар 2011 в 10:12
Какая версия ФФ. Я вставил ваш код на пустую html-страницу, и он отлично работает в FF Mac OS X 3.6.13.
 – 
Martin Algesten
20 Мар 2011 в 10:46
@Martin, вот моя версия: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.15) Gecko/20110303 Firefox/3.6.15. Я протестировал его в Chrome 10.0.648.133, и он тоже не работает.
 – 
Youssef
20 Мар 2011 в 10:56
1
Наполовину связанное с этим замечание: очень ли важно сообщение для пользователя? Я нахожу это довольно отвлекающим, когда получаю всплывающие окна, когда пытаюсь покинуть страницу.
 – 
Chimmy
20 Мар 2011 в 10:56
1
Если мы предположим, что сообщение не важно, каким будет решение для запуска вызова сеанса уничтожения Ajax только в том случае, если пользователь нажимает кнопку «Закрыть» (X)?
 – 
Youssef
20 Мар 2011 в 10:59
 – 
KimKha
6 Май 2011 в 11:54

1 ответ

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

Помимо этого, вы можете использовать различные специальные способы отслеживания действий мыши и клавиатуры до того, как пользователь попытается выгрузить страницу. Например, вы можете отслеживать, когда пользователь перетаскивает мышь по диагонали вправо — это, вероятно, означает, что он собирается закрыть окно/вкладку, так что сохраните сообщение. По диагонали вверх влево — это, вероятно, означает, что он только собирается нажать кнопки «назад вперед» или, может быть, ввести что-то в адресное поле. Если вы настроены серьезно, изучите, как люди перемещают курсор, и сопоставьте это с тем, собираются ли они закрыть страницу или сделать что-то «разрешенное». Опять же, на 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> 
1
nitro2k01 20 Мар 2011 в 11:40