Как отключить ссылки 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');

Примечание. Я не могу отменить регистрацию функции щелчка для тега привязки, поскольку он регистрируется динамически. И я должен показать ссылку в отключенном режиме.


Ответы:


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>но браузеры не будут жаловаться на неизвестные атрибуты. Использование disabledатрибута IE будет игнорировать, pointer-eventsно оно будет учитывать специфический disabledатрибут IE ; другие CSS-совместимые браузеры будут игнорировать неизвестный disabled атрибут и честьpointer-events . Проще написать, чем объяснить:

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

Другой вариант для IE 11 - установить displayэлементы ссылки на blockили inline-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, проверьте условие (или сам атрибут 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()гораздо более понятен (спасибо Дейву Стюарту за этот совет). Пожалуйста, обратите внимание, что здесь я использую disabledатрибут нестандартным способом, если вы заботитесь об этом, тогда замените атрибут на класс и замените .is("[disabled]")на .hasClass("disabled")(добавление и удаление с помощью addClass()и removeClass()).

Золтан Тамаси отметил в комментарии, что «в некоторых случаях событие click уже связано с некоторой« реальной »функцией (например, с использованием knockoutjs). В этом случае упорядочение обработчика событий может вызвать некоторые проблемы. Поэтому я реализовал отключенные ссылки, связав возврат ложный обработчик по ссылке в touchstart, mousedownи keydownсобытия. он имеет некоторые недостатки (это предотвратит касание листания начало по ссылке)» , но обработка событий клавиатуры также имеет преимущество , чтобы предотвратить клавиатуры.

Обратите внимание, что если 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 Framework, вы можете увидеть, что отключенные ссылки не оформлены должным образом. Например, Bootstrap 3.x обрабатывает этот сценарий, и кнопка правильно стилизована как с помощью disabledатрибута, так и с помощью .disabledкласса. Если вместо этого вы очищаете ссылку (или используете один из других методов JavaScript), вы также должны обрабатывать стили, потому что <a>без hrefнего по-прежнему отображается как включенный.

Доступные многофункциональные интернет-приложения (ARIA)

Не забудьте также включить атрибут aria-disabled="true"вместе с disabledатрибутом / классом.


2
Правильно. Но для упрощения обслуживания я бы добавил обработчики событий щелчка ко всем td as, которые могут быть отключены, который будет вызывать, event.preventDefault()если $(this).data('disabled')true, и затем устанавливать data('disabled', true)любую ссылку, которую я хочу отключить (false, чтобы включить и т. Д.)
ori

1
@ Ankit Для внешнего вида у вас есть CSS! Настроить правило для «отключенных» ссылок, например: a [disabled] {color: grey}
Адриано Репетти,

1
Быстрое обновление по поддержке браузера . Обратите внимание, что, хотя IE11 поддерживает события указателя, есть небольшой кусочек, который говорит, что он не работает с ссылками: (...
Aug

1
$(this).is('[disabled]')может быть, лучший способ обнаружить отключенный атрибут
Дейв Стюарт,

2
Джон, мне это не очень нравится. Прежде всего, потому что клавиатурная навигация все еще работает. Во-вторых, потому что это хитрость (они могут быть полезны, только если ничего не работает). В-третьих, потому что некоторые люди держат Javascript отключенным, и в этом случае у вас нет «уровня» защиты. В-четвертых, потому что это самое сложное решение (когда может работать несколько строк Javascript)
Адриано Репетти,

23

Получил исправление в CSS.

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

Выше css при применении к тегу привязки будет отключено событие click.

Для подробной информации оформите ссылку


1
Это хорошее решение, но оно не поддерживается ... думаю ... Internet Explorer.
Адриано Репетти

Поддерживается всеми браузерами
Ankit

1
Он не должен поддерживаться для HTML в Internet Explorer и Opera.
Адриано Репетти

@ Анкит, это не работает в IE 9 и ниже. Вы используете IE 10?
Мандип Джейн

4
Это терпит неудачу сценарий использования событий клавиатуры, как упоминалось выше Адриано Репетти. Пользователь по-прежнему может перейти на ссылку и нажать Enter.
гремучая клетка

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

Класс 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

Но что, если нам нужно прямое решение 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();
    }
});

Примечание: добавлен оператор live для будущих отключенных / включенных ссылок.
Примечание 2: изменено «вживую» на «вкл».


6
Новый пример должен работать и в Firefox. ;-) это исправление: D
Kees C. Bakker

Chrome запрещает навигацию в jsFiddle из-за «Отказ в отображении документа, потому что отображение запрещено X-Frame-Options». Извините, если пример jsfiddle делает странные вещи ;-)
Kees C. Bakker

Я также должен показать тег привязки как отключенный. То же, что показано в IE. Кроме того, я не хочу изменять функцию щелчка, чтобы проверить, отключена ли она
Ankit

Шоу-часть может быть сделано css и добавлением класса, который делает его серым. Преимущество «живого» клика состоит в том, что вы решите проблему для всех ссылок. Если я могу помочь больше, просто дайте мне знать. Надеюсь, у вас все получится.
Кис К. Баккер

Попробуйте мой ответ ниже для полностью кросс-браузерного решения!
Джон Кроуфорд

4

Bootstrap 4.1 предоставляет класс с именем disabledи aria-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.

Иногда bootstrap рекомендует использовать 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

Вы не можете отключить ссылку, если вы хотите, чтобы событие щелчка не срабатывало, то просто Removeпо actionэтой ссылке.

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

Для получения дополнительной информации: - Элементы, которые могут быть отключены


1
Это действительно не отключает ссылку. Элемент привязки все равно сработает, даже если он останется на той же странице.
Флориан Маргэйн

0

Я бы сделал что-то вроде

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

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

как то так должно работать. Вы добавляете класс для ссылок, которые вы хотите отключить, а затем возвращаете false, когда кто-то нажимает на них. Чтобы включить их, просто удалите класс.


Это не поможет. Я должен заново зарегистрировать событие щелчка, и функция является динамической, которая вызывается. После удаления я не могу связать его обратно
Ankit

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', '#');
Марко Демайо

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

Есть еще один возможный способ, и тот, который мне нравится больше всего. По сути, это тот же самый способ, которым лайтбокс отключает целую страницу, помещая 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. Это также очень неприятно, я лично не стал бы этим пользоваться.
Эмиль Бержерон

-5

Я думаю, что многие из них задумались. Добавьте класс того, что вы хотите, как 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');
Джордан Майкл Рашинг
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.