web-dev-qa-db-fra.com

Comment puis-je empêcher une page Web de faire défiler vers le haut lorsque vous cliquez sur un lien qui déclenche JavaScript?

Lorsque j'ai un lien qui est câblé avec un événement jQuery ou JavaScript tel que:

<a href="#">My Link</a>

Comment puis-je empêcher la page de défiler vers le haut? Lorsque je supprime l'attribut href de l'ancre, la page ne défile pas vers le haut, mais le lien ne semble pas être cliquable.

130
Achilles

Vous devez empêcher l'action par défaut de l'événement click (c'est-à-dire de naviguer vers la cible du lien).

Il y a deux façons de faire ça.

Option 1: event.preventDefault()

Appelez la méthode .preventDefault() de l'objet événement transmis à votre gestionnaire. Si vous utilisez jQuery pour lier vos gestionnaires, cet événement sera une instance de jQuery.Event et ce sera la version jQuery de .preventDefault() . Si vous utilisez addEventListener pour lier vos gestionnaires, ce sera un Event et la version DOM brute de .preventDefault() . De toute façon fera ce dont vous avez besoin.

Exemples:

$('#ma_link').click(function($e) {
    $e.preventDefault();
    doSomething();
});

document.getElementById('#ma_link').addEventListener('click', function (e) {
    e.preventDefault();
    doSomething();
})

Option 2: return false;

En jQuery :

Le renvoi de false à partir d'un gestionnaire d'événements appelle automatiquement event.stopPropagation () et event.preventDefault ()

Donc, avec jQuery, vous pouvez également utiliser cette approche pour empêcher le comportement de lien par défaut:

$('#ma_link').click(function(e) {
     doSomething();
     return false;
});

Si vous utilisez des événements DOM bruts, cela fonctionnera également sur les navigateurs modernes, car la spécification HTML 5 dicte ce comportement. Cependant, les anciennes versions de la spécification n'en avaient pas, donc si vous avez besoin d'une compatibilité maximale avec les anciens navigateurs, vous devez appeler explicitement .preventDefault(). Voir event.preventDefault () vs. return false (no jQuery) pour plus de détails.

191
Paolo Bergantino

Vous pouvez définir votre href sur #! Au lieu de #

Par exemple,

<a href="#!">Link</a>

ne fera aucun défilement lorsque vous cliquez dessus.

Attention! Ceci ajoutera quand même une entrée à l'historique du navigateur lorsque vous cliquez dessus, ce qui signifie qu'après avoir cliqué sur votre lien, le bouton Précédent de l'utilisateur ne les mènera pas au page ils étaient auparavant. Pour cette raison, il est probablement préférable d'utiliser l'approche .preventDefault() , ou d'utiliser les deux en combinaison.

Voici un Fiddle illustrant ceci (il suffit de froisser votre navigateur jusqu'à ce que vous obteniez une barre de défilement):
http://jsfiddle.net/9dEG7/


Pour le public - pourquoi cela fonctionne:

Ce comportement est spécifié dans les spécifications HTML5 sous la section Navigation vers un identificateur de fragment . Si un lien avec un href de "#" Provoque le défilement du document vers le haut, c'est que ce comportement est explicitement spécifié comme moyen de gérer un identificateur de fragment vide:

2. Si fragid est la chaîne vide, la partie indiquée du document correspond au haut du document.

L'utilisation d'une href de "#!" Fonctionne simplement parce qu'elle évite cette règle. Le point d'exclamation n'a rien de magique: il crée simplement un identifiant de fragment pratique, car il est sensiblement différent d'un fragment typique et ne devrait jamais correspondre à l'élément id ou name d'un élément de votre page. En effet, nous pourrions mettre presque n'importe quoi après le hachage; les seuls fragments qui ne suffiront pas sont la chaîne vide, le mot 'haut' ou les chaînes correspondant aux attributs name ou id des éléments de la page.

Plus précisément, nous avons juste besoin d’un identifiant de fragment qui nous fera passer à l’étape 8 de l’algorithme suivant pour déterminer = la partie indiquée du document à partir du fragment:

  1. Appliquez l'algorithme d'analyse URL à l'URL et laissez fragid le composant fragmenté de l'URL analysée résultante.

  2. Si fragid est la chaîne vide, la partie indiquée du document est le haut du document. arrêtez l'algorithme ici.

  3. Soit fragid bytes le résultat du décodage en pourcentage fragid.

  4. Soit decoded fragid le résultat de l'application de l'algorithme du décodeur UTF-8 à fragid bytes. Si le décodeur UTF-8 émet une erreur de décodeur, annulez-le et passez à l'étape no decoded fragid.

  5. S'il existe dans le DOM un élément dont l'ID est exactement égal à decoded fragid, le premier élément de ce type dans l'ordre de l'arborescence est la partie indiquée du document; arrêtez l'algorithme ici.

  6. Pas de décodé fragid: S'il existe un élément dans le DOM qui a un attribut name dont la valeur est exactement égale à fragid (= pas decoded fragid), le premier élément de ce type dans l'ordre de l'arbre est la partie indiquée du document; arrêtez l'algorithme ici.

  7. Si fragid est une correspondance ASCII insensible à la casse pour la chaîne top, alors la partie indiquée du document est le haut du document. ; arrêtez l’algorithme ici.

  8. Sinon, aucune partie du document n’est indiquée.

Tant que nous atteignons les étapes 8 et aucune partie du document n'est indiquée, la règle suivante entre en jeu:

S'il n'y a pas de partie indiquée ..., l'agent d'utilisateur ne doit rien faire.

c'est pourquoi le navigateur ne défile pas.

156
Matt Crinklaw-Vogt

Une approche simple consiste à exploiter ce code:

<a href="javascript:void(0);">Link Title</a>

Cette approche ne force pas l'actualisation de la page, la barre de défilement reste donc en place. En outre, il vous permet de modifier par programme l'événement onclick et de gérer la liaison d'événements côté client à l'aide de jQuery.

Pour ces raisons, la solution ci-dessus est meilleure que:

<a href="javascript:myClickHandler();">Link Title</a>
<a href="#" onclick="myClickHandler(); return false;">Link Title</a>

où la dernière solution évitera le problème de défilement si et seulement si la méthode myClickHandler n'échoue pas.

26
phreeskier

Renvoyer false à partir du code que vous appelez fonctionnera et, dans un certain nombre de circonstances, est la méthode préférée, mais vous pouvez aussi le faire

<a href="javascript:;">Link Title</a>

En ce qui concerne le référencement, cela dépend vraiment de la raison pour laquelle votre lien sera utilisé. Si vous comptez vous en servir pour créer un lien vers un autre contenu, je conviendrais en principe que vous souhaitiez quelque chose de significatif ici, mais si vous utilisez le lien à des fins fonctionnelles, vous le ferez peut-être comme le fait Stack Overflow pour la barre d'outils de publication (gras, italique, lien hypertexte). , etc.) alors cela n’a probablement pas d’importance.

11
Dean

Vous devriez changer le

<a href="#">My Link</a>

à

<a href="javascript:;">My Link</a>

Ainsi, lorsque vous cliquez sur le lien, la page ne défilera pas en haut. C'est plus propre que d'utiliser href = "#" et d'empêcher ensuite l'exécution de l'événement par défaut.

J'ai de bonnes raisons pour cela lors de la première réponse à cette question , comme le return false; Ne s'exécutera pas si la fonction appelée génère une erreur, ou vous pouvez ajouter le return false; à une fonction doSomething(), puis oubliez d'utiliser return doSomething();

8
achecopar

Essaye ça:

<a href="#" onclick="return false;">My Link</a>
6
mikeluby

Si vous pouvez simplement changer la valeur href, vous devriez utiliser:

<a href="javascript:void(0);">Link Title</a>

Une autre solution intéressante que je viens de proposer est d'utiliser jQuery pour empêcher l'action de clic de se produire et de faire défiler la page, mais uniquement pour href="#" liens.

<script type="text/javascript">
    /* Stop page jumping when links are pressed */
    $('a[href="#"]').live("click", function(e) {
         return false; // prevent default click action from happening!
         e.preventDefault(); // same thing as above
    });
</script>
4
dazbradbury

Lien vers quelque chose de plus sensé que le haut de la page. Puis annulez l'événement par défaut.

Voir la règle 2 de amélioration progressive pragmatique .

3
Quentin

En outre, vous pouvez utiliser l'attribut event.preventDefault à l'intérieur de onclick.

<a href="#" onclick="event.preventDefault(); doSmth();">doSmth</a>

Pas besoin d'écrire un événement click exstra.

2
efirat
<a onclick="yourfunction()">

cela fonctionnera bien. pas besoin d'ajouter href = "#"

0
Varaj Vignesh

Créez une page contenant deux liens, l'un en haut et l'autre en bas. En cliquant sur le lien du haut, la page doit défiler vers le bas de la page où le lien du bas est présent. En cliquant sur le lien du bas, la page doit défiler vers le haut.

0
Damini

Lorsque vous appelez la fonction, suivez-la avec l'exemple return false:

<input  type="submit" value="Add" onclick="addNewPayment();return false;">
0
buddhi weerasinghe

Vous voudrez peut-être vérifier votre CSS. Dans l'exemple ci-dessous: https://css-tricks.com/the-checkbox-hack/ il y a position: absolute; top: -9999px;. Ceci est particulièrement loufoque sur Chrome, car onclick="whatever" saute toujours à la position absolue de l'élément cliqué.

Enlever position: absolute; top: -9999px;, pour display: none; pourrait aider.

0
urbanaut

Pour Bootstrap 3 pour la réduction, si vous ne spécifiez pas data-target sur l'ancre et ne vous fiez pas à href pour déterminer la cible, l'événement sera évité. Si vous utilisez data-target, vous ' Vous devrez prévenir l'événement vous-même.

<button type="button" class="btn btn-default" data-toggle="collapse" data-target="#demo">Collapse This</button>

<div id="demo" class="collapse"> 
<p>Lorem ipsum dolor sit amet</p>
</div>
0
doug

Vous pouvez simplement écrire comme ceci aussi: -

<a href="#!" onclick="function()">Delete User</a>
0
user2436792