108

I have an anchor link that I want to disable once the user clicks on it. Or, remove the anchor tag from around the text, but definitely keep the text.

<a href='' id='ThisLink'>some text</a>

I can do this easily with a button by adding .attr("disabled", "disabled");
I successfully added the disabled property, but the link was still clickable.
I don't really care if the text is underlined or not.

Any clue?

When you click on the wrong musician, it should just add "Wrong" and then become unclickable.
When you click and you are correct, it should add "Awesome" and then disable all <a> tags.

TylerH
  • 20,799
  • 66
  • 75
  • 101
Evik James
  • 10,335
  • 18
  • 71
  • 122

19 Answers19

210

The cleanest method would be to add a class with pointer-events:none when you want to disable a click. It would function like a normal label.

.disableClick{
    pointer-events: none;
}
mvinayakam
  • 2,808
  • 2
  • 18
  • 20
  • 20
    Using this idea a even easier way would be to use a[disabled] as selector for the css so you would not require to add the .disableClick class to the anchor – Ferran Salguero Nov 13 '13 at 19:06
  • 17
    Be careful though as you can still tab to things disabled with pointer-events: none – Mike Mellor Mar 03 '16 at 11:53
  • this solution is good for me in modern browsers. i have usable anchor tags that are bound to click events, and to discourage spamming them as their processes do their thing i programmatically add this and then remove it when the process is done. tabbing to a disabled anchor tag in my case isnt a concern either, but may be for others. YMMV – Stephen Tetreault Dec 12 '17 at 20:33
  • 2
    Using `pointer-events:none` will also disable `cursor`, title text, and other mouseover events. – ki9 Mar 20 '18 at 20:58
  • _the value none instructs the mouse event to go "through" the element and target whatever is "underneath" that element instead._ https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events That might be an issues on some layouts – user2988142 Oct 09 '18 at 10:21
  • True @user2988142. But the answer satisfies the requirements of the original poster. It would be bad design to have an anchor link on top of another clickable area. Would love to see functional design layouts with such issues. – mvinayakam Nov 22 '18 at 13:17
  • 2
    Pairing this with `tabindex="-1"` appears to satisfy all the use cases except for a click event being generated in JavaScript. – Jacob Stamm Mar 24 '21 at 14:02
  • Nice. I also added text-decoration: none to remove the underline. – arlomedia Aug 11 '21 at 05:02
39
<a href='javascript:void(0);'>some text</a>
Shiv Kumar Sah
  • 1,129
  • 1
  • 13
  • 17
  • 8
    Please explain your solution so that future visitors to this question will understand how it solves the problem at hand. – War10ck Feb 05 '14 at 15:05
  • 3
    From: [MDN: The void Operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/void). When a browser follows a `javascript: URI`, it evaluates the code in the URI and then replaces the contents of the page with the returned value, unless the returned value is `undefined`. The `void` operator can be used to return `undefined`. For example: `` `Click here to do nothing` `` Note, however, that the `javascript:` pseudo protocol is discouraged over other alternatives, such as unobtrusive event handlers. – Lenin May 27 '15 at 15:19
36

Use pointer-events CSS style. (as Jason MacDonald suggested)

See MDN https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events. Its supported in most browsers.

Simple adding "disabled" attribute to anchor will do the job if you have global CSS rule like following:

a[disabled], a[disabled]:hover {
   pointer-events: none;
   color: #e1e1e1;
}
meetar
  • 7,443
  • 8
  • 42
  • 73
vitrilo
  • 1,437
  • 16
  • 20
  • 3
    +1 for adding the styling through the [disabled] attribute rather than a class. It should be noted that pointer-events: none; doesn't work in anything older than IE11 though. – Daniel Tonon May 18 '16 at 05:43
  • All IEs has its own proprietary logic of disabling anchor, buttons and even other elements by default.This workaround needed for non-IE browsers. – vitrilo May 18 '16 at 11:16
  • 3
    +1. Just so I don't have to look it up again next time: required javascript (using jQuery) would be `$("#elementid").attr("disabled", "disabled");`. Also may be helpful to include `cursor: default` in the CSS (as suggested by Muhammad Nasir). – ASL Dec 02 '16 at 13:55
  • A elements don't have a *disabled* attribute, using it as a selector may or may not work. – RobG Jul 08 '17 at 08:35
  • This solution also works well with non-javascript dynamic templates found in frameworks like Django. Ex: ` %}disabled{% endif %}>` – Mike Clymer Sep 05 '17 at 17:19
  • 1
    Intuitive - good solution. I was actually surprised to find that `` elements don't have a disabled attribute - seems odd. – Morvael Mar 02 '18 at 09:04
14

I just realized what you were asking for(I hope). Here's an ugly solution

var preventClick = false;

$('#ThisLink').click(function(e) {
    $(this)
       .css('cursor', 'default')
       .css('text-decoration', 'none')

    if (!preventClick) {
        $(this).html($(this).html() + ' lalala');
    }

    preventClick = true;

    return false;
});
MSI
  • 1,124
  • 8
  • 23
  • This could actually really solve the problem, sort of... Instead of .click, use .on on the body and delegate to 'a[disabled]'. Then put the css code in the actual css using the same selector. Then, preventing click is as simple as event.preventDefault() and return false – lassombra May 18 '15 at 15:59
  • 3
    Disagree, use CSS "pointer-events: none;" instead, just like in other unswers. – vitrilo Mar 02 '16 at 11:48
12
$('a').removeAttr('href')

or

$('a').click(function(){ return false})

It depends on situation

James Khoury
  • 21,330
  • 4
  • 34
  • 65
