Як відключити HTML-посилання


263

У мене є кнопка посилання всередині, <td>яку я повинен відключити. Це працює на IE, але не працює у Firefox та Chrome. Структура - Посилання всередині a <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.

Перехоплення кліків

Використовуйте hrefфункцію JavaScript, перевірте стан (або сам атрибут вимкнено) і нічого не робити в разі.

$("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()).

Золтан Тамасі зазначив у коментарі, що "в деяких випадках подія клацання вже пов'язана з якоюсь" реальною "функцією (наприклад, з використанням 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;
}

Якщо ви використовуєте рамку інтерфейсу користувача, можливо, ви побачите, що відключені посилання неправильно оформлені. Наприклад, Bootstrap 3.x, обробляє цей сценарій, і кнопка правильно стильована як з disabledатрибутом, так і з .disabledкласом. Якщо замість цього ви очищаєте посилання (або використовуєте одну з інших методик JavaScript), ви також повинні керувати стилізацією, оскільки <a>без hrefтексту все ще пофарбовано як включено.

Доступні додатки для багатого Інтернету (ARIA)

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


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

1
@Ankit Для появи у вас є CSS! Налаштуйте правило для таких "відключених" посилань, як ця [відключена] {color: grey}
Adriano Repetti

1
Швидке оновлення на підтримку браузера . Зауважте, що навіть якщо IE11 підтримує покажчики-події, є невеликий підказки, який говорить, що він не працює на посиланнях: (...
серпень

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

2
Джон, мені це не дуже подобається. Перш за все тому, що навігація по клавіатурі все ще працює. По-друге, тому що це трюк (їм це може бути корисно, лише якщо нічого іншого не виходить). По-третє, тому що деякі люди залишають Javascript відключеним, і в цьому випадку у вас немає "рівня" захисту. По-четверте, тому що це найскладніше рішення (коли може працювати декілька ліній JavaScript)
Адріано Репетті

23

Отримав виправлення в css.

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

Наведений вище css при застосуванні до тега прив’язки буде відключати подію натискання.

Ознайомтесь із деталями за цим посиланням


1
Це приємне рішення, але його не підтримує ... здогадуйтесь ... Internet Explorer.
Адріано Репетті

Його підтримують усі браузери
Ankit

1
Він не повинен підтримуватися для HTML в Internet Explorer та Opera.
Адріано Репетті

@Ankit, це не працює в IE 9 і нижче. Ви використовуєте IE 10?
Mandeep Jain

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

Клас скриньки:

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

Chrome перешкоджає навігації в jsFiddle через "Відмовлено у відображенні документа, оскільки показ заборонений для параметрів X-Frame." Вибачте, якщо приклад jsfiddle робить дивні речі ;-)
Kees C. Bakker

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

Шоу-частину можна виконати за допомогою css та додавання класу, що робить його сірим. Перевага "живого" клацання полягає в тому, що ви вирішите проблему для всіх посилань. Якщо я можу допомогти більше, просто дайте мені знати. Сподіваюся, вам вдасться.
Kees C. Bakker

Спробуйте мою відповідь нижче для повністю перехресного рішення браузера!
Джон Кроуфорд

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.

Іноді завантажувальна програма рекомендує використовувати 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
Це дійсно не відключає посилання. Елемент якоря все одно буде спрацьовувати, хоча він залишиться на одній сторінці.
Флоріан Маргайн

0

Я б робив щось подібне

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

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

щось подібне повинно працювати. Ви додаєте клас для посилань, які ви хочете відключити, а потім повертаєте помилкові, коли хтось клацає на них. Щоб увімкнути їх, просто видаліть клас.


Це не допомогло б. Я повинен перереєструвати подію натискання, і функція є динамічною, яка викликається. Після видалення я не можу пов’язати це назад
Анкіт

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-індекс. Тут є відповідні фрагменти з мого проекту. Це працює у всіх браузерах !!!!!

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
Не підкреслив, але я здогадуюсь: занадто багато накладних витрат на просту річ, ваш код недостатньо коментований для відповіді на ТАК. Це також дуже хакі, я особисто не використовував би це.
Еміль Бержерон

-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');
Джордан Майкл Rushing
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.