views:

1515

answers:

10

It seems pretty common to want to let your javascript know a particular dom node corresponds to a record in the database. So, how do you do it?

One way I've seen that's pretty common is to use a class for the type and an id for the id:

<div class="thing" id="5">
<script> myThing = select(".thing#5") </script>

There's a slight html standards issue with this though -- if you have more than one type of record on the page, you may end up duplicating IDs. But that doesn't do anything bad, does it?

An alternative is to use data attributes:

<div data-thing-id="5">
<script> myThing = select("[data-thing-id=5]") </script>

This gets around the duplicate IDs problem, but it does mean you have to deal with attributes instead of IDs, which is sometimes more difficult. What do you guys think?

+12  A: 
<div class="thing" id="myapp-thing-5"/>

// Get thing on the page for a particular ID
var myThing = select("#myapp-thing-5");

// Get ID for the first thing on the page
var thing_id = /myapp-thing-(\d+)/.exec ($('.thing')[0].id)[1];
John Millikin
Definitely do it this way. Selecting by ID is the fastest way to select an element (until all browsers adopt native class selection functions)
John Sheehan
This solution seems to be very performance-intensive on large datasets. //downvote.
roosteronacid
+3  A: 

Considering the fact that you can have multiple classes per element, couldn't you create a unique identifier as an additional class per element? That way, there could be more than one element with the same "id" without HTML ID attribute collisions.

<div class="thing myapp-thing-5" />
<div class="thing myapp-thing-668" />
<div class="thing myapp-thing-5" />

It would be easy to then find these nodes, and find their corresponding DB record with a little string manipulation.

Zack Mulgrew
Remember that selecting by class is much slower than selecting by ID
John Sheehan
@John: But if you have duplicated IDs, you wouldn't be able to use `document.getElementById`.
Matthew Crumley
I wasn't advocating using multiple IDs, just keep in mind that selecting by class is slower in non-modern browsers (it won't be slower for much longer)
John Sheehan
+5  A: 

You'll be giving up some control of the DOM

True, nothing will explode, but it's bad practice. If you put duplicate ids on the page you'll basically loose the ability to be sure about what you're getting when you try to access an element by its id.

var whoKnows = document.getElementById('duplicateId');

The behavior is actually different, depending on the browser. In any case, you can use classNames for duplicate values, and you'll be avoiding the problem altogether.

The browser will try to overlook faults in your markup, but things become messy and more difficult. The best thing to do is keep your markup valid. You can describe both the type of the element and its unique database id in a className. You could even use multiple classNames to differentiate between them. There are a lot of valid possibilities:

<div class="friend04"/>
<div class="featuredFriend04" />

or

<div class="friend friend04" />
<div class="featuredFriend friend04" />

or

<div class="friend objectId04" />
<div class="groupMember objectId04" />

or

<div class="friend objectId04" />
<div class="friend objectId04" id="featured" />

These are all completely legitimate & valid snippets of XHTML. Notice how, in the last snippet, that I've still got an id working for me, which is nice. Accessing elements by their id is very quick and easy, so you definitely want to be able to leverage it when you can.

You'll already spend enough of your time in javascript making sure that you've got the right values and types. Putting duplicate ids on the page will just make things harder for you. If you can find ways to write standards-compliant markup, it has many practical benefits.

keparo
A: 

Non-standard attributes are fine, if you're using XHTML and take the time to extend the DTD you're using to cover the new attributes. Personally, I'd just use a more unique id, like some of the other people have suggested.

Matthew Scharley
+14  A: 

Note that an ID cannot start with a digit, so:

<div class="thing" id="5">

is invalid HTML. See http://stackoverflow.com/questions/70579/what-is-a-valid-value-for-id-attributes-in-html#70586

In your case, I would use ID's like thing5 or thing.5.

Peter Hilton
+1  A: 

In HTML5, you could do it like this:


<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <script>
            window.addEventListener("DOMContentLoaded", function() {
                var thing5 = document.evaluate('//*[@data-thing="5"]', 
                document, null, XPathResult.FIRST_ORDERED_NODE_TYPE ,null);
                alert(thing5.singleNodeValue.textContent);
            }, false);
        </script>
    </head>
    <body>
        <div data-thing="5">test</div>
    </body>
</html>
Shadow2531
+5  A: 

IDs should be unique according to the standards and whilst most browsers don't barf when handed duplicate IDs it would not be a good idea to rely on that always being the case.

Making the ID unique by adding a type name to the ID would work but you need to ask why you need it. Giving an element an id is very useful when the element needs to be found, getElementById is very fast. The reason its fast it that most browsers will build an index of IDs as its loads the DOM. However if you have zillions of IDs that you never actually need to use in something like getElementById then you've incurred a cost that is never paid back.

I think you may find most of the time you want the object ID in an event fired by the element or one of its children. In which case I would use an additional attribute on the element and not the ID attribute.

I would leave class attribute to do what its meant to do and not overload it with identification duties.

AnthonyWJones
A: 

I don't like John Millikin's solution. It's gonna be performance-intensive on large datasets.

An optimization on his code could be replacing the regular expression with a call to substring() since the first few characters of the id-property are constant.

I'd go with matching class and then a specific id though.

roosteronacid
I don't see how that solution is gonna be more performance-intensive, as you'll never do anything more than you'll do with other solutions (where the ways mentioned employs an overhead with a library !-)
roenving
I'm guessing you mean LESS performance-intensive. In that case:
roosteronacid
The optimization of John Millikin's code, I'm proposing IS less performance-intensive. Doing a substring() call versus a call to the regex object is cheaper. Also; He's evaluating the expression every time he wants to extract an ID.
roosteronacid
Also: jQuery takes advantage of the native document.getElementsByClassName function (which I bellieve is implemented in WebKit aswell). John Millikin's solution does not.
roosteronacid
Ah, I misunderstood you, but basically I would use .getElementById because you have all necessary information at hand to do it that way
roenving
A: 

If you set non-standard properties, be sure to either set them programmatically (as everything will be legal that way) or go through the trouble of revising the dtd !-)

But I would use an ID with a meaningful word prepending the DB-id and then use .getElementById, as every necessary informtion is at hand ...

roenving
A: 

Keeping track of your data via the DOM seems shaky to me; remember, those IDs are global variables, so if there's any chance somebody else's script can find its way onto your page, it's vulnerable. For best results, load your data into an object within an anonymous function and write the table (or the big nested list of DIVs) afterwards.

Kent Brewster