Ashot
  • 640
  • 1
  • 6
  • 14
  • Removing the a via the removeAttr doesn't work for me. .removeAttr("href") http://www.awesomealbums.info/?WhoAmI – Evik James Oct 04 '11 at 23:00
11

Bootstrap provide us with .disabled class. Please use it.

But .disabled class only works when the 'a' tag already has class 'btn'. It doesn' t work on any old 'a' tag. The btn class may not be appropriate in some context as it has style connotations. Under the covers, the .disabled class sets pointer-events to none, so you can make CSS to do the same thing as Saroj Aryal and Vitrilo have sugested. (Thank you, Les Nightingill for this advice).

Yevgeniy Afanasyev
  • 37,872
  • 26
  • 173
  • 191
  • 3
    the .disabled class only works when the 'a' tag already has class 'btn'. It doesn' t work on any old 'a' tag. The 'btn' class may not be appropriate in some context as it has style connotations. Under the covers, the .disabled class sets pointer-events to none, so you can make css to do the same thing as Saroj Aryal and Vitrilo have sugested. – Les Nightingill Jun 28 '17 at 21:13
  • Thank you for your detailed comment. It clarifies a lot for many users. May I use some text from your comment to extend my answer? – Yevgeniy Afanasyev Jun 30 '17 at 04:43
9

Add a css class:

.disable_a_href{
    pointer-events: none;
}

Add this jquery:

$("#ThisLink").addClass("disable_a_href"); 
Shubh
  • 6,693
  • 9
  • 48
  • 83
Jason MacDonald
  • 109
  • 1
  • 3
5

The best way is to prevent the default action. In the case of anchor tag, the default behavior is redirecting to href specified address.

So following javascript works best in the situation:

$('#ThisLink').click(function(e)
{
    e.preventDefault();
});
Kedar.Aitawdekar
  • 2,364
  • 1
  • 23
  • 25
4

Jason MacDonald comments worked for me, tested in Chrome, Mozila and IE.

Added gray color to show disable effect.

.disable_a_href{
    pointer-events: none;
    **color:#c0c0c0 !important;**
}

Jquery was selecting only first element in the anchor list, added meta character (*) to select and disable all element with id #ThisLink.

$("#ThisLink*").addClass("disable_a_href"); 
Pankaj
  • 401
  • 1
  • 6
  • 16
4

Write this a single line of jQuery Code

$('.hyperlink').css('pointer-events','none');

if you want to write in css file

.hyperlink{
    pointer-events: none;
}
Douwe de Haan
  • 6,247
  • 1
  • 30
  • 45
Shaik Md N Rasool
  • 484
  • 1
  • 5
  • 13
4

You could use the onclick event to disable the click action:

<a href='' id='ThisLink' onclick='return false'>some text</a>

Or you could just use something other than an <a> tag.

Polynomial
  • 27,674
  • 12
  • 80
  • 107
4

Just remove the href attribute from the anchor tag.

Explosion Pills
  • 188,624
  • 52
  • 326
  • 405
3

Create following class in style sheet :

  .ThisLink{
           pointer-events: none;
           cursor: default;
    }

Add this class to you link dynamically as follow.

 <a href='' id='elemID'>some text</a>

    //   or using jquery
<script>
    $('#elemID').addClass('ThisLink');
 </script>
Muhammad Nasir
  • 2,126
  • 4
  • 35
  • 63
2

This is the method I used to disable.Hope it helps.

$("#ThisLink").attr("href","javascript:;");
Black Mamba
  • 13,632
  • 6
  • 82
  • 105
1

Simply in SASS:

.some_class{
     // styles...

     &.active {
       pointer-events:none;
     }
}
Paul Roub
  • 36,322
  • 27
  • 84
  • 93
  • Although this code may answer the question, providing additional context regarding _why_ and/or _how_ it answers the question would significantly improve its long-term value. Please [edit] your answer to add some explanation. – Toby Speight May 20 '16 at 14:37
1

Never trust the browser because the user can change the page in any way without the server's knowledge.

If a link is to work only once, the first thing you need to do is make sure that server side the click is accepted only once (with an onetime token specified as querystring for example), because the URL present in the href attribute can be copied by the user and inserted in the navigation bar of the browser and runned multiple times.

On the javascript side, the safest thing you can do is completely replace the <a> link with another tag, preserving the content:

/** Replace element, preserving attributes and moving descendant nodes from the previous one.
 *
 * @param {HTMLElement} element Element to be replaced changing tag.
 * @param {String} new_tag New element tag.
 * @return {HTMLElement} New created element.
 */
function rename_element_tag(element, new_tag) {
    let new_block = document.createElement(new_tag);
    for (let j = 0; j < element.attributes.length; ++j)
        new_block.setAttribute(element.attributes[j].name, element.attributes[j].value);

    $(new_block).insertAfter(element);
    while (element.childNodes.length > 0)
        new_block.appendChild(element.childNodes[0]);

    $(element).remove();

    return new_block;
}

This function replaces the passed element in place by "modifying" the tag, and preserves attributes and content by iterating all child nodes via vanilla javascript instead of jQuery to handle text nodes as well.

In your case you must skip the href attribute.

Marco Sacchi
  • 712
  • 6
  • 21
1

Try this:

$('a').contents().unwrap();
Hari Pachuveetil
  • 10,294
  • 3
  • 45
  • 68
-2
$('#ThisLink').one('click',function(){
  $(this).bind('click',function(){
    return false;
  });
});

This would be another way to do this, the handler with return false, which will disable the link, will be added after one click.

GNi33
  • 4,459
  • 2
  • 31
  • 44
-4

The easyest way

In your html:

<a id="foo" disabled="true">xxxxx<a>

In your js:

$('#foo').attr("disabled", false);

If you use it as attribute works perfectly

Nathre
  • 27
  • 8