3
<a (click)="searchExample()" tabindex="0">JavaScript</a>

When I navigate through focusable elements in web page using Tab key, element is also focused since tabindex attribute is set to "0". But not able to click it using Space or Enter key. Is there any solution?

Prime
  • 2,809
  • 1
  • 7
  • 23
  • Hmm is the issue that you're using an `a` element when you should really be using a `button`? For accessibility purposes, I don't believe an anchor tag should do anything but be a real link. If you're using a click handler, it should be a button (you can style the button exactly like a link if you need). – Nick Feb 22 '21 at 03:22
  • Try giving it [`href="javascript: void(0)"`](https://stackoverflow.com/questions/1291942/what-does-javascriptvoid0-mean) to make it a functional link: `JavaScript` – Hao Wu Feb 22 '21 at 03:23
  • 1
    JavaScript is not valid HTML. You cannot use parentheses in an HTML attribute name. Are you using a web framework like Angular or React? If so, which one? – BMiner Feb 22 '21 at 04:14
  • I am using Angular – Prime Feb 22 '21 at 08:18

3 Answers3

7

Short Answer

To call a function you should use a <button> and an Event Listener. Use buttons for same page interactivity (calling JS functions) and use <a href="some-location"... for anything that causes the URL to update (navigation to a new page or to a location in the current document).

This is important for usability!

Longer Answer

As you have marked this accessibility I will focus on that.

Any anchor <a> must have a valid href to be focusable and work as a hyperlink.

I have seen people offering the advice of <a href="javascript:void(0)", never do this, this is an anti-pattern.

Also <a href="#" is also an anti-pattern as it does not provide any navigation.

This is all a hangover from HTML4 where you couldn't style a <button> element and a bad practice that just needs to go away now.

So what should I use?

If you are trying to make something that a user can interact with on the same page (something that calls a JavaScript function) then use a <button>.

If you are trying make something that causes navigation (either to a new page or to a place in the current document) then use a valid anchor <a href="some-location">Some Location</a> or <a href="#document-fragment">Place in current document</a>.

Why does it matter?

For users of assistive technology (mainly screen reader users) the type of element used is important. The use of the correct element for the job is known as semantics.

An anchor with a valid href tells a screen reader user "Clicking this will result in navigation". It also lets them know that they need to press Enter to activate the link.

A <button> on the other hand tells a screen reader user "I will perform an action on this page". It also lets them know that they can press `Enter or Space to activate the button.

This expected behaviour is essential for a screen reader user to not get confused or frustrated while using your website / web app.

It also helps with SEO, makes your mark-up easier to understand etc.

So how to call a function from a page?

First as I said, use a <button>.

Rather than inlining the click handler, add it in your JS file.

In the below example I gave the button an id="searchJavaScript and then used document.querySelector('#searchJavaScript'); to grab that button.

In reality you would use a better selector within querySelector based on your mark-up.

Then we use .addEventListener('click' to listen for any click events on that button.

You can learn more about addEventListener here.

let jsButton = document.querySelector('#searchJavaScript');


jsButton.addEventListener('click', function(){
    alert("You clicked the JavaScript Search Button");
});
<button id="searchJavaScript">JavaScript</button>

But I need to do something before navigation occurs?

It should still be a valid anchor!

If you need to run some function before navigation occurs we can still easily do that with event.preventDefault().

You should still have a valid hyperlink.

let link = document.querySelector('a');

link.addEventListener('click', function(e){
    e.preventDefault();
    console.log("I will appear before navigation so you can set up whatever you need");
    alert("I will appear before navigation");
    window.location.href = this.href;    
});
<a href="https://google.com">Go to Google but run a function first</a>
GrahamTheDev
  • 22,724
  • 2
  • 32
  • 64
0

Focus + enter will trigger the click event, but only if the anchor has an href attribute (at least in some browsers, like latest Firefox). Done it using jQuery. Works:

$(document).keypress(function(e) {
    if ((e.keyCode || e.which) == 13) {
        // Enter key pressed
        $('a').trigger('click');
    }
});

$('a').click(function(e) {
    e.preventDefault();
    alert("The link was clicked.");
});
<html>
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  </head>
  <body>
    <a href="#">Some Link</a>
  </body>
</html>

Now click enter on anywhere in the document, you will get the link doing its function!

0

It's not working because you didn't add the keyboard functionality there. Simply add the (keypress) event and it will work. Something like this:

<a (click)="searchExample()" (keypress)="searchExample()"  tabindex="0">JavaScript</a>

Also please note that anchor tags (<a></a>) DO NOT NEED TABINDEX=0

The anchor tag will be in the focus order even if you remove tabindex because that's how they work. 
Srikar Phani Kumar M
  • 1,069
  • 1
  • 3
  • 8