2

I have a list of elements that act as a menu (not a nav for a site, and I've ruled out using the menu tag as it has limited support):

<ul>
    <li><img src="open-file.png"></li>
    <li><img src="delete-file.png"></li>
    ....

When you click on each one, javascript does something.

What would be the best markup to have, should each li contain a button tag:

<li><button><img src="open-file.png"></button></li>

Or should each li be an anchor:

<li><a href="#"><img src="open-file.png"></a></li>

Or something else?

What is semantically correct here?

Jamie Barker
  • 8,145
  • 3
  • 29
  • 64
panthro
  • 22,779
  • 66
  • 183
  • 324

4 Answers4

3

The usual rules for Unobtrusive JavaScript apply.

Start with something that works. Progressively enhance it with JS.


Can you fallback to a link? i.e. if the JS fails, will following a link be a sensible fallback? If so: use a link.

(<a href="#">, which is a link to the top of the page, is a bad solution for just about everything other than JS that smoothly scrolls the browser to the top of the page.)

Can you fallback to a form submission? i.e. if the JS fails, would you be able to get a similar enough effect by simply submitting a form? Use a submit button in a form.

Is there no way to fallback to something that will work without JavaScript? Use a button.

Ideally, generate that button using JS so it won't be shown to people for whom it definitely will not work.


<img src="open-file.png">

As an aside. The only content of your control is going to be an image, and you have to communicate what the control does to the user, so you really should have an alt attribute.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • Thanks. If the image was inside a button tag, could I just give the button tag a title atr? Instead of the alt. – panthro Apr 20 '15 at 16:06
  • Advisory information about the button isn't a good substitute for text that communicates the same message as the image. The alt is highly preferable. – Quentin Apr 20 '15 at 16:11
  • While this is very good information, the question seems less about JavaScript and more about HTML semantics. – Trevor Apr 21 '15 at 16:19
1

Semantically, it depends. You mentioned that clicking on one of the menu items will trigger some JavaScript, so I'm going to guess that the more semantic approach would be to use buttons instead of anchor tags. Here's the reasoning:

  • Anchor tags are for navigating a user to a resource or document
  • Buttons are for other actions, such as changing the state of the current page in some way (submitting or resetting a form, etc.)

See this article from David Walsh.

Trevor
  • 13,085
  • 13
  • 76
  • 99
0

First, as I'm new to StackOverflow, I'm not sure if this is the proper way to do this.

Quenton's answer above is a good one. You should consider what these controls will do and use proper links for non-JS support. There's enough people that feel more comfortable having JS turned off to warrant it.

As for handling the JavaScript, classes are a good way as stated above. To expand on that, you can have several classes per element as well. For example:

<li class="MenuItem"><a herf="/path/to/action" class="MenuAction MenuAction_Open">(text or image here)</a></li>

This way you can use a class for specific menu actions while also using CSS to stylize things uniformly.

I would also recommend taking a look at JQuery. If you're going to be doing a lot of JavaScript, it makes the process much more simple.

There is a good tutorial on JQuery here: W3 Schools

Keenan
  • 179
  • 1
  • 9
  • I would appreciate if down-voters could let me know what I did to deserve the down-vote. I'd rather learn than remain ignorant. :) – Keenan Apr 21 '15 at 04:39
  • Unfortunately the down-voters aren't so considerate. I can only suggest possible reasons for your down-vote: (A) You have a link to a website but don't quote the text in your answer as the link may die. (B) It sort of repeats what others have already said. Personally I don't think your answer warranted a down-vote though so I'm going to negate it. – Jamie Barker Apr 21 '15 at 09:31
  • Thank you. I admit, I wanted to comment instead, but being new I only have a few options available to me. – Keenan Apr 21 '15 at 15:15
-1

The general consensus in the front-end dev world (IMO) is to add something like a class to your element and then apply a listener.

Have a backup link to run your action without JavaScript (if you so wish - putting #null in the href will just make it do nothing), and then add event.preventDefault(); to the events to prevent them from doing the default action of navigating to the other page so your JavaScript can run.

Example HTML:

<ul>
    <li><a href="?action=open" class="open"><img src="open-file.png" alt="Open File" /></a></li>
    <li><a href="?action=close" class="delete"><img src="delete-file.png" alt="Delete File" /></a></li>
</ul>

Example jQuery:

$('li.open').on('click', function(event) {
    event.preventDefault();
    console.log('Open clicked');
});
$('li.delete').on('click', function(event) {
    event.preventDefault();
    console.log('Delete clicked');
});

Example raw JavaScript:

document.getElementsByClassName('open')[0].addEventListener('click', function(event) {
    event.preventDefault();
    console.log('Open clicked');
});
document.getElementsByClassName('delete')[0].addEventListener('click', function(event) {
    event.preventDefault();
    console.log('Delete clicked');
});
Jamie Barker
  • 8,145
  • 3
  • 29
  • 64
  • Don't do that. By default list items are not interactive elements. You've just made it impossible to activate the control without a pointing device (e.g. a mouse). Many people do depend on tabbing through a page in order to access controls. – Quentin Apr 20 '15 at 15:42
  • @Quentin Updated based upon your comment. – Jamie Barker Apr 20 '15 at 16:02