rc3.org

Strong opinions, weakly held

Tag: JavaScript (page 3 of 3)

Beware excessive abstractions

jQuery creator John Resig warns developers away from libraries that hide JavaScript behind other programming languages, and makes a great point about relying overly much on abstractions to make your life “easier”:

When you use a pure-JavaScript library (such as jQuery, Prototype, Dojo, Yahoo UI, etc.) you are still programming using the JavaScript language. In the case of jQuery a large number of users, who have either never programmed JavaScript before or never programmed before, acquire a good grasp of how to use JavaScript – accented by the use of the library. A pure JavaScript library makes annoying tasks simple, the largest of which being cross-browser support. It does nothing to dilute the quality of the JavaScript-authoring experience. In fact I would argue that JavaScript libraries do much to give JavaScript a particular style and feel. Code written with Prototype feels very different from code written with jQuery – and this is fine since it’s giving the user the option to develop in the JavaScript language how they best see fit.

In the case of these language abstractions you are gaining none of the benefit of learning the JavaScript language. When a leak in the abstraction occurs (and it will occur – just as it’s bound to occur in any abstraction) what resources do you have, as a developer, to correct the problem? If you’ve learned nothing about JavaScript then you stand no chance in trying to repair, or work around, the issue.

This is a problem I often run into with developers who rely on persistence/ORM frameworks. They’re great, but if you’re dealing with relational databases, you really need to know SQL. These frameworks make a nice supplement, but they’re no substitute.

Update: Be sure to read the comments for a well thought out counterpoint.

Why Firebug is awesome

jQuery creator John Resig explains the advances that FireBug brought to JavaScript development. I’d say that I didn’t really take JavaScript seriously until I started using FireBug.

He also has a list of potential improvements to FireBug, including porting it to work with Internet Explorer. Given the amount of time Web developers spend debugging weird issues in Internet Explorer, a tool like FireBug would literally be life changing.

Is it OK to require JavaScript?

WebMonkey today asks whether or not it’s OK for Web sites to require JavaScript.

My opinion on this question has changed a lot over the past year or two. Not long ago, I would have said that it’s never to require JavaScript, but I don’t feel that way any more. I think that if your site centers around publishing, you should certainly make all of your content available to users who have disabled JavaScript, but if you provide more application-like functionality, requiring JavaScript for certain features is OK.

As Simon Willison notes, you should always use unobtrusive JavaScript, and progressive enhancement is my recommended approach, generally speaking.

In the end, how you employ JavaScript is a business decision. Developers have to weigh the costs of providing workarounds for people who don’t have JavaScript with the potential loss of revenue from not providing them.

I think the more interesting question is whether or not it makes sense, as a user, to disable JavaScript. Last February I tried an experiment where I disabled JavaScript by default and only turned it back on for specific sites. Disabling JavaScript eliminates an entire class of obnoxious advertisements, and can really speed up the browsing experiment on many Web sites. I found that in many cases, leaving out the JavaScript made Web sites better, not worse. I haven’t used NoScript in awhile, but I still think that employing it is a good idea for most people.

There are programmers …

… and then there are programmers. jQuery creator John Resig has ported the Processing visualization language to JavaScript. Not only is this an incredibly cool hack, but it also makes Processing a heck of a lot more useful in a practical sense. I wonder if this will become the new best approach for presenting graphs and other data visualizations within Web pages?

Links for April 3rd

Links from March 14th

jQuery evangelism

For the past few weeks, I’ve been completely obsessed with jQuery, one of the many fine JavaScript UI libraries that are competing for your attention these days. I can’t really tell you whether jQuery is better than any of the other libraries, but I can say that it’s infinitely better than writing your own JavaScript by hand, and that it’s very approachable. You can start doing really powerful things with jQuery with a very small time investment, especially if you already know a little JavaScript and you understand CSS selectors.

Rather than provide a full primer on how jQuery works, I thought I’d provide an example of the kinds of thing jQuery makes easier. Here’s some real JavaScript code:

