Como desativar links HTML

263

Eu tenho um botão de link dentro do <td>qual tenho que desativar. Isso funciona no IE, mas não funciona no Firefox e Chrome. Estrutura é - Link dentro de a <td>. Não consigo adicionar nenhum contêiner no <td>(como div / span)

Eu tentei o seguinte, mas não funcionei no Firefox (usando 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');

Nota - Não consigo cancelar o registro da função de clique para a marca de âncora, pois ela é registrada dinamicamente. E tenho que mostrar o link no modo desativado.

Ankit
fonte
CSS única pergunta: stackoverflow.com/questions/2091168/disable-a-link-using-css
Ciro Santilli郝海东冠状病六四事件法轮功

Respostas:

510

Você não pode desativar um link (de maneira portátil). Você pode usar uma dessas técnicas (cada uma com seus próprios benefícios e desvantagens).

Maneira CSS

Esse deve ser o caminho certo (mas veja mais adiante) quando a maioria dos navegadores oferecer suporte:

a.disabled {
    pointer-events: none;
}

É o que, por exemplo, o Bootstrap 3.x faz. Atualmente (2016), é bem suportado apenas pelo Chrome, FireFox e Opera (19+). O Internet Explorer começou a oferecer suporte a partir da versão 11, mas não para links, mas está disponível em um elemento externo como:

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

Com:

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

Gambiarra

Provavelmente, precisamos definir uma classe CSS para, pointer-events: nonemas e se reutilizarmos o disabledatributo em vez de uma classe CSS? A rigor, disablednão há suporte para, <a>mas os navegadores não reclamam por atributos desconhecidos . O uso do disabledatributo IE ignorará, pointer-eventsmas honrará o disabledatributo específico do IE ; outros navegadores compatíveis com CSS ignoram atributo e honra desconhecidos . Mais fácil escrever do que explicar:disabledpointer-events

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

Outra opção para o IE 11 é definir displayelementos de link para blockou inline-block:

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

Observe que essa pode ser uma solução portátil se você precisar dar suporte ao IE (e pode alterar seu HTML), mas ...

Tudo isso dito, observe que pointer-eventsdesativa apenas ... eventos de ponteiro. Os links ainda poderão ser navegados pelo teclado; também é necessário aplicar uma das outras técnicas descritas aqui.

Foco

Em conjunto com a técnica CSS descrita acima, você pode usar de tabindexmaneira não padrão para impedir que um elemento seja focado:

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

Nunca verifiquei sua compatibilidade com muitos navegadores; talvez você queira testá-lo antes de usar isso. Tem a vantagem de trabalhar sem JavaScript. Infelizmente (mas obviamente) tabindexnão pode ser alterado do CSS.

Interceptar cliques

Use a hrefpara uma função JavaScript, verifique a condição (ou o próprio atributo desativado) e não faça nada.

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

Para desativar os links, faça o seguinte:

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

Para reativá-los:

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

Se você quiser, em vez de .is("[disabled]")usar, o .attr("disabled") != undefinedjQuery 1.6+ sempre retornará undefinedquando o atributo não estiver definido, mas is()é muito mais claro (obrigado a Dave Stewart por esta dica). Observe aqui que estou usando o disabledatributo de uma maneira não padrão; se você se importa com isso, substitua o atributo por uma classe e substitua .is("[disabled]")por .hasClass("disabled")(adicionando e removendo com addClass()e removeClass()).

Zoltán Tamási observou em um comentário que "em alguns casos o evento click já está vinculado a alguma função" real "(por exemplo, usando knockoutjs). Nesse caso, a ordem do manipulador de eventos pode causar alguns problemas. Portanto, implementei links desabilitados vinculando um retorno falsa manipulador do link touchstart, mousedowne keydowneventos. ele tem alguns inconvenientes (que irá impedir toque rolagem começou no link)" , mas lidar com eventos de teclado também tem a vantagem de evitar a navegação pelo teclado.

Observe que, se hrefnão estiver limpo, é possível que o usuário visite manualmente essa página.

Limpe o link

Limpe o hrefatributo. Com esse código, você não adiciona um manipulador de eventos, mas altera o próprio link. Use este código para desativar os links:

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

E este para reativá-los:

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

Pessoalmente, eu não gosto muito dessa solução (se você não precisar fazer mais com links desabilitados), mas ela pode ser mais compatível por causa de várias maneiras de seguir um link.

Manipulador de clique falso

Adicione / remova uma onclickfunção em que você return false, o link não será seguido. Para desativar os links:

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

Para reativá-los:

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

Não acho que exista uma razão para preferir esta solução em vez da primeira.

Styling

O estilo é ainda mais simples, qualquer que seja a solução usada para desativar o link, adicionamos um disabledatributo para que você possa usar a seguinte regra CSS:

a[disabled] {
    color: gray;
}

Se você estiver usando uma classe em vez de atributo:

a.disabled {
    color: gray;
}

Se você estiver usando uma estrutura de interface do usuário, poderá ver que os links desabilitados não estão estilizados corretamente. O Bootstrap 3.x, por exemplo, lida com esse cenário e o botão é estilizado corretamente com disabledatributo e com .disabledclasse. Se, em vez disso, você estiver limpando o link (ou usando uma das outras técnicas de JavaScript), também deverá manipular o estilo, porque um <a>sem hrefainda será pintado como ativado.

Aplicativos avançados para Internet acessíveis (ARIA)

Não se esqueça de incluir também um atributo aria-disabled="true"junto com o disabledatributo / classe.

Adriano Repetti
fonte
2
Certo. Mas para facilitar a manutenção Eu acrescentaria manipuladores de eventos de clique para todos os td as que pode ser desativado, que irá chamar event.preventDefault(), se $(this).data('disabled')é verdade, e em seguida, defina data('disabled', true)a qualquer link Quero desativar (falso para permitir, etc.)
Ori
1
@ Ankit Para a aparência, você tem CSS! Configure uma regra para links 'desativados' como este a [desativado] {color: grey} #
Adriano Repetti 23/04
1
Atualização rápida no suporte ao navegador . Nota ainda que IE11 suporta ponteiro-eventos, há um pequeno boato que diz que ele não funciona em links: (...
agosto
1
$(this).is('[disabled]')pode ser uma maneira mais agradável para detectar o atributo desativado
Dave Stewart
2
Jon, eu não gosto muito. Primeiro de tudo porque a navegação pelo teclado ainda funciona. Segundo, porque é um truque (pode ser útil apenas se nada mais funcionar). Terceiro, porque algumas pessoas mantêm o Javascript desativado e, nesse caso, você não tem nenhum "nível" de proteção. Quarto porque é a solução mais complicada aqui (quando poucas linhas Javascript podem funcionar)
Adriano Repetti
23

Consegui a correção em css.

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

Acima de css, quando aplicado à tag anchor, desativará o evento click.

Para mais detalhes, confira este link

Ankit
fonte
1
É uma boa solução, mas não é suportada por ... acho ... Internet Explorer.
Adriano Repetti
Sua suportado por todos os navegadores
Ankit
1
Não deve ser suportado para HTML no Internet Explorer e Opera.
Adriano Repetti 2/12/12
@ Ankit, ele não funciona no IE 9 e abaixo. Você está usando o IE 10?
usar o seguinte
4
Isso falha nos casos de uso de eventos do teclado, como Adriano Repetti menciona acima. O usuário ainda pode acessar o link e pressionar enter.
gaiola cascavel
12

Obrigado a todos que publicaram soluções (especialmente @AdrianoRepetti), eu combinei várias abordagens para fornecer algumas mais avançadas disabled funcionalidades (e funciona em vários navegadores). O código está abaixo (ES2015 e coffeescript com base em sua preferência).

Isso fornece vários níveis de defesa para que as âncoras marcadas como desativadas realmente se comportem como tais. Usando essa abordagem, você obtém uma âncora que não pode:

  • clique
  • guia para e pressione retorno
  • tabulação para ele moverá o foco para o próximo elemento focalizável
  • sabe se a âncora é ativada posteriormente

Como

  1. Inclua esse css, pois é a primeira linha de defesa. Isso pressupõe que o seletor usado sejaa.disabled

    a.disabled {
      pointer-events: none;
      cursor: default;
    }
  2. Em seguida, instancie esta classe em ready (com seletor opcional):

      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
Kross
fonte
Mas e se precisarmos de uma solução jQuery / javascript direta? Veja minha resposta abaixo.
Jon Crawford
1
Bem, então você usa a classe ES2015 que acabei de adicionar!
Kross
7

Experimente o elemento:

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

Desativar um link funciona para mim no Chrome: http://jsfiddle.net/KeesCBakker/LGYpz/ .

O Firefox não parece ter um bom desempenho. Este exemplo funciona:

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

Nota: adicionada uma declaração 'ao vivo' para futuros links desativados / ativados.
Nota2: alterado 'ao vivo' para 'ligado'.

Kees C. Bakker
fonte
6
O novo exemplo também deve funcionar no Firefox. ;-) é um firefix: D
Kees C. Bakker
O Chrome impede a navegação no jsFiddle devido a "Recusou-se a exibir o documento porque a exibição é proibida pelo X-Frame-Options". Desculpe se o exemplo jsFiddle faz coisas estranhas ;-)
Kees C. Bakker
Eu tenho que mostrar a marca de âncora como desativado também. O mesmo que é mostrado no IE. Além disso, eu não quero modificar a função de clique para colocar uma verificação se é deficiente
Ankit
A parte do show pode ser feita por css e adicionando uma classe que a torna esmaecida. A vantagem do clique 'ao vivo' é que você corrigirá o problema para todos os links. Se eu puder ajudar mais, me avise. Espero que você tenha sucesso.
Kees C. Bakker
Experimente a minha resposta abaixo para obter uma solução totalmente para vários navegadores!
Jon Crawford
4

O Bootstrap 4.1 fornece uma classe denominada disablede aria-disabled="true"atributo.

exemplo"

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

Mais está em getbootstrap.com

Então, se você quiser fazer dinamicamente, e depois you don't want to care if it is button or ancorno script JS, precisará de algo assim

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

Mas tenha cuidado

A solução funciona apenas em links com classes btn btn-link.

Às vezes, o bootstrap recomenda o uso da card-linkclasse; nesse caso, a solução não funcionará .

Yevgeniy Afanasyev
fonte
1

Acabei com a solução abaixo, que pode funcionar com um atributo <a href="..." disabled="disabled">ou uma classe <a href="..." class="disabled">:

Estilos CSS:

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

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

Javascript (em jQuery pronto):

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

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

você não pode desativar um link, se desejar que o evento de clique não seja acionado, basta clicar Removeno actionlink.

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

Para obter mais informações: - Elementos que podem ser desativados

Pranav
fonte
1
Isso realmente não desabilita o link. O elemento âncora ainda será acionado, mesmo que permaneça na mesma página.
Florian Margaine
0

Eu faria algo como

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

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

algo assim deve funcionar. Você adiciona uma classe aos links que deseja desabilitar e retorna falso quando alguém clica neles. Para habilitá-los basta remover a classe.

mkk
fonte
Isso não ajudaria. Eu tenho que registrar novamente o evento click e a função é dinâmica, que é chamada. Uma vez removido, não posso associar-lo de volta
Ankit
0

Para desativar o link para acessar outra página no dispositivo de toque:

if (control == false)
  document.getElementById('id_link').setAttribute('href', '#');
else
  document.getElementById('id_link').setAttribute('href', 'page/link.html');
end if;
rgfpy
fonte
Minha resposta também funciona no celular. Navegador muito cruzado. Ver abaixo.
Jon Crawford
Isso está errado, se você setAttribute('href', '');e o URL da página forem http://example.com/page/?query=somethingo link ao clicar no IE11 http://example.com/page/. Uma solução poderia ser a de usarsetAttribute('href', '#');
Marco Demaio
0

No Razor (.cshtml) você pode fazer:

@{
    var isDisabled = true;
}

<a href="@(isDisabled ? "#" : @Url.Action("Index", "Home"))" @(isDisabled ? "disabled=disabled" : "") class="btn btn-default btn-lg btn-block">Home</a>
Joel Wiklund
fonte
-2

Você pode usar isso para desabilitar o hiperlink do asp.net ou os botões de link em html.

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

Existe uma outra maneira possível, e a que eu mais gosto. Basicamente, é da mesma maneira que o lightbox desativa uma página inteira, colocando uma div e mexendo no z-index. Aqui estão trechos relevantes de um projeto meu. Isso funciona em todos os navegadores !!!!!

