web-dev-qa-db-fra.com

Comment puis-je empêcher le déclenchement de window.onbeforeunload par des liens javascript: href dans IE?

Je construis un coffre-fort pour mon formulaire qui avertira les utilisateurs que s'ils quittent la page, leurs données de formulaire seront perdues (comme ce que fait Gmail). 

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

La fonction ci-dessus fonctionne très bien dans firefox, mais dans IE, elle est déclenchée par un lien href, même s'il s'agit de liens vers du javascript et non d'autres pages. 

par exemple....

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

Je me demande s’il existe un moyen de contourner ce problème, car je ne veux pas que l’utilisateur pense qu’il quitte la page alors qu’il clique simplement sur un bouton. Je n'ai pas la possibilité de réécrire tous les différents liens car ils sont intégrés et nombreux.

Des idées?

26
Maxx

Vous pouvez supprimer et réaffecter onbeforeunload lors du survol de ces liens:

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');}
            );

  }
);
35
Dr.Molle

Je viens de rencontrer un problème similaire et j'ai trouvé une solution très simple:

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

Cela supprimera l'événement onbeforeunload juste avant que l'événement click ne soit déclenché.

7
Ginchen

Déplacez n'importe quel script vers un gestionnaire d'événements click, avec une page de secours pour les utilisateurs sans JavaScript:

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

Les champions JS discrets s'opposeront probablement à l'utilisation de l'attribut onclick, mais le fait est que cela fonctionne, c'est le moyen le plus simple d'ajouter un gestionnaire d'événements et le moyen le plus simple de fournir un exemple. Pour une meilleure séparation des problèmes, vous pouvez utiliser à la place une propriété DOM0 onclick, addEventListener()/attachEvent() ou une bibliothèque.

3
Tim Down

Si vous incluez un symbole de signet dans le href d'une balise, vous devriez toujours pouvoir utiliser l'événement onclick pour inclure votre JavaScript.

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

J'ai effectué un certain nombre de tests et cela semble exécuter le JavaScript sans déclencher l'événement onbeforeunload. Je serais curieux de savoir si cela fonctionne pour les autres ou si vous avez toujours le même problème après avoir implémenté une balise de cette manière.

1
Lone Ranger

(Comme certaines des autres réponses, cela nécessite de changer la façon dont le JavaScript est lié. Si cela ne fonctionne pas pour vous, ignorez.)

J'ai trouvé que dans IE 7 à IE 10, le simple fait d'utiliser jQuery .click () avec preventDefault fonctionne sans afficher le message onbeforeunload (IE 11 ne montre pas le message beforeunload pour aucun de mes tests). Ceci est vrai que le href soit '#' ou javascript:void(0). J'espère que la conclusion sera valable si attachEvent/addEventListener est utilisé directement, mais je n'ai pas testé cela.

Vous trouverez une démonstration du programme ci-dessous à l’adresse http://jsbin.com/tatufehe/1 . Les deux versions (en vert) avec preventDefault fonctionnent (n'affichent pas la boîte de dialogue beforeunload). Celui sans preventDefault le montre (à titre de comparaison).


$( 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>
1
Matthew Flaschen

Si la souris de l'utilisateur est sur un lien et qu'il déclenche l'actualisation de la page avec le clavier ou active un lien avec le clavier, l'invite n'apparaîtra pas. L’approche de Dr.Molle ne fonctionnera donc pas dans ce cas rare.

0
danial