So deaktivieren Sie HTML-Links


263

Ich habe einen Link-Button in einem, <td>den ich deaktivieren muss. Dies funktioniert im IE, aber nicht in Firefox und Chrome. Struktur ist - Link innerhalb eines <td>. Ich kann keinen Container in die <td>(wie div / span) hinzufügen

Ich habe Folgendes versucht, aber nicht an Firefox gearbeitet (mit 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');

Hinweis - Ich kann die Klickfunktion für das Ankertag nicht abmelden, da es dynamisch registriert wird. UND ICH MUSS DEN LINK IM BEHINDERTEN MODUS ZEIGEN.


Antworten:


510

Sie können einen Link nicht deaktivieren (auf tragbare Weise). Sie können eine dieser Techniken verwenden (jede mit ihren eigenen Vor- und Nachteilen).

CSS Weg

Dies sollte der richtige Weg sein (siehe aber später), wenn die meisten Browser dies unterstützen:

a.disabled {
    pointer-events: none;
}

Dies ist beispielsweise das, was Bootstrap 3.x tut. Derzeit (2016) wird es nur von Chrome, FireFox und Opera (19+) gut unterstützt. Internet Explorer unterstützt dies ab Version 11, jedoch nicht für Links. Es ist jedoch in einem äußeren Element wie dem folgenden verfügbar:

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

Mit:

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

Problemumgehung

Wir müssen wahrscheinlich eine CSS-Klasse definieren, pointer-events: noneaber was ist, wenn wir das Attribut anstelle einer CSS-Klasse wiederverwendendisabled ? Genau genommen disabledwird dies nicht unterstützt, <a>aber Browser beschweren sich nicht über unbekannte Attribute. Wenn Sie das disabledAttribut IE verwenden, wird es ignoriert pointer-events, es wird jedoch das IE-spezifische disabledAttribut berücksichtigt. Andere CSS-kompatible Browser ignorieren unbekannte disabled Attribute und Ehren pointer-events. Einfacher zu schreiben als zu erklären:

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

Eine weitere Option für IE 11 besteht darin, displayVerknüpfungselemente zu blockoder festzulegen inline-block:

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

Beachten Sie, dass dies eine tragbare Lösung sein kann, wenn Sie IE unterstützen müssen (und Ihren HTML-Code ändern können), aber ...

Bitte beachten Sie, dass pointer-eventsnur ... Zeigerereignisse deaktiviert werden. Links können weiterhin über die Tastatur navigiert werden. Dann müssen Sie auch eine der anderen hier beschriebenen Techniken anwenden.

Fokus

In Verbindung mit der oben beschriebenen CSS-Technik können Sie tabindexeine nicht standardmäßige Methode verwenden, um zu verhindern, dass ein Element fokussiert wird:

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

Ich habe die Kompatibilität mit vielen Browsern nie überprüft. Vielleicht möchten Sie sie selbst testen, bevor Sie sie verwenden. Es hat den Vorteil, ohne JavaScript zu arbeiten. Leider (aber offensichtlich) tabindexkann nicht von CSS geändert werden.

Klicks abfangen

Verwenden Sie eine hrefJavaScript-Funktion, überprüfen Sie die Bedingung (oder das deaktivierte Attribut selbst) und tun Sie für den Fall nichts.

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

So deaktivieren Sie Links:

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

So aktivieren Sie sie erneut:

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

Wenn Sie möchten .is("[disabled]"), können Sie stattdessen verwenden .attr("disabled") != undefined(jQuery 1.6+ wird immer zurückgegeben, undefinedwenn das Attribut nicht festgelegt ist), is()ist aber viel klarer (danke an Dave Stewart für diesen Tipp). Bitte beachten Sie, dass ich das disabledAttribut nicht standardmäßig verwende. Wenn Sie sich dafür interessieren, ersetzen Sie das Attribut durch eine Klasse und ersetzen Sie es .is("[disabled]")durch .hasClass("disabled")(Hinzufügen und Entfernen mit addClass()und removeClass()).

Zoltán Tamási bemerkte in einem Kommentar, dass "in einigen Fällen das Klickereignis bereits an eine" echte "Funktion gebunden ist (z. B. mithilfe von knockoutjs). In diesem Fall kann die Reihenfolge der Ereignishandler einige Probleme verursachen. Daher habe ich deaktivierte Links implementiert, indem ich eine Rückgabe gebunden habe falsche Handler zu den wichtigsten Link touchstart, mousedownund keydownVeranstaltungen. es hat einige Nachteile (es wird verhindert Touch auf den Link gestartet Scrollen)“ aber Tastaturereignisse Handhabung hat auch den Vorteil Navigation mit der Tastatur zu verhindern.

Beachten Sie, dass hrefder Benutzer diese Seite manuell besuchen kann, wenn sie nicht gelöscht wird.

Löschen Sie den Link

Löschen Sie das hrefAttribut. Mit diesem Code fügen Sie keinen Ereignishandler hinzu, sondern ändern den Link selbst. Verwenden Sie diesen Code, um Links zu deaktivieren:

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

Und dieser, um sie wieder zu aktivieren:

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

Persönlich mag ich diese Lösung nicht sehr (wenn Sie nicht mehr mit deaktivierten Links tun müssen), aber sie kann aufgrund verschiedener Möglichkeiten, einem Link zu folgen, kompatibler sein.

Fake Click Handler

Hinzufügen / Entfernen einer onclickFunktion return false, bei der der Link nicht befolgt wird. So deaktivieren Sie Links:

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

So aktivieren Sie sie erneut:

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

Ich glaube nicht, dass es einen Grund gibt, diese Lösung der ersten vorzuziehen.

Styling

Das Styling ist noch einfacher, unabhängig davon, welche Lösung Sie zum Deaktivieren des Links verwenden. Wir haben ein disabledAttribut hinzugefügt , damit Sie die folgende CSS-Regel verwenden können:

a[disabled] {
    color: gray;
}

Wenn Sie eine Klasse anstelle eines Attributs verwenden:

a.disabled {
    color: gray;
}

Wenn Sie ein UI-Framework verwenden, stellen Sie möglicherweise fest, dass deaktivierte Links nicht richtig gestaltet sind. Bootstrap 3.x behandelt beispielsweise dieses Szenario und die Schaltfläche ist sowohl mit disabledAttribut als auch mit .disabledKlasse korrekt gestaltet . Wenn Sie stattdessen den Link löschen (oder eine der anderen JavaScript-Techniken verwenden), müssen Sie auch das Styling übernehmen, da ein <a>ohne hrefweiterhin als aktiviert gezeichnet wird.

Zugängliche Rich Internet-Anwendungen (ARIA)

Vergessen Sie nicht, auch ein Attribut aria-disabled="true"zusammen mit disabledAttribut / Klasse anzugeben.


2
Recht. Aber zur einfacheren Wartung würde ich allen td adeaktivierten s Klickereignishandler hinzufügen , die aufrufen, event.preventDefault()wenn dies $(this).data('disabled')wahr ist, und dann auf data('disabled', true)einen beliebigen Link setzen, den ich deaktivieren möchte (false zum Aktivieren usw.)
ori

1
@Ankit Für den Auftritt haben Sie CSS! Richten Sie eine Regel für 'deaktivierte' Links wie diese ein [deaktiviert] {Farbe: grau}
Adriano Repetti

1
Schnelles Update zur Browser-Unterstützung . Hinweis obwohl IE11 Zeiger-Ereignisse unterstützt, gibt es einen kleinen Leckerbissen, der sagt , dass es nicht funktioniert auf Links: (...
aug

1
$(this).is('[disabled]')könnte eine schönere Möglichkeit sein, das deaktivierte Attribut zu erkennen
Dave Stewart

2
Jon, ich mag es nicht sehr. Erstens, weil die Tastaturnavigation immer noch funktioniert. Zweitens, weil es ein Trick ist (sie können nur nützlich sein, wenn nichts anderes funktioniert). Drittens, weil einige Leute Javascript deaktiviert lassen und Sie in diesem Fall keine "Schutzstufe" haben. Viertens, weil es hier die komplizierteste Lösung ist (wenn nur wenige Javascript-Zeilen funktionieren)
Adriano Repetti

23

Habe das Update in CSS.

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

Über CSS wird das Klickereignis deaktiviert, wenn es auf das Ankertag angewendet wird.

Weitere Informationen finden Sie unter diesem Link


1
Es ist eine nette Lösung, wird aber von ... rate ... Internet Explorer nicht unterstützt.
Adriano Repetti

Es wird von allen Browsern unterstützt
Ankit

1
Es sollte für HTML in Internet Explorer und Opera nicht unterstützt werden.
Adriano Repetti

@Ankit, es funktioniert nicht in IE 9 und darunter. Verwenden Sie IE 10?
Mandeep Jain

4
Dies schlägt den Anwendungsfall für Tastaturereignisse fehl, wie oben von Adriano Repetti erwähnt. Der Benutzer kann weiterhin auf den Link tippen und die Eingabetaste drücken.
Käfig Rattler

12

Dank an alle, die Lösungen veröffentlicht haben (insbesondere @AdrianoRepetti), habe ich mehrere Ansätze kombiniert, um einige erweiterte disabledFunktionen bereitzustellen (und es funktioniert browserübergreifend). Der Code ist unten (sowohl ES2015 als auch Coffeescript nach Ihren Wünschen).

Dies bietet mehrere Verteidigungsebenen, sodass sich Anker, die als deaktiviert markiert sind, tatsächlich als solche verhalten. Mit diesem Ansatz erhalten Sie einen Anker, den Sie nicht können:

  • klicken
  • Tab auf und drücken Sie die Eingabetaste
  • Wenn Sie darauf tippen, wird der Fokus auf das nächste fokussierbare Element verschoben
  • Es ist bekannt, ob der Anker anschließend aktiviert wird

Wie man

  1. Schließen Sie dieses CSS ein, da es die erste Verteidigungslinie ist. Dies setzt voraus, dass der von Ihnen verwendete Selektor ista.disabled

    a.disabled {
      pointer-events: none;
      cursor: default;
    }
    
  2. Instanziieren Sie diese Klasse als Nächstes (mit optionalem Selektor):

      new AnchorDisabler()

ES2015 Klasse

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

Coffescript-Klasse:

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

Aber was ist, wenn wir eine reine jQuery / Javascript-Lösung benötigen? Siehe meine Antwort unten.
Jon Crawford

1
Dann verwenden Sie die ES2015-Klasse, die ich gerade hinzugefügt habe!
Kross

7

Probieren Sie das Element aus:

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

Das Deaktivieren eines Links funktioniert für mich in Chrome: http://jsfiddle.net/KeesCBakker/LGYpz/ .

Firefox scheint nicht gut zu spielen. Dieses Beispiel funktioniert:

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

Hinweis: Es wurde eine Live-Anweisung für zukünftige deaktivierte / aktivierte Links hinzugefügt.
Hinweis 2: 'live' in 'on' geändert.


6
Das neue Beispiel sollte auch in Firefox funktionieren. ;-) es ist ein Feuerfix: D
Kees C. Bakker

Chrome verhindert die Navigation in jsFiddle aufgrund von "Anzeige von Dokumenten verweigert, da Anzeige durch X-Frame-Optionen verboten ist." Tut mir leid, wenn das jsfiddle-Beispiel seltsame Dinge tut ;-)
Kees C. Bakker

