web-dev-qa-db-fra.com

Comment désactiver les liens HTML

J'ai un bouton de lien dans un <td> que je dois désactiver. Cela fonctionne sur IE mais ne fonctionne pas dans Firefox et Chrome . La structure est - Lien dans un <td>. Je ne peux ajouter aucun conteneur dans le <td> (comme div/span)

J'ai essayé tout ce qui suit mais je ne travaille pas sur Firefox (en utilisant 1.4.2 js):

$(td).children().each(function () {
        $(this).attr('disabled', 'disabled');
  });


  $(td).children().attr('disabled', 'disabled');

  $(td).children().attr('disabled', true);

  $(td).children().attr('disabled', 'true');

Remarque - Je ne peux pas désenregistrer la fonction de clic pour la balise d'ancrage car celle-ci est enregistrée de manière dynamique. ET JE DOIS MONTRER LE LIEN EN MODE DÉSACTIVÉ.

232
Ankit

Vous ne pouvez pas désactiver un lien (de manière portable). Vous pouvez utiliser l'une de ces techniques (chacune avec ses avantages et ses inconvénients).

Manière CSS

Cela devrait être la bonne façon (mais voir plus loin) de le faire quand la plupart des navigateurs le supporteront:

a.disabled {
    pointer-events: none;
}

C'est ce que fait par exemple Bootstrap 3.x. Actuellement (2016), il n'est bien pris en charge que par Chrome, FireFox et Opera (19 ans et plus). Internet Explorer a commencé à supporter cela à partir de la version 11 mais pas pour les liens mais il est disponible dans un élément externe comme:

span.disable-links {
    pointer-events: none;
}

Avec:

<span class="disable-links"><a href="#">...</a></span>

Workaround

Nous avons probablement besoin de définir une classe CSS pour pointer-events: none mais que se passe-t-il si nous réutilisons l'attribut disabled au lieu d'une classe CSS? À proprement parler, disabled n'est pas pris en charge pour <a>, mais les navigateurs ne se plaindront pas pour les attributs unknown. Utiliser l'attribut disabled IE ignorera pointer-events mais honorera IE l'attribut disabled spécifique; les autres navigateurs compatibles CSS ignoreront l'attribut unknowndisabled et honoreront pointer-events. Plus facile à écrire qu'à expliquer:

a[disabled] {
    pointer-events: none;
}

Une autre option pour IE 11 consiste à définir display des éléments de lien sur block ou inline-block:

<a style="pointer-events: none; display: inline-block;" href="#">...</a>

Notez que ceci peut être une solution portable si vous avez besoin de supporter IE (et que vous puissiez changer votre code HTML) mais ...

Tout cela étant dit, veuillez noter que pointer-events désactive uniquement ... les événements de pointeur. Les liens seront toujours navigables via le clavier, vous devrez également appliquer l'une des autres techniques décrites ici.

Concentrer

En conjonction avec la technique CSS décrite ci-dessus, vous pouvez utiliser tabindex d'une manière non standard pour empêcher la focalisation d'un élément:

<a href="#" disabled tabindex="-1">...</a>

Je n'ai jamais vérifié sa compatibilité avec de nombreux navigateurs, alors vous voudrez peut-être le tester vous-même avant de l'utiliser. Il a l'avantage de fonctionner sans JavaScript. Malheureusement (mais évidemment), tabindex ne peut pas être modifié à partir de CSS.

Clics d'interception

Utilisez un href pour une fonction JavaScript, recherchez la condition (ou l'attribut disabled lui-même) et ne faites rien au cas où.

$("td > a").on("click", function(event){
    if ($(this).is("[disabled]")) {
        event.preventDefault();
    }
});

Pour désactiver les liens, procédez comme suit:

$("td > a").attr("disabled", "disabled");

Pour les réactiver:

$("td > a").removeAttr("disabled");

Si vous voulez au lieu de .is("[disabled]"), vous pouvez utiliser .attr("disabled") != undefined (jQuery 1.6+ renverra toujours undefined lorsque l'attribut n'est pas défini) mais is() est beaucoup plus clair (merci à Dave Stewart pour ce conseil). Veuillez noter ici que j'utilise l'attribut disabled d'une manière non standard. Si cela vous intéresse, remplacez l'attribut par une classe et remplacez .is("[disabled]") par .hasClass("disabled") (ajouter et supprimer avec addClass() et removeClass()).

Zoltán Tamási a noté dans un commentaire que "dans certains cas, l'événement click est déjà lié à une fonction" réelle "(par exemple, en utilisant knockoutjs). Dans ce cas, la commande du gestionnaire d'événements peut causer des problèmes. J'ai donc implémenté liens désactivés en liant un faux gestionnaire de renvoi aux événements touchstart, mousedown et keydown du lien. Il présente certains inconvénients (il empêchera le défilement tactile démarré sur le lien) ", mais la gestion des événements de clavier permet également d'empêcher la navigation au clavier.

Notez que si href n'est pas effacé, il est possible pour l'utilisateur de visiter manuellement cette page.

Effacer le lien

Désactivez l'attribut href. Avec ce code, vous n’ajoutez pas de gestionnaire d’événements, mais vous modifiez le lien lui-même. Utilisez ce code pour désactiver les liens:

$("td > a").each(function() {
    this.data("href", this.attr("href"))
        .attr("href", "javascript:void(0)")
        .attr("disabled", "disabled");
});

Et celui-ci pour les réactiver:

$("td > a").each(function() {
    this.attr("href", this.data("href")).removeAttr("disabled");
});

Personnellement, je n'aime pas beaucoup cette solution (si vous n'avez pas à en faire plus avec les liens désactivés) mais peut être plus compatible en raison des différentes façons de suivre un lien.

