如何禁用 HTML 链接

IT技术 javascript jquery html css
2021-01-31 12:55:08

我在 a 中有一个链接按钮<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');

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

6个回答

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

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>但浏览器不会抱怨未知属性。使用disabled属性 IE 将忽略,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") != undefined(jQuery 1.6+ 将undefined在未设置属性时始终返回)但is()更加清晰(感谢 Dave Stewart 提供此提示)。请注意,这里我使用的disabled属性在非标准的方式,如果你在乎这个,然后用一个类替换属性和替换.is("[disabled]").hasClass("disabled")(添加与删除addClass()removeClass())。

Zoltán Tamási在评论指出“在某些情况下,click 事件已经绑定到某个“真实”函数(例如使用 Knockoutjs)在这种情况下,事件处理程序的排序可能会导致一些麻烦。因此我通过绑定返回来实现禁用链接链接的touchstart,mousedownkeydown事件的错误处理程序。它有一些缺点(它会阻止在链接上开始触摸滚动)”但处理键盘事件也有防止键盘导航的好处。

请注意,如果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属性/类。

对。但是为了更容易维护,我会向所有td a可能被禁用的 s添加点击事件处理程序,event.preventDefault()如果$(this).data('disabled')为真,它将调用,然后设置data('disabled', true)为我想要禁用的任何链接(假启用等)
2021-03-18 12:55:08
$(this).is('[disabled]') 可能是检测禁用属性的更好方法
2021-03-23 12:55:08
乔恩,我不太喜欢它。首先,因为键盘导航仍然有效。其次,因为这是一个技巧(它们可能只有在没有其他任何效果的情况下才有用)。第三,因为有些人禁用 Javascript,在这种情况下,您没有任何“级别”的保护。第四,因为它是这里最复杂的解决方案(当很少有 Javascript 行可以工作时)
2021-03-23 12:55:08
浏览器支持的快速更新请注意,尽管 IE11 支持指针事件,但有一个小花絮说它不适用于链接:(...
2021-04-02 12:55:08
@Ankit 对于外观,您有 CSS!为这样的“禁用”链接设置规则 a[disabled] { color: gray }
2021-04-05 12:55:08

在 css 中得到了修复。

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

当应用于锚标记时,上面的 css 将禁用单击事件。

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

所有浏览器都支持它
2021-03-17 12:55:08
正如 Adriano Repetti 上面提到的那样,这使键盘事件用例失败。用户仍然可以使用 Tab 键切换到链接并按 Enter。
2021-04-03 12:55:08
这是一个不错的解决方案,但它不受...猜测...Internet Explorer 的支持。
2021-04-05 12:55:08
@Ankit,它在 IE 9 及以下版本中不起作用。您使用的是 IE 10 吗?
2021-04-05 12:55:08
Internet Explorer 和 Opera 中的 HTML 不应该支持它。
2021-04-08 12:55:08

感谢发布解决方案的每个人(尤其是@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 解决方案呢?请看我下面的回答。
2021-03-20 12:55:08
好吧,那你就用我刚刚添加的 ES2015 类吧!
2021-04-05 12:55:08

尝试元素:

$(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:将'live'改为'on'。

Chrome 阻止在 jsFiddle 中导航,因为“拒绝显示文档,因为 X-Frame-Options 禁止显示”。抱歉,如果 jsfiddle 示例做了奇怪的事情;-)
2021-03-18 12:55:08
新示例也应该适用于 Firefox。;-) 这是一个固件:D
2021-03-19 12:55:08
显示部分可以通过 css 完成并添加一个使其变灰的类。“实时”点击的优点是您将解决所有链接的问题。如果我能提供更多帮助,请告诉我。希望你会成功。
2021-03-20 12:55:08
试试我下面的答案以获得完全跨浏览器的解决方案!
2021-04-01 12:55:08
我还必须将锚标记显示为禁用状态。与 IE 中显示的相同。另外我不想修改点击功能来检查它是否被禁用
2021-04-03 12:55:08

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类,在这种情况下解决方案将不起作用