Ich muss das Ankertag auch als deaktiviert anzeigen. Gleich wie im IE gezeigt. Außerdem möchte ich die Klickfunktion nicht ändern, um zu überprüfen, ob sie deaktiviert ist
Ankit

Der Show-Teil kann durch CSS und Hinzufügen einer Klasse erstellt werden, die ihn ausgegraut macht. Der Vorteil des "Live" -Klicks besteht darin, dass Sie das Problem für alle Links beheben. Wenn ich mehr helfen kann, lass es mich wissen. Ich hoffe, Sie werden Erfolg haben.
Kees C. Bakker

Versuchen Sie meine Antwort unten für eine vollständig browserübergreifende Lösung!
Jon Crawford

4

Bootstrap 4.1 bietet eine Klasse mit dem Namen disabledund dem aria-disabled="true"Attribut.

Beispiel"

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

Mehr ist auf getbootstrap.com

Wenn Sie es also dynamisch erstellen möchten und dann you don't want to care if it is button or ancorim JS-Skript so etwas benötigen

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

Aber sei vorsichtig

Die Lösung funktioniert nur bei Verknüpfungen mit Klassen btn btn-link.

Manchmal empfiehlt Bootstrap die Verwendung von card-linkclass. In diesem Fall funktioniert die Lösung nicht .