Faux gestionnaires de clics

Ajouter/supprimer une fonction onclick où vous return false, le lien ne sera pas suivi. Pour désactiver les liens:

$("td > a").attr("disabled", "disabled").on("click", function() {
    return false; 
});

Pour les réactiver:

$("td > a").removeAttr("disabled").off("click");

Je ne pense pas qu'il y ait une raison de préférer cette solution à la première.

Coiffant

Le style est encore plus simple, quelle que soit la solution utilisée pour désactiver le lien, nous avons ajouté un attribut disabled afin que vous puissiez utiliser la règle CSS suivante:

a[disabled] {
    color: gray;
}

Si vous utilisez une classe au lieu d'un attribut:

a.disabled {
    color: gray;
}

Si vous utilisez un framework d'interface utilisateur, vous constaterez peut-être que les liens disabled ne sont pas correctement stylés. Bootstrap 3.x, par exemple, gère ce scénario et le bouton est correctement stylé avec l'attribut disabled et avec la classe .disabled. Si, au lieu de cela, vous effacez le lien (ou utilisez l'une des autres techniques JavaScript), vous devez également gérer le style car un <a> sans href est toujours peint comme étant activé. 

Applications Internet riches accessibles (ARIA)

N'oubliez pas d'inclure également un attribut aria-disabled="true" avec disabled attribut/classe.

465
Adriano Repetti

Vous avez le correctif en css. 

td.disabledAnchor a{
       pointer-events: none !important;
       cursor: default;
       color:Gray;
}

Au-dessus de css lorsqu'il est appliqué à la balise anchor, l'événement click est désactivé.

Pour plus de détails, cliquez sur ce lien - link

21
Ankit

Merci à tous ceux qui ont publié des solutions (en particulier @AdrianoRepetti), j'ai combiné plusieurs approches pour fournir des fonctionnalités disabled plus avancées (et cela fonctionne sur plusieurs navigateurs). Le code est ci-dessous (ES2015 et coffeescript en fonction de vos préférences).

Ceci fournit plusieurs niveaux de défense afin que les ancres marquées comme désactivées se comportent réellement comme telles . En utilisant cette approche, vous obtenez une ancre que vous ne pouvez pas:

  • cliquez sur
  • appuyer sur et appuyer sur retour
  • la tabulation sur celle-ci déplacera le focus sur le prochain élément activable
  • il sait si l'ancre est activée par la suite

Comment

  1. Inclure ce css, car il s’agit de la première ligne de défense. Cela suppose que le sélecteur que vous utilisez est a.disabled

    a.disabled {
      pointer-events: none;
      cursor: default;
    }
    
  2. Ensuite, instanciez cette classe sur ready (avec le sélecteur facultatif):

      new AnchorDisabler()
    

Classe ES2015

npm install -S key.js

import {Key, Keycodes} from 'key.js'

export default class AnchorDisabler {
  constructor (config = { selector: 'a.disabled' }) {
    this.config = config
    $(this.config.selector)
      .click((ev) => this.onClick(ev))
      .keyup((ev) => this.onKeyup(ev))
      .focus((ev) => this.onFocus(ev))
  }

  isStillDisabled (ev) {
    //  since disabled can be a class or an attribute, and it can be dynamically removed, always recheck on a watched event
    let target = $(ev.target)
    if (target.hasClass('disabled') || target.prop('disabled') == 'disabled') {
      return true
    }
    else {
      return false
    }
  }

  onFocus (ev) {
    //  if an attempt is made to focus on a disabled element, just move it along to the next focusable one.
    if (!this.isStillDisabled(ev)) {
      return
    }

    let focusables = $(':focusable')
    if (!focusables) {
      return
    }

    let current = focusables.index(ev.target)
    let next = null
    if (focusables.eq(current + 1).length) {
      next = focusables.eq(current + 1)
    } else {
      next = focusables.eq(0)
    }

    if (next) {
      next.focus()
    }
  }

  onClick (ev) {
    // disabled could be dynamically removed
    if (!this.isStillDisabled(ev)) {
      return
    }

    ev.preventDefault()
    return false
  }

  onKeyup (ev) {
    // We are only interested in disabling Enter so get out fast
    if (Key.isNot(ev, Keycodes.ENTER)) {
      return
    }

    // disabled could be dynamically removed
    if (!this.isStillDisabled(ev)) {
      return
    }

    ev.preventDefault()
    return false
  }
}

Classe Coffescript:

class AnchorDisabler
  constructor: (selector = 'a.disabled') ->
    $(selector).click(@onClick).keyup(@onKeyup).focus(@onFocus)

  isStillDisabled: (ev) =>
    ### since disabled can be a class or an attribute, and it can be dynamically removed, always recheck on a watched event ###
    target = $(ev.target)
    return true if target.hasClass('disabled')
    return true if target.attr('disabled') is 'disabled'
    return false

  onFocus: (ev) =>
    ### if an attempt is made to focus on a disabled element, just move it along to the next focusable one. ###
    return unless @isStillDisabled(ev)

    focusables = $(':focusable')
    return unless focusables

    current = focusables.index(ev.target)
    next = (if focusables.eq(current + 1).length then focusables.eq(current + 1) else focusables.eq(0))

    next.focus() if next


  onClick: (ev) =>
    # disabled could be dynamically removed
    return unless @isStillDisabled(ev)

    ev.preventDefault()
    return false

  onKeyup: (ev) =>

    # 13 is the js key code for Enter, we are only interested in disabling that so get out fast
    code = ev.keyCode or ev.which
    return unless code is 13

    # disabled could be dynamically removed
    return unless @isStillDisabled(ev)

    ev.preventDefault()
    return false
11
kross

Essayez l'élément:

$(td).find('a').attr('disabled', 'disabled');

Désactiver un lien fonctionne pour moi dans Chrome: http://jsfiddle.net/KeesCBakker/LGYpz/ .

Firefox ne semble pas jouer à Nice. Cet exemple fonctionne:

<a id="a1" href="http://www.google.com">Google 1</a>
<a id="a2" href="http://www.google.com">Google 2</a>

$('#a1').attr('disabled', 'disabled');

$(document).on('click', 'a', function(e) {
    if ($(this).attr('disabled') == 'disabled') {
        e.preventDefault();
    }
});

Remarque: ajout d'une déclaration "en direct" pour les futurs liens désactivés/activés.
Note2: a changé de «live» en «on».

5
Kees C. Bakker

J'ai fini avec la solution ci-dessous, qui peut fonctionner avec un attribut, <a href="..." disabled="disabled"> ou une classe <a href="..." class="disabled">:

Styles CSS:

a[disabled=disabled], a.disabled {
    color: gray;
    cursor: default;
}

a[disabled=disabled]:hover, a.disabled:hover {
    text-decoration: none;
}

Javascript (prêt pour jQuery):

$("a[disabled], a.disabled").on("click", function(e){

    var $this = $(this);
    if ($this.is("[disabled=disabled]") || $this.hasClass("disabled"))
        e.preventDefault();
})
1
isapir

Je ferais quelque chose comme

$('td').find('a').each(function(){
 $(this).addClass('disabled-link');
});

$('.disabled-link').on('click', false);

quelque chose comme ça devrait marcher. Vous ajoutez une classe aux liens que vous souhaitez désactiver, puis vous renvoyez false lorsque quelqu'un les clique dessus. Pour les activer, supprimez simplement la classe.

0
mkk

Pour désactiver le lien pour accéder à une autre page sur un périphérique tactile:

if (control == false)
  document.getElementById('id_link').setAttribute('href', '#');
else
  document.getElementById('id_link').setAttribute('href', 'page/link.html');
end if;
0
rgfpy

vous ne pouvez pas désactiver un lien; si vous voulez que cet événement click ne se déclenche pas, il suffit alors de Remove à action à partir de ce lien.

$(td).find('a').attr('href', '');

Pour plus d'informations: - Eléments pouvant être désactivés

0
Pranav

Bootstrap 4.1 fournit une classe nommée disabled et aria-disabled="true" attribut.

exemple"

<a href="#" 
        class="btn btn-primary btn-lg disabled" 
        tabindex="-1" 
        role="button" aria-disabled="true"
>
    Primary link
</a>

Plus est sur getbootstrap.com

Donc, si vous voulez le créer dynamiquement, et you don't want to care if it is button or ancor thanin script JS, vous avez besoin de quelque chose comme ça

   let $btn=$('.myClass');
   $btn.attr('disabled', true);
   if ($btn[0].tagName == 'A'){
        $btn.off();
        $btn.addClass('disabled');
        $btn.attr('aria-disabled', true);
   }

Mais soyez prudent

La solution ne fonctionne que sur les liens avec les classes btn btn-link.

Parfois, bootstrap recommande d'utiliser la classe card-link; dans ce cas, la solution ne fonctionnera pas.

0
Yevgeniy Afanasyev