Как я могу предотвратить окно.onbeforeunload от запуска javascript: ссылки href в IE?

Я создаю fail safe для моей формы, которая будет предупреждать пользователей, что если они покинут страницу, их данные формы будут потеряны (аналогично тому, что делает gmail).

window.onbeforeunload = function () {    
        if (formIsDirty) {
            return "You have unsaved data on this form. Don't leave!";
        }
}

вышеуказанная функция отлично работает в firefox, но в IE она запускается любой ссылкой href, даже теми, которые являются ссылками на javascript, а не на другие страницы.

например....

<a href='javascript:someFunction();'>click</a>

мне интересно, есть ли способ обойти это, так как я не хочу, чтобы пользователь думал, что они покидают страницу, когда они просто нажимают на нее кнопку. у меня нет возможности переписать все различные ссылки как они встроены и многочисленны.

какие идеи?

6 ответов


вы можете удалить и повторно назначить onbeforeunload при наведении на эти ссылки:

jQuery(
  function($)
  {
      //store onbeforeunload for later use
    $(window).data('beforeunload',window.onbeforeunload);  

      //remove||re-assign onbeforeunload on hover 
    $('a[href^="javascript:"]')
      .hover( 
             function(){window.onbeforeunload=null;},
             function(){window.onbeforeunload=$(window).data('beforeunload');}
            );

  }
);

Я просто столкнулся с подобной проблемой и нашел очень простое решение:

$("a").mousedown(function() {
    $(window).unbind();
});

это удалит событие onbeforeunload непосредственно перед запуском события click.


переместить любой скрипт в click обработчик событий вместо этого, с резервной страницей для пользователей без JavaScript:

<a href="foo.html" onclick="someFunction(); return false">click</a>

ненавязчивые чемпионы JS там, вероятно, будут возражать против использования onclick атрибут, но факт в том, что он работает, это самый простой способ добавить обработчик событий и самый простой способ предоставить пример. Для лучшего разделения проблем вы можете вместо этого использовать DOM0 onclick собственность addEventListener() / attachEvent() или в библиотеке.


Если вы включаете символ закладки в href тега a, вы все равно сможете использовать событие onclick для включения JavaScript.

<a href="#" onclick='someFunction();'>click</a>

Я запустил несколько тестов, и это, похоже, выполняет JavaScript без запуска события onbeforeunload. Мне было бы интересно узнать, работает ли это для других или у вас все еще есть та же проблема после реализации тегов таким образом.


(как и некоторые другие ответы, это требует изменения способа привязки JavaScript. Если это не сработает, не обращайте внимания.)

я обнаружил, что в IE 7 через IE 10, просто используя jQuery .нажмите () с помощью preventDefault работает, не показывая onbeforeunload сообщение (IE 11 не показывает beforeunload сообщение на любой из моих тестовых случаев). Это верно, независимо от того, является ли href " # " или javascript:void(0). Я ожидаю, что вывод выполняется, если attachEvent/addEventListener используется напрямую, но я не тестировал что.

есть демонстрация ниже в http://jsbin.com/tatufehe/1 . Обе версии (в зеленом цвете) с preventDefault работа (не показывать beforeunload диалог). Тот, что без preventDefault показывает это (в качестве сравнения).


$( document ).ready( function () {
  $( 'a' ).click( function ( evt ) {
    $( '#display' ).text( 'You clicked: ' + $( this ).text() );

    if ( $(this).hasClass( 'withPreventDefault' ) ) {
      evt.preventDefault();
    }
  } );
})

window.onbeforeunload = function () {
  return "Are you sure you want to leave?";   
};

<p id="display"></p>

<p><a class="withPreventDefault" href="#">Number sign link *with* preventDefault</a></p>

<p><a class="withPreventDefault" href="javascript:void(0);">JavaScript href link *with* preventDefault</a></p>

<p><a href="javascript:void(0);">JavaScript href link *without* preventDefault</a></p>

Если пользовательская мышь находится по ссылке, и они запускают страницу обновления с помощью клавиатуры или активируют ссылку с помощью клавиатуры, приглашение не появится. Так что подход доктора Молле не сработает в этом редком случае.