1

Ich habe die folgende Lösung gefunden, die entweder mit einem Attribut <a href="..." disabled="disabled">oder einer Klasse funktionieren kann <a href="..." class="disabled">:

CSS-Stile:

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

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

Javascript (in jQuery bereit):

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

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

0

Sie können einen Link nicht deaktivieren. Wenn Sie möchten, dass dieses Klickereignis nicht ausgelöst wird, dann einfach Removedas actionvon diesem Link.

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

Weitere Informationen: - Elemente, die deaktiviert werden können


1
Dadurch wird der Link nicht wirklich deaktiviert. Das Ankerelement wird weiterhin ausgelöst, obwohl es auf derselben Seite verbleibt.
Florian Margaine

0

Ich würde so etwas tun

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

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

so etwas sollte funktionieren. Sie fügen eine Klasse für Links hinzu, die deaktiviert werden sollen, und geben dann false zurück, wenn jemand darauf klickt. Um sie zu aktivieren, entfernen Sie einfach die Klasse.


Das würde nicht helfen. Ich muss das Klickereignis neu registrieren und die Funktion ist dynamisch und wird aufgerufen. Einmal entfernt, kann ich es nicht wieder
zuordnen

0

So deaktivieren Sie den Link für den Zugriff auf eine andere Seite auf dem Touch-Gerät:

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

