简体   繁体   中英

Semantically “correct” way to select multiple elements in jQuery?

I often use classes as a means to identify a related set of elements, for example:

<input value="10" class="sum-this" />
<input value="20" class="sum-this" />
<input value="30" class="sum-this" />

The sum-this class has no CSS, and isn't defined in any CSS files -it's simply used in some jQuery - for example:

var total = 0;
$(".sum-this").each(function(i, el){
  total += parseInt($(el).val());
});
console.log(total); // 60?

Is there a correct way to do this? Should I use another attribute? rel or data-* ?

As @Pointy and @JustinPowell have stated in the comments, this is completely valid. In fact, it's also explicitely stated in the W3C HTML4 specification that using class attributes for purposes other than selecting style is completely valid. I quote:

The class attribute, on the other hand, assigns one or more class names to an element; the element may be said to belong to these classes. A class name may be shared by several element instances. The class attribute has several roles in HTML:

  • As a style sheet selector (when an author wishes to assign style information to a set of elements).
  • For general purpose processing by user agents.

However, HTML5 also added the custom data-* attributes (where * is a custom string) for this purpose.


LINKS

  1. A blog post discussing your question
  2. W3C HTML4 attributes
  3. W3C HTML 5 data attribute

As said in the comments, it's perfectly fine to use classes in the JavaScript only. But here's a suggestion: when my colleagues want to use a class for this purpose only, they prefix it by 'js-' in order to distinguish classes used for styling from classes made for JS.

While your code is syntactically valid using classes and there's nothing wrong with it, since you're looking for something that's semantically correct I'd recommend data attributes . Classes are really meant to be used for styling while data attribtes were created "with extensibility in mind for data that should be associated with a particular element but need not have any defined meaning. "

You could write your HTML like:

<input value="10" data-item="sum-this" />
<input value="20" data-item="sum-this" />
<input value="30" data-item="sum-this" />

And your jQuery like:

var total = 0;
$('input[data-item="sum-this"]').each(function(i, el){
  total += parseInt($(el).val());
});
console.log(total);

jQuery selector optimization is less important than it used to be, as more browsers implement getElementsByClassName, querySelector and querySelectorAll which parses CSS syntax.

So the burden of selection shifts from jQuery to the browser and now jQuery supports most CSS3 selectors, as well as some non-standard selectors and you can choose the selector you want to work with.

However, there are still some tips to keep in mind:

  1. Use an ID if Possible
  2. Avoid Selecting by Class Only
  3. Avoid overly complex selectors
  4. Increase Specificity from Left to Right
  5. Avoid Selector Repetition

As everyone else has said, it's entirely appropriate to class elements for the purposes of javascript only.

In the example that you give, the alternative to collecting these elements:

<input value="10" class="sum-this" />
<input value="20" class="sum-this" />
<input value="30" class="sum-this" />

with:

document.querySelectorAll('.sum-this'); (or $('.sum-this') in jQuery)

might be to collect these elements:

<input value="10" />
<input value="20" />
<input value="30" />

with:

document.querySelectorAll('input[value]');

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM