【问题标题】:How to disable HTML links如何禁用 HTML 链接
【发布时间】:2012-05-03 19:18:06
【问题描述】:

我在<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');

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

【问题讨论】:

标签: javascript jquery html css


【解决方案1】:

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

CSS方式

当大多数浏览器都支持它时,这应该是正确的方式(但见后文):

a.disabled {
    pointer-events: none;
}

例如,Bootstrap 3.x 就是这样做的。目前(2016 年)只有 Chrome、FireFox 和 Opera(19+)支持它。 Internet Explorer 从版本 11 开始支持此功能,但 not for links 但是它可以在外部元素中使用,例如:

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

与:

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

解决方法

我们可能需要为pointer-events: none 定义一个CSS 类,但是如果我们重用 disabled 属性而不是CSS 类会怎样?严格来说,disabled 不支持 &lt;a&gt;,但浏览器不会抱怨 unknown 属性。使用 disabled 属性 IE 将忽略 pointer-events 但它会尊重 IE 特定的 disabled 属性;其他符合 CSS 的浏览器将忽略 unknown 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 中更改。

拦截点击

对 JavaScript 函数使用 href,检查条件(或 disabled 属性本身),以防万一。

$("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() 和@987654357 @)。

Zoltán Tamási noted in a comment “在某些情况下,点击事件已经绑定到一些“真实”功能(例如使用 knockoutjs)在这种情况下,事件处理程序排序可能会导致一些麻烦。因此我实现了禁用通过将返回 false 处理程序绑定到链接的 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");
});

我个人不太喜欢这种解决方案(如果您不必对禁用的链接做更多的事情),但它可能更兼容,因为跟踪链接的方式多种多样。

虚假点击处理程序

return false 的位置添加/删除onclick 函数,链接将不会被跟踪。要禁用链接:

$("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 技术之一),您还必须处理样式,因为没有 href&lt;a&gt; 仍被绘制为启用。

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

不要忘记将属性aria-disabled="true"disabled 属性/类一起包含。

【讨论】:

  • 对。但为了便于维护,我会将点击事件处理程序添加到所有可能被禁用的td as,如果$(this).data('disabled') 为真,它将调用event.preventDefault(),然后将data('disabled', true) 设置为我想要禁用的任何链接(假启用等)
  • @Ankit 外观你有 CSS!为这样的“禁用”链接设置规则 a[disabled] { color: gray }
  • 快速更新browser-support。请注意,即使 IE11 支持指针事件,也有一个小消息说它在链接上不起作用:(...
  • $(this).is('[disabled]') 可能是检测禁用属性的更好方法
  • 乔恩,我不太喜欢。首先,因为键盘导航仍然有效。其次,因为这是一个技巧(它们只有在没有其他方法的情况下才有用)。第三,因为有些人禁用 Javascript,在这种情况下,您没有任何“级别”的保护。第四,因为它是这里最复杂的解决方案(当少数 Javascript 行可能工作时)
【解决方案2】:

在 css 中得到了修复。

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

以上css应用到锚标签时会禁用点击事件。

详情请查看link

【讨论】:

  • 这是一个不错的解决方案,但它不受...猜测...Internet Explorer 的支持。
  • 所有浏览器都支持
  • Internet Explorer 和 Opera 中的 HTML 不应该支持它。
  • @Ankit,它在 IE 9 及以下版本中不起作用。您使用的是 IE 10 吗?
  • 这使键盘事件用例失败,正如 Adriano Repetti 上面提到的那样。用户仍然可以跳到链接并按回车键。
【解决方案3】:

感谢所有发布解决方案的人(尤其是@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 解决方案呢?请参阅下面的答案。
  • 那你就用我刚刚加的ES2015类吧!
【解决方案4】:

试试元素:

$(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”。

【讨论】:

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

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>

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

【讨论】:

    【解决方案6】:

    我最终得到了下面的解决方案,它可以使用属性&lt;a href="..." disabled="disabled"&gt; 或类&lt;a href="..." class="disabled"&gt;

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

    【讨论】:

      【解决方案7】:

      只需添加一个 css 属性:

      <style>   
      a {
       pointer-events: none;
      }
      </style>
      

      这样做可以禁用锚标记。

      【讨论】:

        【解决方案8】:

        您可以禁用 HTML 链接,如下所示:

        <style>
            .disabled-link {
                pointer-events: none;
            }
        </style>
        <a href="https://google.com" class="disabled-link">Google.com</a>
        

        您可以使用内联 JavaScript:

        <a href="javascript:void(0)">Google.com</a>
        

        【讨论】:

          【解决方案9】:

          您不能禁用链接,如果您希望点击事件不触发,那么只需从该链接Remove action

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

          更多信息:- Elements that can be Disabled

          【讨论】:

          • 这并没有真正禁用链接。锚元素仍然会触发,即使它会保留在同一页面上。
          【解决方案10】:

          我会做类似的事情

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

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

          【讨论】:

          • 这无济于事。我必须重新注册点击事件,并且调用的函数是动态的。删除后,我无法将其重新关联
          【解决方案11】:

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

          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', '#');
          【解决方案12】:

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

          【讨论】:

            【解决方案13】:

            我建议将链接变成一个按钮并使用“禁用”属性。您可以查看此问题以检查如何将链接转换为按钮:How to create an HTML button that acts like a link

            【讨论】:

              【解决方案14】:

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

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

              【讨论】:

                【解决方案15】:

                还有另一种可能的方法,也是我最喜欢的一种。基本上,这与灯箱禁用整个页面的方式相同,方法是放置一个 div 并摆弄 z-index。这是我的一个项目中的相关sn-ps。 这适用于所有浏览器!!!!!!

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

                【讨论】:

                • 没有被否决,但我的猜测是:对于一件简单的事情来说开销太大,您的代码没有足够的评论来回答 SO。它也感觉很hacky,我个人不会使用它。
                【解决方案16】:

                我认为其中很多都是过度思考。添加任何你想要的类,比如disabled_link
                然后让css有.disabled_link { display: none }
                Boom 现在用户看不到链接,因此您不必担心他们会点击它。如果他们做了一些事情来满足可点击的链接,只需使用 jQuery 删除该类:
                $("a.disabled_link").removeClass("super_disabled")。大功告成!

                【讨论】:

                • 来自问题:“我必须在禁用模式下显示链接。”
                • 是的,你是对的。我错过了。所以我会说,将 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');
                猜你喜欢
                • 1970-01-01
                • 2015-07-18
                • 2012-08-14
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2020-07-09
                • 1970-01-01
                相关资源
                最近更新 更多