$(document).ready(function(event) {
    $("#sameAsPhysical").change(function(event) {
        if (event.target.checked) {
            $("#physical input").each(function() {
                $("#billing input[name='" + $(this).attr("name").replace(/physical/, "billing") + "']").val($(this).val());
            });
        }
    });
});

Here’s how the code works. I have a form that has two fieldset elements. One contains the fields for the physical address for a business, the other contains the fields for the billing address. Because the fields are in the same form, they need different names, so all of the physical address fields begin with physical and all the fields associated with the billing address start with billing.

The first thing I do in this code is bind a handler to the onChange event for a checkbox with the ID sameAsPhysical. Like every other JavaScript library, jQuery provides a facility for binding events to elements at page load time, allowing you to follow the tenets of unobtrusive JavaScript. In this case, I bind an anonymous function to $(document).ready(), which fires when all of the page content has loaded. I do all of my other event binding inside that anonymous function.

My goal here is to bind a function to the onChange event associated with my checkbox. Here’s where the “query” part of jQuery comes into play. To get a reference to the checkbox, I just use $("#sameAsPhysical"). As you can probably tell, that query selects an element with the ID sameAsPhysical, just like it would in a style sheet.

jQuery makes event binding simple by adding methods to selectors for each of the events that you can associate with them. So to bind a function to the onChange event, you just call change() on the results of your query. If the query returned a list of elements, the same function would be bound to all of the elements in the query results, as you’ll see in a moment.

Inside the event handler function, I need to check to see whether the checkbox (which has the label “Same as physical address”) is checked, and if it is, I copy all of the values from the “physical” fields to the “billing” fields.

jQuery helpfully passes in the event being captured to my function, so to check the state of the checkbox, I use the expression event.target.checked. If the box is checked, I copy the values. Now for the cool part.

First I query for $("#physical input"), which returns a list of all of the input elements inside an element with the ID physical. I call the each method on the results, which calls the function passed to it as an argument on each of the elements returned. Inside the function I’m going to copy the value in the field passed to each‘s callback to the value of the corresponding field in the other fieldset, containing the billing address fields.

Let’s look at this line of code:

$("#billing input[name='" + $(this).attr("name").replace(/physical/, "billing") + "']").val($(this).val());

First I grab a reference to the corresponding billing field for the physical field being processed. (Remember we’re inside a loop that’s iterating over the fields in the physical section of the form.)

jQuery goes beyond CSS selectors and provides some XPath-like features. In this case, I write a jQuery that looks like this #billing input[name='billing_address']. That returns any input fields in the billing section that have a name attribute set to billing_address. jQuery selectors are ridiculously powerful.

To create the billing_address name, I use a JavaScript expression: $(this).attr("name").replace(/physical/, "billing"). The trick here is that $(this) is a reference to the current element being passed into the callback function associated with the each method. So I replace “physical” in the name of that element with “billing” to grab the billing field that corresponds with this.

jQuery adds a convenience method to elements that are form fields, called val(). If you call it without an argument, it returns the value in that form field. If you pass it an argument, it sets the value of the field to the argument. So .val($(this).val()) sets the value of the field I looked up (using the name I constructed) to the value of this, which again is the form field passed in by each.

Needless to say this one line of code accomplishes a whole lot, and it’s par for the course with jQuery. You can get an amazing amount done with only a couple of lines of code. Here’s another much simpler example:

$("p.note").prepend('<span class="red">Note</span>: ');

This is a way to fake the ability to use the :before CSS pseudo-selector and the content property. It finds all of the paragraphs with the class note on the page and prepends my text label before the content in the tag.

These are all things you can do with JavaScript alone or with any of the libraries out there, but what I like about jQuery is that it allows you to accomplish these kinds of things with very little code, using a query language that’s easy for humans to comprehend. It doesn’t matter how powerful a tool is if you don’t actually use it, and I find jQuery to be a tool that’s easy to find ways to use. I highly recommend checking it out.

Newer posts

© 2024 rc3.org

Theme by Anders NorenUp ↑