

5 Tips for Better jQuery Code - geuis
http://marcgrabanski.com/article/5-tips-for-better-jquery-code

======
jsdalton
Nice tips. I definitely did not know about the data() method previously.

On a related issue, does anyone have a nice way for passing "arguments" to a
jquery function from the html, while still using jquery selectors (i.e. not
calling the function from an inline event handler)?

I whipped up a truncate function not too long ago that truncates a block of
text to a certain word count and adds a "more" link to reveal the whole thing.
I wanted to add a feature where I could specify from the HTML what word count
the block should be truncated through. I ended up using the class...e.g. <div
class="truncate 30">...</div> would truncate the text in the block to 30
words.

Just curious, in the spirit of this article, if anyone had any alternative
approaches or better suggestions.

~~~
geuis
You can assign a custom attribute to your element, then select on that. So if
you have an input where you want to store 200 characters but truncate at
thirty, you could do input type="text" show="30" size="200"

in jquery, it might be $('input[show]').attr(show)) to select that value. The
input[show] would only select elements with the show attribute. If you only
want to select inputs with certain show values, you could do input[show="30"]
or input[show="10"] if your show values were 30 or 10.

~~~
jsdalton
I shied away from that only because I wasn't sure about adding custom
attributes and making my xhtml invalid, e.g. to a div block which doesn't have
a show attribute in the spec.

Getting the argument itself is actually easy enough, I more ended up
struggling to find an "appropriate" or natural interface for it within the
html itself.

~~~
tr4nslator
Check out the jQuery Metadata plugin:

<http://plugins.jquery.com/project/metadata>

It lets you choose where to define this kind of custom data: in an arbitrary
attribute, as a class within the className attribute, or in a script tag.

------
axod
I don't mean to derail, but the thing I dislike about javascript libraries is
the deception. $ looks really cheap! So lets use it as we would to reference a
variable...

for(var e=0;e<10;e++) { $('foo').doSomething(); }

It's not obvious from that code that $ is a relatively expensive function, and
you'd be far better doing.

var foo = document.getElementById("foo"); for(var e=0;e<10;e++) {
foo.doSomething(); }

I think that point alone creates poor, slow code.

~~~
geuis
hey axod, I'm not sure what your previous exposure to jquery is but you really
should try it if you haven't. I've used prototype and dojo over the years, but
they don't hold a candle to jquery.

You are right in being suspect of speed issues. However, look at a common use
of jQuery and compare it to straight JS.

$('a[href^="https"]').addClass('secureLink');

This one simple line selects all of the anchor tags on a page that are SSL
links, then adds a custom css class to just those anchors. To write that in
straight JS you would need roughly 7 lines, which includes an element match,
looping through those, retrieving the href content of each one, doing a string
match against the results, and adding a new attribute for the class.

At the end of it, the classic JS code isn't any more efficient and its a lot
harder to write and read.

Additionally, since we've already selected the anchors with secure SSL links,
we can do a lot more things with the jquery object without having to take the
cost penalty of doing a new DOM lookup with getElementsByTagName and byId for
subsequent operations. Lets chain some more operations:

$('a[href^="https"]').addClass('secureLink').appendTo( $('<div
id="secureLinkDiv"/>'));

Now we're not only adding a custom class to the selection, we're moving all of
our matching anchor elements to a new div that's being created on the fly
called secureLinkDiv. This is very efficient because you're still operating on
the initial object collection elements and you don't have to re-select the
group for subsequent modifications.

In the rare cases where you can write straight JS that is more efficient than
existing jQuery methods, regular JS mixes quite normally with jQuery. So you
could use a selector like I did for the secure links, then iterate through
that object and do your straight JS. Simple example:

$('a').each(function(i){ //reference each 'a' element by $(this) or with i });

Writing javascript in jQuery has made it SO MUCH EASIER to code now that I
can't say enough how remarkable the difference is. JS used to be a fun thing
to mess with, and a tiresome chore when writing code for work. Now with jQuery
my code is much leaner and runs better, its also fun to write again and opens
up a _lot_ of possibilities to easily create different effects that would have
been hard to do before, simply because the code would have been too lengthy to
efficiently write and then debug.

Give jQuery a try. Its worth it.

~~~
axod
Thanks for the response, I do admit I haven't really played with jquery in
depth, just seen lots of code.

However, it does seem like it is geared to "Find things in the dom" a fair
amount. Whilst I can see that being handy for some websites, for webapps I can
see less point - I know what's in the DOM, I put it there. If I need to do
something with ssl links later, I'll just remember them all.

In your example $('a[href^="https"]') I'd say it'd be a lot tidier and faster
where possible to just give all https links a class and manipulate that class
- sure, not as easy to do things like your 2nd example, which admittedly is
kinda fun (Although seeing HTML in javascript strings always makes me feel
very very sick).

Several people seem to sell jquery etc on cross browser issues. But from my
personal experience most of those issues are css layout issues - not js
issues. Is that sort of thing covered in jquery?

~~~
tptacek
Most UI code written in JS is a variant of "find something in the DOM and
change it". Most JS frameworks are really UI frameworks. And in evolutionary
terms, we are with JS where X11 was around the time when Xt came out; there's
Motif if you want it, but I might just stick with Xt and wait for Gtk.

What are the cross-browser issues you're thinking jQ won't handle for you?

~~~
axod
Things like IE scrollbars covering the content, word-wrap weirdness,
designMode idiocy.. Differences in how iframes are handled - Things like that.
Not to mention all the IE6 rubbish like if you set left _and_ right, it can't
figure out width.

"Most UI code written in JS is a variant of "find something in the DOM and
change it"."

I'd agree to a point, but I'd note that ideally you want to keep handy js
references to what you have in the DOM so you don't have to find it again. And
if you put it in the DOM, you don't ever have to find it, you just store it
somewhere handy. Constantly performing search operations just isn't efficient.

------
JoelSutherland
I am generally against lists on HN but this was really good.

My one thought: does #5 contradict #1?

~~~
geuis
Nah, the intent is for 2 different things. You can add/remove a class on
demand for display, not data, purposes. If I was editing text in an input or
text area and wanted to change its background color for example. the .data()
method would be if I wanted to store content for the element I was editing.
Say if you store its current data using .data() and then blank the input, and
if the user blurs out from the field without entering new data, you can
replace it with the original.

