jquery vs mootools: my initial thoughts
Introduction
I’ve been using jQuery regularly for my new job now for about 3 weeks or so. I’ve used the selectors, event handling, short cuts/handlers, animations, plugins etc. Nothing too fancy, but in general, a descent exposure. I’d like to compare it with Mootools. And while I do rock a Mootools skin on my phone, I’m going to try and remain as objective as subjectively possible. I’m going to try and stay positive about the differences and give use-cases for using either.
Gut Reaction
jQuery is fast to learn, easy to use, and passes the ‘thinking’ to the framework. It allows you to do incredibly powerful client side stuff without knowing too much of the inner workings, worrying about being specific and explicit about your syntax or organization, and most importantly lets you get this stuff done quickly.
Mootools on the other hand requires you to be explicit. You want to create a node with 4 children and easy of them have a bunch of inline attributes? Cool, do it manually, instead of specifying a string of html which the engine will parse and DOM-inize for you (jQuery can do this). Most prominent for me: jQuery is very smart and very easy to use, but lacks a certain elegance due it’s lack of explicit control; Mootools requires more work and overhead to get something done, but is very organized and beyond the learning curve, more meaningful.
Example
To create a series of nodes in jQuery, it’s as easy as this:
var html = ‘<div id=”div-one”><span id=”span-one”>yo yo</span></div>’;
$(html).prependTo($(’#random-node’));
In Moo, it’d be something like this:
var first = new Element(’div’,{’id’:'div-one’});
var two = new Element(’span’,{’id’:’span-one’});
first.adopt(two);
$(’body’).shift().adopt(first);
One is easier/more implicit than the other. However the other is much more explicit, and easier to follow for a foreigner who isn’t too familiar with the jQuery syntax, rules and behaviors.
Optimization/Speed
I don’t know too much about jQuery’s speed. I believe that at this point we’ve got to the point where an extra 10 milliseconds isn’t a do or die or decision maker for what framework/library to use. But with that in mind, one of the great things for Moo is the ability to compartmentalize only what is needed for client side behavior. Everything is kept as a separate stand alone, window based class, where as jQuery seems to throw in a lot of other code into one batch which is mutually dependent.
This goes back to my gut reaction though. For a new comer, I don’t want to try to determine what classes/objects I’ll need. I want a script tag that has almost everything that I need. No playing with downloader apps to pick and choose what my project will need. Mootools therefore introduces a higher level of (initial) complexity, but brings with it greater than control, and again, explicitness.
Community
Up until this point, I’ve more or less tried giving opinions for and against both libraries, but in this category (Community), there is a winner hands down: jQuery. I don’t really know what the reason for this is. I would say that jQuery has been more organized in their community/developer evangelism, which is completely true, but I don’t think that’s the real reason.
While Mootools is still trying to get it’s community plugin system up and rung (MooForge, I believe), I think a core reason it’s the direct and simplicity of jQuery. I think it was able to garner such a strong following because the barrier to entry is to incredibly tiny. I don’t need to understand JavaScript syntax, programming syntax, or the inner workings of client side development. The very syntax that I love about Moo (e.g. new Element(’div’).addClass(’oliver’).addEvent….) is also probably what turns people off. The fact that I need to be so direct about what I want done is something that many people probably don’t want to deal with.
Conclusion
But away from my tangent, the jQuery community is amazing. So many plugins, organized horizontally and vertically by jQuery themselves. So many resources to learn the syntax, deconstruct plugins to understand the code, etc. While my obsessive compulsiveness when it comes to coding syntax and practices would never allow me to fully embrace and adopt jQuery personally and independently of where I work full time, I can understand fully it’s benefits. I’ll always evangelize Mootools whenever I can, but after this exposure to jQuery, I’ll understand where it’s most useful and for whom Mootools would really be welcome to.
grabbing an attribute in mootools: .[name] or .get or .retrieve or .getProperty?
Something I ran into just now was returning an anchor’s attribute consistently across browsers. So I have an anchor with an address like ‘/users/delete/5/’ which does what you’d think it does. But I ran into an inconsistent return response in (you guessed it) ie6. In all fairness, it might not be IE6’s fault, but it speaks more to a problem with mootools. While it is a nearly perfect library/framework, this does bug me.
Mootools has 3 native methods for accessing an attribute/property for a node (which in the DOM, often overlaps). .get(’name’), .retrieve(’name’), and getProperty(’name’). While they are all meant to do things a little differently (eg. set an attribute for a node, store a data object in an existing object (which could be a DOM node) or store a property in an object (which again, could be a DOM node), they seem to overlap a lot.
So I have this anchor, and when I tried accessing it (grabbing the href) using the accessors I have, here at the results for FF (mac) vs. IE6 (windows):
.[name]
FF: full path including host
IE6: full path including host
.get
FF: request path (excluding host)
IE6: full path including host
.retrieve
FF: null
IE6: null
.getProperty
FF: request path (excluding host)
IE6: full path including host
Now it’s hard to say what is the correct expectation. I’m sure I could figure it out in the eyes of the W3C, but rather, here’s what I’ve noticed. Both browsers take whatever path is specified and render it internally with the host. I understand this since it’s what the browser would need to actually make a full request.
The 2nd and 4th accessors, though, are inconsistent and cause problems since their expected results different. IE6 includes the full path & host each time which is most likely an issue with how it accesses it. When the browser defines the href in memory it must overwrite the local pointer which then can’t be accessed properly.
So what do I do about this? Nothing really. I have this documented now so that if there is a pre-dom-ready source that I need to inspect (for example, href values written but no rendered after the dom has been loaded), I should be using the .[name] accessor, and make adjustments accordingly based on what is being accessed (in this case the href which has the host prepended).
These differences really suck since they introduce inconsistencies in places where you wouldn’t expect them and thus break applications/scripts (like what drove me to discover this). I would hope a framework/library would help mitigate this kind of thing, but alas, they can’t do everything, and I’m just happy for what they do bring to the table.
IE6 and input type changes: short answer, ie6 sucks, long answer:
The Problem
I ran into another problem the other day native to ie6 (well ie7 and ie8 too, to be fair) where by I was trying to dynamically change a text input field from type=”text” to type=”password”. Safari, chrome and firefox had no issues. It was a simple as node.type = ‘password’, or since I was using mootools, node.set(’type’,'password’). Resolved. But wait…
Then I ran into IE6, whereby I got a nice “This command is not supported.”. It took me a while to figure this out. At first I thought the node didn’t have mootools ’set’ method for some reason (didn’t access it right?), but once I found out the reason, I looked for workarounds. None really. Other resolutions that attempted completely different code, but no workaround for IE6 specific to change the type. It seemed microsoft had decided that an input field’s type should not be able to change after it’d been loaded. I’ll get to that in a second
My Resolution
Spit out password fields on the page for when it gets sent back to the client. When the DOM has loaded, iterate over the input[type=password] fields (I did this via the mootools selector node.getElements(’input[type=password’)), make them hidden (via add a class or adjusting it’s style property), and make a new node that has an input type with the text value. I added the same classes to it as the password node had. When a user focused on the field (the text one that was originally a password field), I destroyed it, and removed the hidden class.
What really bothered me
“This is an expected behavior. One can’t change the type of an INPUT element once it is already created and became part of the DOM. The behavior is documented below in the Remarsk Section:”
That was microsoft’s response in their developer forums. That was last year, and instead of addressing it as an issue and complying with a standard, they were stubborn and basically refuted the claim as a bug. I’m not sure how I feel about the standard. I understand why an input type is set after the DOM has been loaded. I can’t change a tag type from div to span after the fact (or at least I shouldn’t be able to). Ideally, in my own head that is, every input type should have a separate tag value. <button />, <select />, <file />, <text />, <textarea /> and <password />. I think that’d be ideal, and save a lot of confusion.
Either way, that’s my resolution. M$ response is kind of sucky, but what can ya do.
Flexibility: Server side vs Client side
I’ve been told by many people, veterans in their respective industries such as family friends, family members, etc., that when you’re in a technical field, the best type of job security is to specialize. I imagine this would extend to a lot of different areas (entertainment, finance, management, etc.) but especially in the technical/programming arena, I find it’s very true and productive.
What I mean by this is, be very very very good in a very very very specific field/discipline. Be the best out of all the people you know. If you’re a server side developer, don’t try and learn all the server side languages; rather be the best object-oriented php5 developer who knows the ins and outs of PECL and PEAR extensions. Or be the best db admin who can optimize an InnoDB mysql engine better than anyone you’ve met. That way, when anyone is looking for something specific, you’ll be the first person to come to mind.
I’m too obsessive to follow this though. I would hate being really good at one thing, and then just having to depend on someone else to help me out with the other. Because of that, I’m not very very very good in one area, rather I’m pretty good in a bunch of them. But this is actually still making me fall into a very specific niche; namely, if someone is looking for one guy who can configure a linux/apache box, set up and admin a db, set up a server side dev env., do designs in photoshop, turn them into html/css/js, and add in ajax/js techniques to make a more interactive application/website, I’m that guy. If I were to work in a company with other developers, I probably wouldn’t be better than anyone in any specific area. I wouldn’t be the best JS guy, or CSS guy, or DB guy, and because of that I’m probably not suited for a lot of companies, but for my current contract, they needed one guy who can wear 5 or 6 different hats.
So ironically, the fact that I don’t specialize in one specific area, rather 5 or 6 of them, makes me specialized. It makes me the specific person to go to when you need one person who is pretty good in a bunch of areas.
If you read the title, you might wonder what this has to do with it; it’s a segway into my point. On my current project, I’m having to do both client and server side dev., and it’s making me realize something. The server is way more flexible than the client.
—
Here’s why.
—
The server is usually a linux/unix box. It’s role in a web application/site is to fulfill client side requests, push out data, yadda yadda. It normally doesn’t do anything visual. The client, however, is intrinsically visual. It’s supposed to represent a server architecture in a cohesive, logical way. Now when doing client side dev., you have to normally worry about ie6, ie7, ie8, ff3, sf, opera and chrome (not always this, but thats the goal). At times you’ll run into things you can’t do in the others (CSS3, certain types of ajax callbacks, etc.); sometimes they’ll be things that aren’t worth the time, but other times, it just can’t be done. There is no hack or way around it, it just can’t be done. It’s frustrating to say the least, but it’s making me really value and respect the entire web paradigm and the server’s role in it all.
—
How does this relate to my introduction?
—
I find that there is a lot of ego involved in the web industry. A lot of butting heads in terms of how important people/disciplines are in the grand schemes of things. There are the executives/bus.dev. guys, marketing dudes/gals, client side developers, server side developers, operations/db dudes, and creative/design people. That’s generally how I break it down, and with some exceptions, everyone thinks their role is one of the most important ones. They’ll pretend and put on a face that they don’t believe it, but at their core, there is a lot of pretense about their own positions. I suppose that’s normal considering that’s their professional role.
I’ve always maintained (and have a post that should be coming soon) that one of the most important roles, which I’m terrible at and in no way consider myself part of, is in fact the creative/design ones. I’ll leave my reasoning here for another post. My understanding of the flexibility of client vs server side therefore comes from the fact that I don’t specialize in any one area. If I were a operations/db guy, I’d think the db was the most flexible. If I was a pure server side guy, I’d think it was the most flexible, and the same for the client side.
The point I tried to make with my introduction and the conclusion of the server side being the most flexible is that because of my lack of specialization (and therefore abstract specialization) in the full life cycle of a web application, I think I’m in a unique situation to make that judgment. It’s not right or infallible or anything, but I come at it from a unique perspective. My career/financial stability doesn’t hinge on any one area of the cycle. I could find a job doing client side, or server side, or db/operations, maybe even some mild graphic/creative design stuff. Even as far as more on the management and marketing stance, I think I’d be alright. And because of this, I think I’m in a convenient location to sit back, analyze where any bottle necks are in flexibility, and make a call on what makes the most sense and is most accommodating.
And my conclusion? The server side is way more flexible. There is never a point/time when I can’t do something. It might take more time than I’d hope, require more resources (memory, developers, etc.), but at no point do I have to create ‘hacks’. It’s logical and follows procedures and standards. I think this is mainly because it’s been around longer. The server side env. is really just a programming environment. It’s been around, and perfected, since the 50’s. The web client-side has been around, for the most part, for less than 15 years.
That being said, the client side is getting better. With Flash, Adobe Air, Google Gears, and some really cool plugins (Rhino, for one) the client side is trying real hard, and milding succeeding, in become less of a bottle neck for an application. I think with time it will succeed, but as it stands right now, the server side is where it’s at. Fewer headaches, and more logic, make it one of the most time-satisfying parts of the projects I’m doing lately.
Client side framework’s should be called client side libraries; here’s why:
This isn’t a really important post, it’s just something I think need’s to be expressed and accepted; it must be accepted. Mootools, YUI, jQuery, Dojo etc. are great. They help a person with very tedious javascript techniques, speed up your applications, and make the UX much richer.
But they are not frameworks. I know this probably just seems like a semantics issue, but I want to make it clear that they are not frameworks, they are libraries. From http://dictionary.reference.com/browse/framework
frame⋅work [freym-wurk] Show IPA
–noun
1. a skeletal structure designed to support or enclose something.
2. a frame or structure composed of parts fitted and joined together.
3. the construction or sale of frames.
4. work done in, on, or with a frame.
A framework should be referenced only when your development is surrounded or incased by some structure. On the php side of things, this makes sense; an MVC based framework since every piece of code you write it part of the execution of the framework. On the client side though, it’s not so clear cut.
While you can work inside of a client side library as if you were in a framework (eg. creating new, framework-specific, classes), most of the code you write is simply using the library to help it out. As an example, you attach event handlers, create and manage JSON, make ajax calls, etc. All of this you can do natively, or you can have the library help you out. But when you use one of the library’s helpers, you’re not tied to it. You’re still writing native javascript, just short-cutting through the library’s helper methods and naming conventions.
I’m not sure why this deserved a post, such a long post at that. I suppose as I learn more about true frameworks, I’m realizing that semantics like this really do matter. When I write in CI or Cake, I have to fall in line with their file, naming and folder conventions. I need to work inside of a controller, which is triggered by the framework. I need to define the interface in view/template/layout files, which are loaded and compiled by the framework. And I need to access the data set through their ORM, which is managed by the framework.
JavaScript isn’t like that.
Now while the specific cases I’m talking about (YUI,dojo,jQuery,Moo) are in my eyes libraries, that’s not to say that there couldn’t be/aren’t client side frameworks. I imagine javascript/ajax driven applications (large ones like gmail or a few Ycombinator/startup’s) have client side frameworks.
They have these systems in place where you have to work inside of them; the work is delineated among an MVC pattern, or some sort of separation of logic. I think that’d be really cool to check out, but because of the nature of javascript, I don’t think it’s as necessary as it is on the server side. Maybe I’m just saying that because I haven’t really been exposed to one, but client side JS is more modular and sparse than server side development, and for that reason having a library to help you tap into short cuts makes tons of sense.
My last point though, is that while I’ll always consider these javascript extensions libraries, I can definitely understand how some people would call them frameworks due to the way they use them. If you constantly are creating new framework-specific classes that follow standard programming practices (eg. hierarchy, casting, separation of logic), I think it’d be fair to see you’re using the library AS a framework. I’m cool with that. Lets just be clear about how the extension is used by the general public.
PHP Reflection class: a gem I found
In developing my own mash-up of a framework, drawing inspiration from a lot of different areas, I ran into an interesting hurdles.
Since my framework is MVC based, I ran into a problem whereby calling an action/method in a controller should only be fulfilled if the number of parameters passed in was valid. So for example, if I was dealing with a user’s model, and I wanted to return the email address for the user, I would normally access it via a url pattern such as: http://www.website.com/users/details/email/
On the server side, this would access the Users controller, the details method, and pass in a parameter with the value ‘email’. The method would then grab it from the db, and return it however it decided. The trick came in, however, as to validating the parameters that were passed to a controller’s action/method. So for example, http://www.website.com/users/details/email/oliver/ would pass the details method/action two parameters with values ‘email’, and ‘oliver’.
But my method/action only accepts one. So what should happen? Well ideally, a 404/error page should be pushed out, but how would PHP know that the parameter count doesn’t match? You have two options. One is very intrusive, and the other is best thing ever.
1) Intrusive: in every action, hard code something like:
if(func_num_args()>HARDCODED_NUMBER)This would mean every action/method would need to do this check to make sure the right number of param’s were sent in (this doesn’t even take into account the minimum number of req’d parameters; only the max allowed.
// redirect
2) The best way ever: before making a call to controller’s action use the Reflection class.
This class allows you to check the parameter requirements of a call BEFORE you actually make it. So using php5’s Reflection class, you can check to see how many parameters are required at a minimum (excludes required praams’), how many are the max, and even more fun stuff. This allows you to centralize the error handling for controller calls to the dispatcher (my naming convention for the class/method that actually makes the calls to an action/method), keep your code very clean and clear.
I did some checking, and it seems using this class isn’t too expensive since this information is contained by php be default; it’s just that this extension contains the API for actually accessing it.
It’s a win-win situation as far as I’m concerned.
Dynamic Variables Assignment?
In JS, I ran into a problem where I needed to create a shortcut string, and then turn that string’s value into a reference to a different object.
So for example, I create a string called ‘oliver’ under the variable shortcut like so:
var shortcut = 'oliver';
Then I have a bunch of other code in my framework, and to access any of it, I would write something like:
FRAMEWORK.doSomething();
I wanted the framework’s name space to be preserved (so that I could easily upgrade/update it without affecting any code), but I wanted to be able to use my shortcut handle to access the framework, such that writing the following would work as well:
oliver.doSomething();
This led me to the use of eval to run a js command in js itself to get the assignment/reference working properly like so:
eval(shortcut+' = FRAMEWORK');
This worked really well and met exactly what I was trying to do, but I’m always hesitant to use eval. I’ve heard terrible things about it’s security and performance (although most ajax is based on this function). I’ll look into it and update the post if I find anything, but for the mean while, this has helped me do what I was trying to. It allows me to write really general client side framework code that can then be extended easily into a new namespace without any conflicts. Very powerful stuff.
When I search for it on google, it didn’t come up right away. My search terms (hopefully writing this in the post will help someone else) were: dynamic javascript variable assignment.
ps. The picture is supposed to represent a ’shortcut’. not the best fit I don’t mind saying.
Update: window[name] = reference is the winner. I don’t know why it escaped me before. This should prevent the use of eval and will allow you to dynamically create variables in the window scope.
Framework: S^3 (aka S cubed): I’m calling it Smart Setting Selection
In working on a custom framework (that’s uniting a lot of the best of the existing ones, but keeping it lean and cutting out what I don’t need), I ran into a configuration roadblock which caused me to write some nifty code.
Basically, this framework has a bunch of settings/config files, and some of the files (ini format, using parse_ini_file) are seperated by the following keywords:
local,development,staging,production
Basically meaning, if I have a configuration setting that is supposed to mean something like ‘maxTimeout = 500′, I could, and in a real world application, would have that setting store different values based on which server the code base is being run on (eg. my local would be a lot higher, but the other ones like the production would be much lower for optimization purposes).
This lead me to write some nifty code that will parse all the ini files, and then when I want to retrieve something, it does a check for one of those 4 reserved words. So a real world example would be something like this:
An ini file is parsed and has the following format:
Array
(
[local] => Array
(
[name] => TEST
[cookies] => 1
)
[production] => Array
(
[name] => TEST
[cookies] => 1
)
)
When doing a call to the function and asking for the setting ‘name’, recursively as it moves it’s way down the settings array, it’ll look to see if it contains a keyword of local, production, etc., and if it does, automatically set the value to that array/value. This will be clearer once I OS the framework which won’t be for a while, but to understand it from a code perspective, check this out:
public static function getDetails() {
$details = self::$details;
foreach(func_get_args() as $argument) {
$details = $details[$argument];
if(array_key_exists(Request::getServerRole(),(array) $details))
$details = $details[Request::getServerRole()];
}
return $details;
}
This means that my server will automatically pull the right setting detail based on what server is doing the requesting. I just need to setup my ini files so that if a setting needs to be different based on which server is being loaded, it can be.
Mootools caveat #2: noCache in new Request() is your friend
Reading the docs is really worth it’s weight in gold. Namely, noCache option/parameter for a new Request (aka. Ajax for mootools) object really does make all the difference in the world.
“noCache – (boolean; defaults to false) If true, appends a unique noCache value to the request to prevent caching. (IE has a bad habit of caching ajax request values. Including this script and setting the noCache value to true will prevent it from caching. The server should ignore the noCache value.)”
I was having a problem with ajax being ‘retrieved’ by IE, but not actually making a hit in my access log. I was baffled, and figured it was a caching issue, but confused since safari/FF were working fine.
For those of you out there, be aware of this. My specific problem was actually based on a call to something like:
http://www.website.com/controller/action/
Now I can make that exact url call and have it return a bunch of html; but for the framework I’m working in, adding a header of AC:true (short form for ‘Ajax Call’) will change the output (namely, to a JSON object instead of pure html). It seems IE was caching the request since the page had been requested without the header, and then returning it every time.
Damn you IE!!!!! I understand <link /> and <script /> and <img />’s being cached, but XHR’s? Come on. They’re based on actions (eg. click events, mouse overs, key combinations), not default behaviors of a page load (ordinarily).
Mootools caveat: event.target is not extended by $
This took me wayt too long to discover:
When using event.target via mootools event handlers, I figured out, after way too much testing, that event.target is NOT extended via $, and therefore doesn’t have accessors like .get(’tag’) and default’s for the $ (dollar sign extension).
I wasn’t sure if this was note worthy of a post, but I reckon I’ll fill this up with enough keywords that it’ll hopefully show up in the SERP’s for mootools event trigger target source, etc.
We shall see.