Associating data to a DOM element for jQuery
Asked Answered
N

4

5

In a previous life, I might have done something like this:

<a href="#" onclick="f(311);return false;">Click</a><br/>
<a href="#" onclick="f(412);return false;">Click</a><br/>
<a href="#" onclick="f(583);return false;">Click</a><br/>
<a href="#" onclick="f(624);return false;">Click</a><br/>

Now with jQuery, I might do something like this:

<a class="clicker" alt="311">Click</a><br/>
<a class="clicker" alt="412">Click</a><br/>
<a class="clicker" alt="583">Click</a><br/>
<a class="clicker" alt="624">Click</a><br/>

<script language="javascript" type="text/javascript">
    $(".clicker").bind("click", function(e) {
        e.preventDefault();
        f($(this).attr("alt"));
    });
</script>

Except that using the alt attribute to pass the data from the DOM to jQuery feels like a hack, since that's not its intended purpose. What's the best practice here for storing/hiding data in the DOM for jQuery to access?

Navar answered 12/12, 2008 at 22:45 Comment(0)
S
3

JQuery.data lets you associate a dictionary to a DOM element. This data can be set via jQuery:

<a class="clicker">Click</a><br/>
<a class="clicker">Click</a><br/>
<a class="clicker">Click</a><br/>
<a class="clicker">Click</a><br/>

<script language="javascript" type="text/javascript">
    var values = new Array("311", "412", "583", "624");
    $(".clicker").each(function(i, e) {
       $(this).data('value', values[i]).click(function(e) { 
         f($(this).data('value'));
       });
    });
</script>

or (since jQuery 1.4.3) using the HTML5 data- attributes, which work even in non-HTML5 documents:

<a class="clicker" data-value="311">Click</a><br/>
<a class="clicker" data-value="412">Click</a><br/>
<a class="clicker" data-value="583">Click</a><br/>
<a class="clicker" data-value="624">Click</a><br/>

<script language="javascript" type="text/javascript">
    $(".clicker").click(function(e) { 
       f($(this).data('value'));
    });
</script>
Scandalize answered 12/12, 2008 at 23:9 Comment(4)
This looks fragile to me. You are depending on an arbitrary coherence in the ordering between two different collections -- one data, one markup. I can't see using it in this case.Wizard
Agreed. If I'm going to continue in this route, the metadata plugin seems the way to go.Navar
You're assuming ordering matters in this example? All the links are the same! How you set the data isn't really relevant to the question, IMO. You'd need some more context to answer that - are the links generated, where's the data from, who generates them, do they actually point somewhere, etc.Scandalize
Using another jQuery plugin to solve a problem isn't really the best option. Yes, it does the job, but John Sheehan's answer below is the better one. Don't overload yourself with code if you don't have to.Nit
M
4

You could use an id attribute like "clicker-123" then parse out the number. I usually do that or use the 'rel' attribute.

So, in essence, there is no better way to do it that I know of. I hope this thread proves me wrong.

Menon answered 12/12, 2008 at 22:47 Comment(1)
For simplicity, and in the event of non HTML5 documents, this is indeed the better answer than the one selected. Got my vote!Nit
U
4

You'll best use a new feature of HTML5: the data-...-attribute.

Your html-code will look like this:

<a class="clicker" data-mynumber="311">Click</a>

Then you can use el.attr('data-mynumber') to get the data.

Instead of mynumber, you can choose any name.

This works in all browsers.

Unipersonal answered 25/4, 2010 at 19:32 Comment(1)
Theres a nice jQuery helper for accessing HTML5 data attributes: $(el).data('mynumber');Mot
S
3

JQuery.data lets you associate a dictionary to a DOM element. This data can be set via jQuery:

<a class="clicker">Click</a><br/>
<a class="clicker">Click</a><br/>
<a class="clicker">Click</a><br/>
<a class="clicker">Click</a><br/>

<script language="javascript" type="text/javascript">
    var values = new Array("311", "412", "583", "624");
    $(".clicker").each(function(i, e) {
       $(this).data('value', values[i]).click(function(e) { 
         f($(this).data('value'));
       });
    });
</script>

or (since jQuery 1.4.3) using the HTML5 data- attributes, which work even in non-HTML5 documents:

<a class="clicker" data-value="311">Click</a><br/>
<a class="clicker" data-value="412">Click</a><br/>
<a class="clicker" data-value="583">Click</a><br/>
<a class="clicker" data-value="624">Click</a><br/>

<script language="javascript" type="text/javascript">
    $(".clicker").click(function(e) { 
       f($(this).data('value'));
    });
</script>
Scandalize answered 12/12, 2008 at 23:9 Comment(4)
This looks fragile to me. You are depending on an arbitrary coherence in the ordering between two different collections -- one data, one markup. I can't see using it in this case.Wizard
Agreed. If I'm going to continue in this route, the metadata plugin seems the way to go.Navar
You're assuming ordering matters in this example? All the links are the same! How you set the data isn't really relevant to the question, IMO. You'd need some more context to answer that - are the links generated, where's the data from, who generates them, do they actually point somewhere, etc.Scandalize
Using another jQuery plugin to solve a problem isn't really the best option. Yes, it does the job, but John Sheehan's answer below is the better one. Don't overload yourself with code if you don't have to.Nit
W
1

I'm sorry, but if you are already filling in the alt tag, I fail to see how delaying the assignment of the onclick handler to jQuery actually buys you anything. Isn't this just a case of "Now that I have a hammer, every problem looks like a nail." I think the jquery method is best used when the action does not depend on extra data than what can naturally be derived from the content, for example, class definition, tag type, etc.

Wizard answered 12/12, 2008 at 23:14 Comment(1)
In this case my clicker opens a UI modal dialog. When does the onclick assignment execute? If before jQuery ready, then onclick could run before the dialog is ready; if after, then I'm not delaying it at all.Navar

© 2022 - 2024 — McMap. All rights reserved.