0

In our project currently I have the following problem. I have to bind some clicks to a list of elements locking like the following:

  <ul>
    <li class="listeelement" id="load-content-id-1"><div>listcontent</div></li>
    <li class="listeelement" id="load-content-id-2"><div>listcontent</div></li>
    <li class="listeelement" id="load-content-id-3"><div>listcontent</div></li>
    <li class="listeelement" id="load-content-id-4"><div>listcontent</div></li>
  </ul>

The click on .listelement should send a request to a specific action with specific params like element-id and something like that (-> module/action?id=1&something=something).

I want to write a generic request class that send the request and handle all things, that have to do with the click and the request and I'm not sure if it is a good way to bind the click unobtrusive to the class .listelement and to save the action and param information somewhere in my markup OR if it is much better to bind the click by the onclick="sendRequest(action, params)".

The obstrusive-onclick-solution seems to me much easier, but I'm not sure if it is also a GOOD solution.

Would be happy if someone could give an opinion to that.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
snirgel
  • 121
  • 1
  • 2
  • 9

2 Answers2

1

I would suggest use decent markup and not rely on onclick attributes. The biggest reason would be that it keeps your markup clean, and it also reduces byte-size over the wire vastly if you have a lot of these elements.

Also, I wouldn't encode values in the id attribute, as you can now legally use HTML5 data attributes and they are backwards compatible too.

<ul id="container">
    <li class=".." data-action="login" data-id="1" data-params="a=b">..</li>
    <li class=".." data-action="logout" data-id="2" data-params="c=d">..</li>
    ...
</ul>

Once you have the data in the markup, it's rather simple to setup the click handlers and connect it with the Request class.

var list = document.getElementById("container");
var items = list.getElementsByTagName("li");

for(var i = 0; i < items.length; i++) {
    items[i].onclick = (function(element) {
        return function() {
            var action = element.getAttribute('data-action');
            var id = element.getAttribute('data-id');
            var params = element.getAttribute('data-params');

            sendRequest(action, params);
        };
    })(items[i]);
}

If you have a lot of <li> elements, then event delegation may be a better approach instead of adding one handler for each element. Also, consider using DOM event registration model for adding handlers instead of the onclick property as that limits options to one handler maximum.

Anurag
  • 140,337
  • 36
  • 221
  • 257
  • I love this HTML5 solution. But currently we use xhtml, because we have to support all browser like ie7, etc.! So i need a solution that i can use in the 'old-school'-way :). – snirgel Jul 13 '10 at 10:00
  • I think you can still use the data attributes, hopefully :) See http://stackoverflow.com/questions/2412947/do-html5-custom-data-attributes-work-in-ie-6 and http://wiki.whatwg.org/wiki/HTML_vs._XHTML#Syntax_and_Parsing – Anurag Jul 13 '10 at 10:15
  • Thank you very much. Discussed that with my CTO and we agree, that this would be a good solution, but is it possible, that the element.dataset currently doesn't work in e.g. Firefox (tried it out with version 3.6.3 on ubuntu). At this time your parsing-for-data-attributes solution sounds a little bit to static for our needs, because you have generally to know, which data-attributes are set in the tag, because you can't get the whole dataset. Btw.: Did anyone/you try out this: http://www.orangesoda.net/jquery.dataset.html ? Sounds , as would this fix my problems?! – snirgel Jul 13 '10 at 12:05
0

Here's an option. Make the li's links <a> instead and put the controller/action as a querystring (or slash delimited key-value pairs if your back end can parse pretty URLs). Assuming you're doing an AJAX call, have some simple javascript that, on page load, hooks the click event for all <a> elements w/ a given class (you can pick something appropriate, like .ajax-link). In the handler, prevent the default action so the browser doesn't navigate to the href, and pluck the href, parse it, and configure an xhr with it and away you go. Not sure if you're using a library like jQuery, but that would lighten the load and the code a deal.

If you need to, you can nest the <a> inside the existing <li>.

This might help: JQuery parameter injection on bind/click vs. embedded click handlers with parameters

Community
  • 1
  • 1
jinglesthula
  • 4,446
  • 4
  • 45
  • 79