views:

95

answers:

3

I have been tasked with improving the current mess that is our JavaScript "strategy"; we're an online shopping company and my boss has given me time to do this properly. He is very keen on keepin this modular and increase the reusability of the components.

Our HTML is being rendered with JSP and we have lots of custom tags writing out, for example, information about products without the web designers needing to worry about it.

Now, we want to do similar things with JavaScript. The web designers should be given a set of custom tags, like, say,

<foo:draggable> 
 ... some HTML here ...
</foo:draggable>

that will wrap the HTML in a <div> with a drag bar at the top and a close button.

My idea is to mark the div with a unique namespaced CSS class name, like foo_draggable, and then put all my functions in a single JS file. That JS file then sees if there are elements with the CSS class foo_draggable in the DOM and if it finds any it will attach the required event handlers.

However, I am worried about scaling problems, and wondering whether it is a good idea to have lots of selector queries running when they quite often aren't going to be used.

The first alternative would be to initiate each draggable item explicitly but that would mean putting <script> tags all over the place. The second approach would be to not put all UI function in one file but rather just download the ones I need, but that would mean lots more HTTP requests and slower page load speed.

Has anyone got experience with this?

+3  A: 

What about having two classnames?

<div class='foo fooDragable'></div>
<div class='foo fooSortable'></div>

You add the class 'foo' to all your elements that require javascript modification. Your javascript has to check the dom only once for foo.

var $foo = $('.foo');

Afterwards you can search within this array which should be way smaller than the complete dom.

var $dragAble = $foo.filter('.fooDragable');
Ghommey
Please, Javascript != jQuery.
BalusC
you know, this is a really good idea ... +1 :-)
Joel Martinez
Very clever solution. Shame I didn't think of it myself.
Lenni
jQuery > Javascript, jQuery is what javascript should have been.
Chris Marisic
I would say that jQuery is what the DOM/browser environment should have been. It doesn't change the language at all, just how you interact with the browser. I'm probably just being pedantic, but I do a lot of JavaScript programming that's not connected to a web browser at all, so jQuery doesn't really do anything there.
Matthew Crumley
A: 

Have you considered or taken a look to JSF? I know it's a major change if you aren't using JSF yet. But there are lot of ready-to-use JSF component libaries with an ajaxical sauce, for example RichFaces, IceFaces, PrimeFaces, etc. It's almost a waste of time to create components/tags for it yourself.

Alternatively you can replace all Javascripts to use the great jQuery JS framework.

BalusC
We evaluated JSF but in the end the powers-that-be decided that keeping a whole boat load of backing beans and UI trees on the server wasn't worth it. I myself never used JSF so can't really say whether that was the right decision.
Lenni
A: 

Depending on how many separate components you have, the extra overhead of running the selectors might not be a big deal. You can initialize all the components just the once, when the page is loaded. Anything that's not present on the page simply won't get initialized, and will incur no further overhead. In most JavaScript frameworks, selecting by classname (or tag name) is pretty fast. It's only the complex selectors, which aren't natively supported by the browser, that are slow.

If you have a few commonly used components, and then a set of less commonly used ones, it may be worth splitting those up. Keep the commonly used components in a single JavaScript file (minified, served with compression and aggressive caching), and load that in every page, regardless of whether it's needed or not. Caching will ensure it's only downloaded once, and it'll only be one small HTTP request. For the less common components, keep them in separate files (ideally, one per component), and add a script tag on pages that use them.

I'm not entirely familiar with how JSP works, but it might be possible to do this automatically - if a tag is included in the document, add a script tag for foo_widget.js in the document header, or something like that.

BlackAura