Advancing JavaScript with Libraries
Written by on April 13th, 2007 in Ajax News.
The Yahoo! UI team kindly invited me to listen to John Resig, of Mozilla and jQuery, talk to the team on “Advancing JavaScript with Libraries”.
John wanted to talk about his experiences developing a number of JavaScript libraries,
At Mozilla John is working on FUEL, a JavaScript library that should be shipping in Firefox 3, that will reduce the complexity for developers to create add-ons.
What is a library?
- An abstraction away from an existing API
- Give us new APIs to interface with
APIs breed patterns based on how the API is constructed. Libraries will develop new patterns on top of the existing APIs.
For example, compare the DOM API versus a library that makes the DOM easier to work with. This enables library authors to enhance The Way.
Why create a library?
There are many, many libraries out there. Why write a library?
- Avoid repetition
- In JavaScript: Distance from browser differences
- In C: stdlib distances itself from the platform differences
What about the DOM API?
DOM is implemented in every modern browser, and is very stable and web documented. Even here libraries are useful.
This breaks in IE 7, and always returns an empty set:
This fails in Safari 2
These are genuine bugs in a specific strange way.
These fail in Opera and IE (return the input where the name is q)
And expandos mess you up if you use an id of length (in Opera and IE)
And these fail in all browsers (for valid reasons, but Joe User doesn’t get it):
-
-
document.getElementById("name").setAttribute("disabled", false)
-
-
<input type=”text” id=”name” disabled=”disabled” />
-
Reason: DOM doesn’t grok booleans.
-
-
document.body.setAttribute("className", "home");
-
-
<body> … </body>
-
Reason: class is reserved in JavaScript. Use className.
All of these differences cause libraries to be created.
- IE has lots of well documented bugs.
- Safari has less, but more obscure, bugs
Libraries break down issues into meta-problems
E.g.
- Waiting for the document to load
- Traversing the DOM
- Injecting HTML into a page
Waiting for the document to load
A DOM document must be fully loaded before you can work with it, and most wait for the window to load which causes flashes of un-effected content.
What people often do:
jQuery example:
Traversing the DOM
We all know it is ugly, tricky, and long-winded.
We are moving to DOM Selectors to improve the DOM Traversal API. We have looked to standards such as XPath selectors (//div/span[2]), and CSS 3 selectors (div > span:nth-of-type(2)).
Most web developers grok CSS more than XPath, however they are stuck in CSS 1-ish land due to IE.
Here are some one line solutions that would take a lot more in DOM:
-
-
$(”#menu> li:not(:first-child)”).hide(); // CSS 3
-
-
$(”ul[ul]“).show(); // XPath
-
-
$(”tr:even”).addClass(”even”); // Users want it
-
Injecting HTML
Many issues here, such as injecting table rows, select options, etc.
jQuery and others allow you to create HTML and insert into the DOM directly.
-
-
$(”table tr”).append(”<td>test</td>”);
-
$(”select”).prepend(”<option>test</option>”);
-
Put them together and you get unobtrusive DOM scripting:
-
-
$(document).ready(function() {
-
$(”select”).append(”<option>test</option>”);
-
})
-
and it sets up new expectations:
jQuery users have thought that this should work:
The users expect these behaviours to not be running once on page load. It should be like CSS. You don’t re-run CSS rules.
function handleClick() {
$(”li”, this).click(loadMenu);
}
function loadMenu() {
$(this).load(”menu.html”, handleClick);
}
$(document).ready(function() {
$(document).each(handleClick);
});
and becomes the behaviour pattern:
$(document).ready(function() {
$(”li”).behaviour(”click”, function(){
$(this).load(”menu.html”, handleClick);
})
FUEL
JavaScript library for Firefox Extension development, designed to be used by Web Developers (not C++ centric folk).
XPCOM is very daunting, and John shows the code for setting a preference. Lots of lines, lots of ugly XPCOM.
With FUEL:
-
-
Application.prefs.setValue(”some.pref”, “some non-ascii text”);
-
This isn’t new to JavaScript
John compares our library development to other worlds.
E.g. SQL
SELECT * FROM users WHERE id = 5;
…
to Ruby on Rails ActiveRecord::Base
Conclusion
- Libraries build new patterns on top of existing APIs
- New library patterns advance development in meaningful considerable ways
And there is more… Meta-Libraries
John is excited about the DSL movement and what it can mean to the web.
He has been playing with jquery2 which isn’t version 2 of jquery, but rather a DSL for JavaScript.
Browsers ignore a script tag where the type isn’t know, which means that you can have your code go back and grok and run it.
This is how the LISP in Firefox works.
Here is how jquery2 is plugged in:
Come on, time for:
-
-
<script type=”text/ruby”>
-
document.ready do |dom|
-
dom["table tr"] <<”<td>test"
-
end
-
</script>
-
Could get to this via JRuby and the JVM?
Source: Ajaxian
Original Article: http://ajaxian.com/archives/advancing-javascript-with-libraries