如何禁用HTML链接


263

我有一个<td>必须禁用的链接按钮。这适用于IE,但不适用于Firefox和Chrome。结构是-内的链接<td>。我无法在中添加任何容器<td>(例如div / span)

我尝试了以下所有方法,但无法在Firefox上运行(使用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');

注意-我无法取消注册锚标记的click功能,因为它是动态注册的。而且我必须在禁用模式下显示链接。


Answers:


510

您不能(以便携式方式)禁用链接。您可以使用其中一种技术(每一种都有其自身的优点和缺点)。

CSS方式

当大多数浏览器都支持它时,这应该是正确的方法(但请参阅后面):

a.disabled {
    pointer-events: none;
}

例如,Bootstrap 3.x就是这样做的。目前(2016年)只有Chrome,FireFox和Opera(19岁以上)才得到很好的支持。Internet Explorer从版本11开始支持此功能,但不支持链接,但是它在外部元素中可用,例如:

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

带有:

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

解决方法

我们可能需要为其定义CSS类,pointer-events: none但是如果我们重用disabled属性而不是CSS类该怎么办?严格来说disabled不支持,<a>但浏览器不会抱怨未知属性。使用disabledIE属性将被忽略,pointer-events但将支持IE特定的disabled属性。其他CSS兼容的浏览器将忽略未知 disabled属性和荣誉pointer-events。写起来比解释起来容易:

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

IE 11的另一种选择是将display链接元素设置为blockinline-block

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

请注意,这可能是便携式的如果您需要支持IE(并且可以更改HTML)解决方案,但是...

所有这些都请注意,pointer-events仅禁用...指针事件。链接仍可通过键盘导航那么您还需要应用此处介绍的其他技术之一。

焦点

结合上述CSS技术,您可以tabindex以非标准方式使用,以防止元素被聚焦:

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

我从未检查过它与许多浏览器的兼容性,因此您可能需要在使用此功能之前对其进行测试。它具有无需JavaScript即可工作的优势。不幸的(但很明显)tabindex不能从CSS更改。

拦截点击

使用hrefJavaScript函数,检查条件(或禁用的属性本身),以防万一。

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

要禁用链接,请执行以下操作:

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

要重新启用它们:

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

如果您愿意使用而不是.is("[disabled]")使用它.attr("disabled") != undefinedundefined当未设置属性时,jQuery 1.6+将始终返回),但is()更加清晰(感谢Dave Stewart的技巧)。请注意,这里我disabled以非标准的方式使用属性,如果您对此很在意,则将属性替换为类,然后将其替换.is("[disabled]").hasClass("disabled")(使用addClass()和添加和删​​除removeClass())。

ZoltánTamási 在评论中指出:“在某些情况下,单击事件已绑定到某些“实际”功能(例如,使用基因敲除js)。在这种情况下,事件处理程序的排序可能会引起一些麻烦。因此,我通过绑定返回来实现禁用的链接假处理程序的链接的touchstartmousedownkeydown事件。它也有一些缺点(它会阻止触摸滚动开始链接)”,但在处理键盘事件,还具有防止键盘导航的好处。

请注意,如果 href未清除,则用户可以手动访问该页面。

清除链接

清除href属性。使用此代码,您无需添加事件处理程序,但可以更改链接本身。使用此代码可禁用链接:

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

然后重新启用它们:

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

我个人不太喜欢这种解决方案(如果您不必对禁用的链接做更多的事情),但是由于遵循链接的方式多种多样,因此它可能更具兼容性。

假点击处理程序

onclick在您添加/删除功能的地方return false,将不会跟随链接。禁用链接:

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

要重新启用它们:

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

我认为没有理由更喜欢这种解决方案而不是第一个解决方案。

造型

样式更加简单,无论您使用哪种解决方案来禁用链接,我们都添加了disabled属性,因此您可以使用以下CSS规则:

a[disabled] {
    color: gray;
}

如果您使用的是类而不是属性:

a.disabled {
    color: gray;
}

如果您使用的是UI框架,则可能会看到禁用链接的样式不正确。例如,Bootstrap 3.x可以处理这种情况,并且可以使用disabled属性和.disabled类对按钮进行正确的样式设置。相反,如果您要清除链接(或使用其他JavaScript技术之一),则还必须处理样式,因为一个<a>不带href的仍被标记为启用。

可访问的富Internet应用程序(ARIA)

不要忘了还包括一个属性aria-disabled="true"连同disabled属性/类。


2
对。但是为了便于维护,我会向所有td a可能被禁用的s 添加单击事件处理程序,event.preventDefault()如果事件$(this).data('disabled')为true,则将调用它,然后将其设置data('disabled', true)为我想禁用的任何链接(启用false等等)
ori 2012年

1
@Ankit外观上有CSS!为这样的“禁用”链接设置规则[a [disabled] {color:grey}
Adriano Repetti 2012年

1
浏览器支持快速更新。请注意,即使IE11支持指针事件,也有一个小提示表明它不适用于链接:(...
2014年

1
$(this).is('[disabled]')也许是检测禁用属性的更好方法
Dave Stewart

2
乔恩,我不太喜欢。首先,因为键盘导航仍然有效。其次,因为这是一个技巧(它们只有在没有其他作用的情况下才有用)。第三,因为有些人禁用了Javascript,在这种情况下,您没有任何“级别”的保护。第四,因为它是这里最复杂的解决方案(当很少的Java语言行可能起作用时)
Adriano Repetti

23

在CSS中得到修复。

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

在CSS上方应用到锚标记后,将禁用click事件。

有关详细信息,请查看此链接


1
这是一个不错的解决方案,但...猜测... Internet Explorer不支持。
Adriano Repetti 2012年

它的浏览器支持
ANKIT

1
Internet Explorer和Opera中的HTML不应该支持它。
阿德里亚诺·雷佩蒂

@Ankit,它在IE 9及以下版本中不起作用。您正在使用IE 10吗?
Mandeep Jain

4
正如Adriano Repetti前面提到的,这使键盘事件用例失败。用户仍然可以跳至链接,然后按Enter。
笼子响尾蛇,2016年

12

感谢每个发布解决方案的人(尤其是@AdrianoRepetti),我结合了多种方法来提供一些更高级的disabled功能(它可以跨浏览器运行)。下面的代码(ES2015和coffeescript均根据您的喜好)。

这提供了多个防御级别,因此标记为“禁用”的锚实际上具有这种作用。使用这种方法,您将获得以下锚点:

  • 点击
  • 转到并点击返回
  • 切换到它会把焦点移到下一个可聚焦元素
  • 它知道是否随后启用了锚点

如何

  1. 包括此CSS,因为它是第一道防线。假设您使用的选择器是a.disabled

    a.disabled {
      pointer-events: none;
      cursor: default;
    }
  2. 接下来,在就绪时实例化此类(使用可选选择器):

      new AnchorDisabler()

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

咖啡课:

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

但是,如果我们需要直接的jQuery / javascript解决方案怎么办?请参阅下面的答案。
乔恩·克劳福德

1
好吧,那么您使用我刚刚添加的ES2015类!
克罗斯

7

尝试元素:

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

在Chrome浏览器中,禁用链接对我有用:http : //jsfiddle.net/KeesCBakker/LGYpz/

Firefox似乎运行不佳。此示例有效:

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

注意:为以后的禁用/启用链接添加了“活动”语句。
注意2:将“实时”更改为“开启”。


6
新示例也应在Firefox中运行。;-)这是一个修复程序:D
Kees C. Bakker

由于“由于X-Frame-Options禁止显示,拒绝显示文档,” Chrome阻止了jsFiddle中的导航。抱歉,如果jsfiddle示例产生奇怪的事情;-)
Kees C. Bakker