Meine Antwort funktioniert auch auf dem Handy. Sehr browserübergreifend. Siehe unten.
Jon Crawford

Dies ist falsch, wenn Sie setAttribute('href', '');und die Seiten-URL http://example.com/page/?query=somethingder Link sind, auf den beim Klicken auf IE11 zugegriffen wird http://example.com/page/. Eine Problemumgehung könnte seinsetAttribute('href', '#');
Marco Demaio

0

In Razor (.cshtml) können Sie Folgendes tun:

@{
    var isDisabled = true;
}

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

-2

Sie können dies verwenden, um den Hyperlink von asp.net oder die Link-Schaltflächen in HTML zu deaktivieren.

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

-2

Es gibt einen anderen möglichen Weg und den, den ich am liebsten mag. Grundsätzlich ist es die gleiche Art und Weise, wie Lightbox eine ganze Seite deaktiviert, indem ein Div platziert und mit dem Z-Index herumgespielt wird. Hier sind relevante Ausschnitte aus einem meiner Projekte. Dies funktioniert in allen Browsern !!!!!

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

und in 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"/>

Der Resizer findet also die Positionen des Ankers (die Bilder sind nur Pfeile) und platziert den Disabler oben. Das Bild des Deaktivierers ist ein durchscheinendes graues Quadrat (ändern Sie die Breite / Höhe der Deaktivierer im HTML-Code entsprechend Ihrem Link), um anzuzeigen, dass es deaktiviert ist. Durch das Floating kann die Größe der Seite dynamisch geändert werden, und die Deaktivierer folgen in windowResizer (). Sie können geeignete Bilder über Google finden. Der Einfachheit halber habe ich das relevante CSS inline gestellt.

dann basierend auf einer Bedingung,

$('#backdisabler').css({'visibility':'hidden'});
$('#nextdisabler').css({'visibility':'visible'});

4
Nicht herabgestimmt, aber meine Vermutung: Zu viel Aufwand für eine einfache Sache, Ihr Code ist nicht genug kommentiert für eine Antwort auf SO. Es fühlt sich auch sehr hackig an, das würde ich persönlich nicht benutzen.
Emile Bergeron

-5

Ich denke, viele davon sind überlegt. Fügen Sie eine Klasse hinzu, wie Sie möchten disabled_link.
Stellen Sie dann sicher, dass das CSS .disabled_link { display: none }
Boom hat. Der Benutzer kann den Link nicht sehen, sodass Sie sich keine Sorgen machen müssen, dass er darauf klickt. Wenn sie etwas tun, um den anklickbaren Link zu erfüllen, entfernen Sie einfach die Klasse mit jQuery :
$("a.disabled_link").removeClass("super_disabled"). Boom geschafft!


Aus der Frage: "Und ich muss den Link im deaktivierten Modus anzeigen."
Marcelo

Ja, du hast recht. Das habe ich vermisst. Also würde ich stattdessen sagen, verschiebe den href-Wert auf data-href. $("td a").each(function(i,v){ $(this).data('href',this.href); $(this).attr('href','#').css('color','grey'); });Dann, wenn du einen nicht zu deaktivieren willst:$(this).attr('href',$(this).data('href')).css('color','blue');
Jordan Michael Rushing
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.