Jak wyłączyć linki HTML

263

W środku <td>mam przycisk linku, który muszę wyłączyć. Działa to w IE, ale nie działa w Firefox i Chrome. Struktura jest - Link wewnątrz <td>. Nie mogę dodać żadnego kontenera do <td>(jak div / span)

Próbowałem wszystkich poniższych czynności, ale nie działałem w przeglądarce Firefox (używając wersji 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');

Uwaga - Nie mogę wyrejestrować funkcji kliknięcia dla tagu kotwicy, ponieważ jest ona rejestrowana dynamicznie. I MUSZĘ POKAZAĆ LINK W TRYBIE WYŁĄCZONYM.

Ankit
źródło
Tylko pytanie CSS: stackoverflow.com/questions/2091168/disable-a-link-using-css
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Odpowiedzi:

510

Nie możesz wyłączyć linku (w przenośny sposób). Możesz użyć jednej z tych technik (każda ma swoje zalety i wady).

Sposób CSS

Powinien to być właściwy sposób (ale zobacz później), aby to zrobić, gdy większość przeglądarek będzie go obsługiwać:

a.disabled {
    pointer-events: none;
}

Tak działa na przykład Bootstrap 3.x. Obecnie (2016) jest dobrze obsługiwany tylko przez Chrome, FireFox i Opera (19+). Internet Explorer zaczął obsługiwać to od wersji 11, ale nie dla linków, jednak jest dostępny w elemencie zewnętrznym, takim jak:

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

Z:

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

Obejście

My, prawdopodobnie, trzeba zdefiniować klasę CSS pointer-events: noneale co jeśli mamy ponowne ten disabledatrybut zamiast klasy CSS? Ściśle mówiąc, disablednie jest obsługiwane, <a>ale przeglądarki nie będą narzekać na nieznane atrybuty. Użycie disabledatrybutu IE zignoruje, pointer-eventsale będzie honorować określony disabledatrybut IE ; inne przeglądarki zgodne z CSS zignorują nieznany disabled atrybut i honor pointer-events. Łatwiej pisać niż wyjaśniać:

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

Inną opcją dla IE 11 jest zestaw displayelementów łącza do blocklub inline-block:

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

Pamiętaj, że może to być przenośne rozwiązanie, jeśli potrzebujesz obsługi IE (i możesz zmienić swój HTML), ale ...

Wszystko to powiedział, proszę pamiętać, że pointer-eventswyłącza tylko ... zdarzenia wskaźnika. Łącza będą nadal można nawigować za pomocą klawiatury, wówczas musisz również zastosować jedną z innych opisanych tutaj technik.

Skupiać

W połączeniu z opisaną powyżej techniką CSS możesz użyć tabindexw niestandardowy sposób, aby zapobiec koncentracji elementu:

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

Nigdy nie sprawdzałem jego kompatybilności z wieloma przeglądarkami, więc możesz przetestować go sam przed użyciem. Ma tę zaletę, że działa bez JavaScript. Niestety (ale oczywiście) tabindexnie można go zmienić z CSS.

Przechwytuj kliknięcia

Użyj hreffunkcji JavaScript, sprawdź warunek (lub sam wyłączony atrybut) i nic nie rób.

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

Aby wyłączyć łącza, wykonaj następujące czynności:

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

Aby je ponownie włączyć:

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

Jeśli chcesz zamiast tego .is("[disabled]")możesz użyć .attr("disabled") != undefined(jQuery 1.6+ zawsze zwróci, undefinedgdy atrybut nie jest ustawiony), ale is()jest znacznie bardziej przejrzysty (dzięki Dave'owi Stewartowi za tę wskazówkę). Należy pamiętać, tutaj używam disabledatrybut w niestandardowy sposób, jeśli dbasz o to następnie zastąpić atrybut z klasą i wymienić .is("[disabled]")z .hasClass("disabled")(dodawanie i usuwanie z addClass()a removeClass()).

Zoltán Tamási zauważył w komentarzu, że „w niektórych przypadkach zdarzenie kliknięcia jest już powiązane z jakąś„ rzeczywistą ”funkcją (na przykład za pomocą knockoutjs). W takim przypadku zamawianie procedury obsługi zdarzeń może powodować pewne problemy. Dlatego zaimplementowałem wyłączone linki, wiążąc zwrot false obsługi do tego linku touchstart, mousedowni keydownwydarzeń. to ma pewne wady (uniemożliwi to dotykowy przewijania rozpoczęto link)” ale obsługi zdarzeń klawiaturowych ma również korzyści, aby zapobiec nawigację za pomocą klawiatury.

Pamiętaj, że jeśli hrefnie zostanie wyczyszczone, użytkownik może ręcznie odwiedzić tę stronę.

Wyczyść link

Wyczyść hrefatrybut. Za pomocą tego kodu nie dodajesz modułu obsługi zdarzeń, ale zmieniasz sam link. Użyj tego kodu, aby wyłączyć linki:

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

A ten, aby je ponownie włączyć:

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

Osobiście nie podoba mi się to rozwiązanie (jeśli nie musisz robić więcej z wyłączonymi linkami), ale może być bardziej kompatybilne z powodu różnych sposobów podążania za linkiem.

Fałszywy moduł obsługi kliknięć

Dodaj / usuń onclickfunkcję, w której return falselink nie będzie śledzony. Aby wyłączyć linki:

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

Aby je ponownie włączyć:

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

Nie sądzę, aby istniał powód, aby preferować to rozwiązanie zamiast pierwszego.

Stylizacja

Stylizacja jest jeszcze prostsza, bez względu na to, jakiego rozwiązania użyjesz do wyłączenia łącza, dodaliśmy disabledatrybut, dzięki czemu możesz użyć następującej reguły CSS:

a[disabled] {
    color: gray;
}

Jeśli używasz klasy zamiast atrybutu:

a.disabled {
    color: gray;
}

Jeśli używasz frameworku interfejsu użytkownika, możesz zauważyć, że wyłączone linki nie są poprawnie stylizowane. Na przykład Bootstrap 3.x obsługuje ten scenariusz, a przycisk ma poprawną stylizację zarówno z disabledatrybutem, jak iz .disabledklasą. Jeśli zamiast tego usuwasz link (lub używasz jednej z innych technik JavaScript), musisz również obsługiwać stylizację, ponieważ <a>bez hrefjest nadal malowane jako włączone.

Dostępne bogate aplikacje internetowe (ARIA)

Nie zapomnij również dołączyć atrybutu aria-disabled="true"wraz z disabledatrybutem / klasą.

Adriano Repetti
źródło
2
Dobrze. Ale dla łatwiejszego utrzymania dodałbym obsługi zdarzeń kliknij, aby wszystkie td as, które mogą być wyłączone, który zadzwoni event.preventDefault(), jeśli $(this).data('disabled')jest prawdziwa, a następnie ustawić data('disabled', true)na dowolny link Chcę wyłączyć (false, aby umożliwić, etc.)
ori
1
@Ankit Dla wyglądu masz CSS! Ustaw regułę dla „wyłączonych” linków, takich jak ten [wyłączony] {kolor: szary}
Adriano Repetti
1
Szybka aktualizacja obsługi przeglądarki . Uwaga: chociaż IE11 obsługuje zdarzenia wskaźnikowe, istnieje mały smakołyk, który mówi, że nie działa na linkach: (...
sierpień
1
$(this).is('[disabled]')może być lepszym sposobem na wykrycie wyłączonego atrybutu
Dave Stewart
2
Jon, nie lubię tego zbytnio. Przede wszystkim dlatego, że nawigacja za pomocą klawiatury nadal działa. Po drugie, ponieważ jest to podstęp (mogą być przydatne tylko wtedy, gdy nic innego nie działa). Po trzecie, ponieważ niektórzy ludzie wyłączają Javascript, aw tym przypadku nie masz żadnego „poziomu” ochrony. Po czwarte, ponieważ jest to najbardziej skomplikowane rozwiązanie tutaj (gdy może działać kilka wierszy JavaScript)
Adriano Repetti
23

Mam poprawkę w css.

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

Powyżej css po zastosowaniu do tagu zakotwiczenia spowoduje wyłączenie zdarzenia kliknięcia.

Aby uzyskać szczegółowe informacje, sprawdź ten link

Ankit
źródło
1
To dobre rozwiązanie, ale nie jest obsługiwane przez ... zgadnij ... Internet Explorer.
Adriano Repetti,
Obsługiwany jest przez wszystkie przeglądarki
Ankit
1
Nie powinno być obsługiwane dla HTML w Internet Explorerze i Operze.
Adriano Repetti
@Ankit, to nie działa w IE 9 i poniżej. Czy używasz IE 10?
Mandeep Jain
4
Nie udaje się to w przypadku użycia zdarzeń klawiatury, jak wspomniano powyżej Adriano Repetti. Użytkownik może nadal przejść do łącza i nacisnąć klawisz Enter.
rattler klatkowy
12

Dzięki wszystkim, którzy opublikowali rozwiązania (szczególnie @AdrianoRepetti), połączyłem wiele metod, aby zapewnić bardziej zaawansowane disabledfunkcje (i działa w różnych przeglądarkach). Kod znajduje się poniżej (zarówno ES2015, jak i coffeescript w zależności od preferencji).

Zapewnia to wiele poziomów obrony, dzięki czemu Kotwice oznaczone jako wyłączone faktycznie zachowują się jako takie. Stosując to podejście, otrzymujesz kotwicę, której nie możesz:

  • Kliknij
  • tab i naciśnij Return
  • naciśnięcie klawisza spowoduje przeniesienie fokusa do następnego elementu, na którym można ustawić fokus
  • wie, czy kotwica zostanie następnie włączona

Jak

  1. Dołącz ten css, ponieważ jest to pierwsza linia obrony. Zakłada się, że używany jest selektora.disabled

    a.disabled {
      pointer-events: none;
      cursor: default;
    }
  2. Następnie utwórz instancję tej klasy w trybie gotowości (z opcjonalnym selektorem):

      new AnchorDisabler()

Klasa 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
  }
}

Klasa 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
źródło
Ale co, jeśli potrzebujemy prostego rozwiązania jQuery / javascript? Zobacz moją odpowiedź poniżej.
Jon Crawford,
1
No to skorzystaj z klasy ES2015, którą właśnie dodałem!
kross
7

Wypróbuj element:

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

Wyłączenie linku działa dla mnie w Chrome: http://jsfiddle.net/KeesCBakker/LGYpz/ .

Firefox wydaje się nie grać dobrze. Ten przykład działa:

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

Uwaga: dodano instrukcję „na żywo” dla przyszłych wyłączonych / włączonych łączy.
Uwaga 2: zmieniono „na żywo” na „na”.

Kees C. Bakker
źródło
6
Nowy przykład powinien również działać w przeglądarce Firefox. ;-) to poprawka ogniowa: D
Kees C. Bakker
Chrome uniemożliwia nawigację w jsFiddle z powodu „Odmowa wyświetlenia dokumentu, ponieważ wyświetlanie jest zabronione przez X-Frame-Options”. Przepraszam, jeśli przykład jsfiddle robi dziwne rzeczy ;-)
Kees C. Bakker
Muszę również pokazać tag zakotwiczenia jako wyłączony. Tak jak pokazano w IE. Poza tym nie chcę modyfikować funkcji kliknięcia, aby zaznaczyć, czy jest wyłączona
Ankit
Część pokazową można wykonać za pomocą css i dodając klasę, która powoduje, że jest wyszarzona. Zaletą kliknięcia „na żywo” jest to, że rozwiążesz problem wszystkich linków. Jeśli mogę pomóc, daj mi znać. Mam nadzieję, że ci się uda.
Kees C. Bakker
Wypróbuj moją odpowiedź poniżej, aby uzyskać w pełni przeglądarkę!
Jon Crawford
4

Bootstrap 4.1 zapewnia klasę o nazwie disabledi aria-disabled="true"atrybucie.

przykład"

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

Więcej znajduje się na getbootstrap.com

Więc jeśli chcesz zrobić to dynamicznie, a you don't want to care if it is button or ancorniż w skrypcie JS potrzebujesz czegoś takiego

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

Ale bądź ostrożny

Rozwiązanie działa tylko w przypadku łączy z klasami btn btn-link.

Czasami bootstrap zaleca użycie card-linkklasy, w takim przypadku rozwiązanie nie będzie działać .

Jewgienij Afanasiew
źródło
1

Skończyło się na poniższym rozwiązaniu, które może współpracować z atrybutem <a href="..." disabled="disabled">lub klasą <a href="..." class="disabled">:

Style CSS:

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

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

JavaScript (w jQuery gotowy):

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

    var $this = $(this);
    if ($this.is("[disabled=disabled]") || $this.hasClass("disabled"))
        e.preventDefault();
})
isapir
źródło
0

nie można wyłączyć link, jeśli chcesz, że zdarzenie click nie powinien strzelać po prostu z tego linku.Removeaction

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

Więcej informacji: - Elementy, które można wyłączyć

Pranaw
źródło
1
To tak naprawdę nie wyłącza łącza. Element kotwicy nadal się uruchamia, nawet jeśli pozostanie na tej samej stronie.
Florian Margaine,
0

