Making links with no href accessible

梦想与她 提交于 2019-11-29 13:19:15

To make a non-href A behave like an A (and be accessible), you'd have to add role=link, tabindex=0, style it to look like a real link, and add keyboard handler code to treat Return as a click. role="link" isn't sufficient; a screenreader may report it as a link, but without tabindex="0" and appropriate visual styles, a sighted user won't be able to tab to it in the first place, and without a keyboard event handler, only mouse users will be able to click it. (Technically screenreader users typically have hotkeys to simulate a mouse click; but keyboard-only sighted users generally don't have that option, so don't rely on it.)

Alternatively, if (big if!) the crazy script you're using allows for it, you could try shimming a 'keyboard click source' (my terminology) A just inside the original A: so where you have:

<a>foo</a>

you replace it with:

<a><a class='shim' href="javascript:void(0)">foo</a></a>

(The class='shim' is only needed if you need to do the event stuff described later...) You can do this in jQuery using something like: (borrowing from Jack's answer)

$("a:not([href])").wrapInner("<a class='shim' href='javascript:void(0)'></a>")

How this works is that the inner newly-added <a ...> has a href, so is exposed as a link and is tabbable. More importantly, if a user tabs to it and presses return, the default A behavior converts that keyboard input into a click event. This specific A has a href that returns undefined/void(0), so no actual navigation happens, but the click event will still bubble up to the original A, which gets to act on it.

(This is a neat pattern for allowing some parent element - often a DIV or similar - to handle click events, adding a child tabbable A that can source click events from keyboard gives you UI that's both mouse and keyboard usable.)

The big caveat here is that it assumes that your original script doesn't care about the target of the event. If that script does check this, it will get confused when it sees click events coming from the shim A's rather than the original As. One way to get around this is to capture and re-raise the event, which can be fiddly, and may only work on recent browsers - eg using something like:

// 'shim' class used so we can do this:
$("a.shim").click(function(e) {
    e.preventDefault();
    e.stopPropagation();

    // the following works if listener using jQuery or is setting onclick directly, otherwise...
    // $(e.target).parent().click();.

    // More general way to raise events; may need alternate for IE<9
    var e2 = document.createEvent("UIEvents");
    e2.initUIEvent("click", true, true, window, 1);
    e.target.parentNode.dispatchEvent(e2)
});

Whilst it's not very pretty, you can get at all anchors without a href attribute like so, using jQuery;

$("a:not([href])")

You can then just set the href attribute on those links to "#" and that should make them work again as regular links.

Here's a working JSFiddle

Sorry to reply with a jQuery solution...but doing this in regular JavaScript would be much more verbose.

Another way would be to give the anchors a role and then select them that way:

$("a[role='link']")
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!