Reputation: 30178
I have the following markup:
<li class="remove-filter-key-list-item" data-id="{{this.id}}">
<a
href="#"
class="remove-filter-key-button flx jst-cntr"
role="button"
tabindex=0
>
<img
class="remove-filter-key-list-icon"
src="{{this.icon}}"
alt="{{this.statusText}} icon"
/>
<span
class="remove-filter-key-list-title"
>{{this.statusText}}</span>
</a>
</li>
which is triggering this error in the firefox accessibility inspector:
From what I can gather, the link needs an onclick listener, a keydown listener, a tab index, and aprevent default
on both events. I've tried adding those, but the error persists. Firefox seems to be focused on the image inside the anchor link, not the link itself, which is the clickable thing.
I'm adding the listeners in a javascript file (I do not and can't add them inline in the html) as follows:
function addStatusFilterListener(el) {
el.addEventListener("click", onStatusFilterToggle);
el.addEventListener("keydown", (e) => {
e.preventDefault();
if (e.keycode === 32) {
//if spacebar
onStatusFilterToggle(e);
}
});
}
This doesn't seem to work though - the spacebar scrolls the page, and my event is not triggered, and it seems the accessibility inspector is looking for events on the contained img
tag. What's the proper way to structure this to resolve these issues?
Upvotes: 2
Views: 1884
Reputation: 24905
To save a lot of workarounds and fiddles the most straight forward solution is to wrap the image in a button rather than trying to make an anchor behave like a button.
This means that you don't have to worry about different handlers etc. as a click
event handler on a button has all the behaviour built in!
In the following example I changed your code to use a <button>
instead and added a data-id
just to alert to which item is clicked.
You will see that you can use Enter or Space to activate the item as well as a mouse click!
const removeBtn = document.querySelectorAll('.remove-filter-key-button');
removeBtn.forEach((element) => {
element.addEventListener('click', onStatusFilterToggle);
});
function onStatusFilterToggle(e){
let el = e.currentTarget;
let itemID = el.getAttribute('data-id');
alert("you pressed item: " + itemID);
}
button{
border: 0px;
background: transparent;
}
button:hover{
cursor: pointer;
opacity: 0.9;
}
<button class="remove-filter-key-button flx jst-cntr" data-id="1">
<img
class="remove-filter-key-list-icon"
src="https://picsum.photos/100/100"
alt="Some Alt Text icon"
/><br>
<span
class="remove-filter-key-list-title"
>Current Status</span>
</button>
<button class="remove-filter-key-button flx jst-cntr" data-id="2">
<img
class="remove-filter-key-list-icon"
src="https://picsum.photos/100/100"
alt="Some Alt Text icon"
/><br>
<span
class="remove-filter-key-list-title"
>Current Status</span>
</button>
Upvotes: 2
Reputation: 14837
Here are what I could say about your code:
<img/>
, the <span>
, or anything inside the link is going to create troubles; nested focusable or clickable elements create confusion because they aren't well understood by users and the actual events triggered isn't well defined and/or hard to handle well.Upvotes: 1