Zrobiłbym coś takiego

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

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

coś takiego powinno działać. Dodajesz klasę dla linków, które chcesz wyłączyć, a następnie zwracasz wartość false, gdy ktoś je kliknie. Aby je włączyć, po prostu usuń klasę.

mkk
źródło
To by nie pomogło. Muszę ponownie zarejestrować zdarzenie kliknięcia, a funkcja jest dynamiczna i jest wywoływana. Po usunięciu nie mogę go ponownie powiązać
Ankit,
0

Aby wyłączyć link, aby uzyskać dostęp do innej strony na urządzeniu dotykowym:

if (control == false)
  document.getElementById('id_link').setAttribute('href', '#');
else
  document.getElementById('id_link').setAttribute('href', 'page/link.html');
end if;
rgfpy
źródło
Moja odpowiedź działa również na urządzeniach mobilnych. Bardzo przeglądarka. Patrz poniżej.
Jon Crawford
To źle, jeśli ty setAttribute('href', '');i adres strony to http://example.com/page/?query=somethinglink po kliknięciu na IE11, by przejść do http://example.com/page/. Obejściem może być użyciesetAttribute('href', '#');
Marco Demaio
0

W Razor (.cshtml) możesz:

@{
    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
źródło
-2

Możesz go użyć do wyłączenia hiperłącza asp.net lub przycisków linków w html.

$("td > a").attr("disabled", "disabled").on("click", function() {
    return false; 
});
Mitesh
źródło
-2

Jest jeszcze jeden możliwy sposób, który najbardziej mi się podoba. Zasadniczo jest to ten sam sposób, w jaki lightbox wyłącza całą stronę, umieszczając div i majstrując przy indeksie Z. Oto odpowiednie fragmenty mojego projektu. Działa to we wszystkich przeglądarkach !!!!!

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

i w 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"/>

Więc resizer znajduje lokalizacje kotwicy (obrazy to tylko strzałki) i umieszcza wyłącznik na górze. Obraz wyłącznika to półprzezroczysty szary kwadrat (zmień szerokość / wysokość blokad w html, aby dopasować do linku), aby pokazać, że jest wyłączony. Liczba zmiennoprzecinkowa pozwala dynamicznie zmieniać rozmiar strony, a wyłączniki będą podążać w tym samym kierunku w windowResizer (). Odpowiednie obrazy można znaleźć w Google. Dla uproszczenia umieściłem odpowiedni plik CSS.

następnie w oparciu o jakiś warunek,

$('#backdisabler').css({'visibility':'hidden'});
$('#nextdisabler').css({'visibility':'visible'});
Jon Crawford
źródło
4
Nie przegłosowałem, ale zgaduję: zbyt duży narzut na prostą rzecz, twój kod nie jest wystarczająco komentowany, aby odpowiedzieć na SO. Czuje się też bardzo hackersko, osobiście nie użyłbym tego.
Emile Bergeron,
-5

Myślę, że wiele z nich jest nad myśleniem. Dodaj klasę, co chcesz disabled_link.
Następnie spraw, aby css miał .disabled_link { display: none }
Boom, teraz użytkownik nie widzi linku, więc nie będziesz musiał się martwić, że go kliknie. Jeśli robią coś, aby zaspokoić link jest klikalny, wystarczy usunąć klasy z jQuery:
$("a.disabled_link").removeClass("super_disabled"). Boom gotowy!

Jordan Michael Rushing
źródło
Z pytania: „I POKAŻĘ LINK W TRYBIE WYŁĄCZONYM”.
Marcelo,
Tak, masz rację. Tęsknie za tym. Więc powiedziałbym zamiast tego, przenieś wartość href na data-href $("td a").each(function(i,v){ $(this).data('href',this.href); $(this).attr('href','#').css('color','grey'); });Następnie, jeśli chcesz ją wyłączyć: $(this).attr('href',$(this).data('href')).css('color','blue');
Jordan Michael Rushing