Javascript (jQuery):

var windowResizer = function(){
        var offset = $('#back').offset();   
        var buttontop = offset.top;
        var buttonleft = offset.left;
        $('#backdisabler').css({'top':buttontop,'left':buttonleft,'visibility':'visible'});
        offset = $('#next').offset();
        buttontop = offset.top;
        buttonleft = offset.left;
        $('#nextdisabler').css({'top':buttontop,'left':buttonleft,'visibility':'visible'});
}

$(document).ready(function() {
    $(window).resize(function() {   
        setTimeout(function() {
            windowResizer();
        }, 5); //when the maximize/restore buttons are pressed, we have to wait or it will fire to fast
    });
});

e em html

<a href="" id="back" style="float: left"><img src="images/icons/back.png" style="height: 50px; width: 50px" /></a>
<a href="" id="next" style="float: right"><img src="images/icons/next.png" style="height: 50px; width: 50px" /></a>
<img id="backdisabler" src="images/icons/disabled.png" style="visibility: hidden; position: absolute; padding: 5px; height: 62px; width: 62px; z-index: 9000"/>
<img id="nextdisabler" src="images/icons/disabled.png" style="visibility: hidden; position: absolute; padding: 5px; height: 62px; width: 62px; z-index: 9000"/>

Assim, o redimensionador encontra os locais da âncora (as imagens são apenas setas) e coloca o desativador no topo. A imagem do desabilitador é um quadrado cinza translúcido (altere a largura / altura dos desabilitadores no html para corresponder ao seu link) para mostrar que está desabilitado. A flutuação permite que a página seja redimensionada dinamicamente, e os desabilitadores seguirão o exemplo em windowResizer (). Você pode encontrar imagens adequadas no google. Coloquei o CSS relevante em linha para simplificar.

então com base em alguma condição,

$('#backdisabler').css({'visibility':'hidden'});
$('#nextdisabler').css({'visibility':'visible'});
Jon Crawford
fonte
4
Não diminuiu, mas meu palpite: muita sobrecarga para uma coisa simples, seu código não é comentado o suficiente para uma resposta no SO. Também está me sentindo muito hacky, eu pessoalmente não usaria isso.
Emile Bergeron
-5

Eu acho que muitos deles estão pensando demais. Adicione uma classe do que você quiser, como disabled_link.
Em seguida, faça com que o CSS tenha o .disabled_link { display: none }
Boom agora, o usuário não pode ver o link, para que você não precise se preocupar com o clique nele. Se eles fazem algo para satisfazer o link sendo clicável, basta remover a classe com jQuery:
$("a.disabled_link").removeClass("super_disabled"). Crescimento feito!

Jordan Michael Rushing
fonte
Da pergunta: "E eu preciso mostrar o link no modo desativado".
Marcelo
Sim, você está certo. Eu senti falta disso. Então, eu diria vez, mover valor href a dados em href $("td a").each(function(i,v){ $(this).data('href',this.href); $(this).attr('href','#').css('color','grey'); });Então, quando você quer um undisable: $(this).attr('href',$(this).data('href')).css('color','blue');
Jordan Michael Rushing