我还必须将锚标记显示为已禁用。与IE中显示的相同。另外,我不想修改单击功能以检查是否已禁用
Ankit 2012年

显示部分可以通过css并添加一个使其变灰的类来完成。“实时”点击的优点是,您将解决所有链接的问题。如果我可以提供更多帮助,请告诉我。希望你能成功。
Kees C. Bakker

请在下面尝试我的答案,以获得完全跨浏览器的解决方案!
乔恩·克劳福德

4

Bootstrap 4.1提供了一个名为disabledaria-disabled="true"属性的类。

例”

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

更多内容在getbootstrap.com上

因此,如果您想动态制作它,并且you don't want to care if it is button or ancor比在JS脚本中需要类似的东西

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

但是要小心

该解决方案仅适用于具有类的链接btn btn-link

有时引导程序建议使用card-link类,在这种情况下,解决方案将不起作用


1

我得到了下面的解决方案,该解决方案可以与属性<a href="..." disabled="disabled">,或类一起使用<a href="..." class="disabled">

CSS样式:

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

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

Javascript(在jQuery中已准备就绪):

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

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

0

你不能禁用链接,如果你想要一个单击事件不应该那么火简单Removeaction从该链接。

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

有关更多信息:- 可以禁用的元素


1
这并没有真正禁用链接。即使锚元素仍保留在同一页面上,它仍将触发。
Florian Margaine '04年

0

我会做类似的事情

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

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

这样的事情应该起作用。您为要禁用的链接添加一个类,然后当有人单击它们时返回false。要启用它们,只需删除该类。


这无济于事。我必须重新注册click事件,并且该函数是动态的,称为动态函数。移除后,我将无法将其重新关联
Ankit 2012年

0

要禁用链接以访问触摸设备上的另一个页面:

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

我的回答也适用于移动设备。非常跨浏览器。见下文。
乔恩·克劳福德

这是错误的,如果您setAttribute('href', '');和页面url是http://example.com/page/?query=something单击IE11时的链接将转到http://example.com/page/。可以使用一种解决方法setAttribute('href', '#');
Marco Demaio,

0

在Razor(.cshtml)中,您可以执行以下操作:

@{
    var isDisabled = true;
}

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

-2

您可以使用它禁用asp.net的超链接或html中的链接按钮。

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

-2

还有另一种可能的方式,而我最喜欢这种方式。基本上,这与lightbox通过放置div并摆弄z-index来禁用整个页面的方式相同。这是我的一个项目的相关摘要。这适用于所有浏览器!

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

和在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"/>

因此,调整程序会找到锚点(图像只是箭头)的位置,并将禁用器放置在顶部。禁用者的图像是半透明的灰色正方形(在html中更改禁用者的宽度/高度以匹配您的链接)以表明它已被禁用。浮动允许页面动态调整大小,并且禁用者将在windowResizer()中跟进。您可以通过Google找到合适的图片。为了简单起见,我将相关的CSS内联了。

然后基于某种条件

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

4
并没有降低投票率,但我的猜测是:对于一件简单的事情而言,开销太大了,您的代码没有得到足够的注释,无法获得SO的答案。它也感觉很hacky,我个人不会使用它。
Emile Bergeron

-5

我认为其中许多都超出了思考范围。添加任何您想要的类,例如disabled_link
然后,使CSS .disabled_link { display: none }
现在具有Boom,用户将看不到该链接,因此您不必担心他们单击它。如果他们做了某些事情来满足可单击的链接,只需使用jQuery:删除该类
$("a.disabled_link").removeClass("super_disabled")。繁荣!


从问题开始:“而且我必须在禁用模式下显示链接。”
Marcelo 2014年

是的,你是对的。我错过了。因此,我要说的是,将href值移动到data-href。 $("td a").each(function(i,v){ $(this).data('href',this.href); $(this).attr('href','#').css('color','grey'); });然后,当您想要禁用它时:$(this).attr('href',$(this).data('href')).css('color','blue');
Jordan Michael Rushing
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.