19

So I am working on a project that requires a <div> with an onclick event. I've got the main functionality working, but there is one problem. I need the onclick event to happen when the user tabs to the <div> and presses enter. I added a tabindex to the <div> which allows it to gain focus, but nothing happens when the user presses enter (or any other key).

Can anyone help me with this? Or is what I want not even possible?

Here is a jsfiddle demonstrating my problem. http://jsfiddle.net/logiwan992/suwq7r09/

Thank you in advance for any help.

lfitzgibbons
  • 625
  • 1
  • 4
  • 17
  • Send your code please.!!! – Mxx persian Sep 18 '15 at 18:52
  • @Mxxpersian: It's in the JSFiddle. – D4V1D Sep 18 '15 at 18:53
  • Learn about [.focus()](https://api.jquery.com/focus/). – D4V1D Sep 18 '15 at 18:53
  • This work fine For me !!!! – Mxx persian Sep 18 '15 at 18:55
  • Wrap that div in an anchor dog. It's more semantic and will simplify your code. – Matthew Darnell Sep 18 '15 at 19:02
  • 1
    @MatthewDarnell How is using an anchor in this case more semantic? – Jacob Sep 18 '15 at 19:11
  • @divinecomedian screenreaders don't know you're attaching anchor-like functionality to a div (unless you start adding ARIA markup to tell them about it... but an anchor is easier) – Daniel Beck Sep 18 '15 at 19:29
  • Because and anchor has assumed click functionality. A screen reader doesn't know when you attached a click handler to an element. The browser doesn't know you can tab to the element unless you add a tab index. So after you add a click and focus handler, alter the HTML to include an incorrect tab index (is that DIV really the first thing the user should tab to on the page?) add in all the aria tags to get screen readers to understand that the element should be treated like an anchor, what are you left with? Seems easier to add another element or just change the DIV itself to an anchor. – Matthew Darnell Sep 18 '15 at 19:35
  • @MatthewDarnell I see. You definitely make a good case for making the code easier. But how do you know the OP wants the `div` to be semantically equivalent to an anchor? He didn't mention using it to link to a resource, which is what anchors are for, so it wouldn't be more semantic. – Jacob Sep 18 '15 at 19:44
  • The more semantic option would be a ` – lfitzgibbons Sep 18 '15 at 19:45
  • If you have to keep with a div with onclick then you can add a onkeypress with the same command to accept keyboard input – Viking NM Sep 25 '19 at 19:34

5 Answers5

44

I note the question is tagged WCAG and "accessibility".

The answer to your question is therefore "don't do that." The other answers on this page will all work fine, for everyone except the people who need it to work, i.e. those using screenreaders or other assistive technology. None of the javascript-based solutions here are WCAG compliant.

What you want is a <button>. That gives you your tabindex and keyboard control for free.

You can also force a <div> to work like a <button> by adding ARIA markup (though it's better and easier to just use the tag that already does what you need it to do.)

If absolutely necessary, a good introduction to using ARIA for pseudo-buttons is here: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_button_role

The gist of it is, you need to add the role="button" attribute, and manage the state of the aria-pressed attribute manually (by capturing key events and clicks in javascript; other answers have covered this pretty thoroughly so I won't repeat the details)

Daniel Beck
  • 16,972
  • 5
  • 29
  • 49
  • 2
    The problem here is that I am working with legacy code. If I change the `
    ` to a `
    – lfitzgibbons Sep 18 '15 at 19:43
  • 3
    If you're working with legacy code then I'm willing to bet the whole darn thing is inaccessible. – Jacob Sep 18 '15 at 19:48
  • 1
    @Logiwan992 : A ` – Stephen P Sep 18 '15 at 21:43
  • *I note the question is tagged WCAG and "accessibility". The answer to your question is therefore "don't do that."* Oh my god, you read my mind... – Adam Sep 19 '15 at 12:08
  • @Logiwan992 I added some more info about ARIA -- I really suspect you'll find it less work to use a ` – Daniel Beck Sep 20 '15 at 14:55
  • 4
    I did end up changing it to a ` – lfitzgibbons Sep 25 '15 at 18:51
3

It is perfectly fine to have a <div> work like a button provided you specify the right ARIA tags, roles, and keyboard events. That's the whole point of ARIA.

I do agree, though, that when possible you should use the native html elements. That's the first rule of ARIA use - http://www.w3.org/TR/aria-in-html/#notes-on-aria-use-in-html. But I understand that's not always possible.

There was a mention of using focus(). That's incorrect. Focus() is used to move the focus to the object. It's not used to handle an event. Now perhaps they meant onFocus(), which is an event triggered when the object receives focus, but that's still not the right event to trap for. You don't want a button (whether implemented as a <div> or a <button>) to perform its function just because you tabbed to it. The user has to click or press enter/space on it.

Please look at the authoring practices which define the keyboard behavior for a button, http://www.w3.org/TR/wai-aria-practices/#button, as well as the section that talks about keyboard events, http://www.w3.org/TR/wai-aria-practices/#focus_tabindex. In particular, note that you should not rely on keypress. Not all browsers send that event.

Anytime you press a key, three possible events might happen: Keydown, keypress, keyup. Keydown and keyup are supported on all browsers and have access to event.keyCode. Keypress is supported on some browser and has access to event.charCode.

There's a significant different between keyCode and charCode, especially if you're trying to implement shortcut keys such as Ctrl+/. Many non-US keyboards have special keys in different places on the keyboard and you get different keyCodes for them. But that's a topic for another discussion.

slugolicious
  • 8,671
  • 1
  • 20
  • 30
1

The "onclick" attribute has a specific behavior on links, because it can be triggered with the enter key.

See the following WCAG failure: http://www.w3.org/TR/WCAG20-TECHS/F59.html

You have to take care of the "role" of the element.

The following page illustrates how you can make an "accessible link" from a "span": https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_link_role

Also, as already said, best way is relying on a button/a element when possible.

Adam
  • 15,932
  • 27
  • 48
0

Try to bind the keypress event on the said div and detect if Enter key was pressed (which has code number 13).

var div = document.getElementsByTagName('div');
div[0].addEventListener('keypress', function(e) {
    if(e.keyCode == 13) {
        alert('div focused');   
    }
});

Working JSFiddle


You can, alternatively, use jQuery also:

jQuery(function($) {

    $('div').on('keypress', function(e) {
        if(e.keyCode == 13) {
            alert('div focused'); 
        }
    });

});

Working JSFiddle

D4V1D
  • 5,517
  • 3
  • 27
  • 58
  • this solution would require jQuery (not sure it was an original requirement) - but it should work with TAB (keycode '9') not ENTER – blurfus Sep 18 '15 at 18:56
  • @ochi: Fair enough, I haven't noticed that jQuery was not in the OP tags. – D4V1D Sep 18 '15 at 18:57
  • I would like it to work without JQuery if at all possible, but I do want it to work with ENTER. First the div receives focus from TAB and then ENTER acts like a click on the div. – lfitzgibbons Sep 18 '15 at 18:59
  • @ochi: Sure, but the OP wants to detect the press of the `Enter` key **on** the `div`. Element must have focus for the event handler to fire anyway so no need to detect `focus` or `TAB` key. – D4V1D Sep 18 '15 at 19:05
  • If it works with `Enter` it should also work with `Space` ... when using keyboard navigation either one of those will activate a button or link. – Stephen P Sep 18 '15 at 21:08
  • @StephenP: I'm not really that much into accessibility. Next time, I'll give more time into reading the tags linked to the question :) – D4V1D Sep 18 '15 at 21:10
  • @D4V1D : I'm into keeping my fingers on the keyboard because it's faster than reaching for the mouse, so I tab-then-space a lot to get to a button and press it - for example, type something in a field, tab to the submit button, press space when the button has focus. And _**that's**_ why I know this behavior. – Stephen P Sep 18 '15 at 21:39
-2

Use the same event handler for both events. If the event is keypress verify the key pressed is the Enter key before executing.

var divButton = document.querySelector('#div-button');

divButton.addEventListener('click', activate);
divButton.addEventListener('keypress', activate);

function activate(e) {
  if (e.type === 'keypress' && e.keyCode == 13) {
    alert('activated the div'); 
  }
};
div {
    outline: 1px solid black;
}

div:focus {
    outline: 1px solid red;
}
<div id="div-button" tabindex="0">
    <h1>This is my div!</h1>
</div>    
Jacob
  • 2,209
  • 1
  • 9
  • 17