Note: Don’t feel like you need to write all of this down. The slides are available here... http://www.slideshare.net/nathansmith/drupalcon-jquery Carpal Tunnel Relief
FYI – I don’t especially love CSS The reason I create and use CSS frameworks is because I hate doing mundane tasks repeatedly (yawn). I’d rather be working in JavaScript.
Assuming you already know CSS, Sass can help you write CSS faster. But using Sass doesn’t magically create “better” CSS. If you write bad code, Sass won’t remedy it. But Sass isn’t a magic bullet (Because no framework is)
The same principles apply to JavaScript An important discipline when using any framework is striving to understand the underlying language. In other words, use it as a tool – Not a black box
Veteran “ninjas” master a variety of tools – Not just one. Use a framework as an extension of yourself – Not just as a crutch. BY HAND FRAMEWORK http://imdb.com/title/tt1046173
“JavaScript is the only language that I’m aware of that people feel they don’t need to learn before they start using it.” — Douglas Crockford http://www.youtube.com/watch?v=hQVTIJBZook A day to learn, A lifetime to master
Demystifying z-index The default z-index value is 0, and it only takes effect if an element is position: fixed, relative, or absolute. The default is position: static. You don’t have to go overboard with z-index: 99999. Just +1 higher than another element will suffice.
Singleton Pattern = Object-oriented JS Nested JS objects versus dot-notation => Same result, but different approaches var APP = { foo: function() { // Do stuff. }, bar: function() { // Do more stuff. } } var APP = {}; APP.foo = function() { // Do stuff. }; APP.bar = function() { // Do more stuff. }; I prefer the one on the left, but you would call methods by using the same syntax either way: APP.foo() + APP.bar()
// Module pattern. var APP = (function($, window, document, undefined) { // For use only inside APP. var PRIVATE_CONSTANT_1 = 'foo'; var PRIVATE_CONSTANT_2 = 'bar'; // Expose contents of APP. return { go: function() { for (var i in APP.init) { APP.init[i](); } }, // APP.init init: { call_automatically: function() { // Called when DOM is ready. // Can still be called individually, via: // APP.init.call_automatically(); }, // etc. }, // APP.misc misc: { call_specifically: function() { // Must be called individually, via: // APP.misc.call_specifically(); }, // etc. } }; // Alias window, document. })(jQuery, this, this.document); // Automatically run all functions in APP.init jQuery(document).ready(function() { APP.go(); }); Module Pattern << init example Using a module pattern exposes only one global variable, in this case “APP” – with the rest of your methods within an object. It gives you the ability to use private “constant” variables inside your appʼs function scope. Nesting functions within an “init” object allows them to be called automatically on DOM ready.
.live() is Awesome. Use it. Love it. $('div.window').live('mousedown', function() { // Bring window to front. JQD.util.window_flat(); $(this).addClass('window_stack'); }).live('mouseenter', function() { $(this).die('mouseenter').draggable({ // Confine to desktop. // Movable via top bar only. cancel: 'a', containment: 'parent', handle: 'div.window_top' }).resizable({ containment: 'parent', minWidth: 400, minHeight: 200 }); // etc. });
All the event wire-ups are ready, before the page even has any content. Once the content is loaded remotely via Ajax, the elements respond to their respective predefined .live() event listeners. Live (pun intended) example of .live() http://desktop.sonspring.com/ajax_load.html
// Relative or remote links? $('a').live('click', function(ev) { var url = $(this).attr('href'); this.blur(); if (url.match(/^#/)) { ev.preventDefault(); ev.stopPropagation(); } else { $(this).attr('target', '_blank'); } }); External links open in a new window
// Desktop icons. $('a.icon').live('mousedown', function() { // Highlight the icon. JQD.util.clear_active(); $(this).addClass('active'); }).live('dblclick', function() { // Get the link's target. var x = $(this).attr('href'); var y = $(x).find('a').attr('href'); // Show the taskbar button. if ($(x).is(':hidden')) { $(x).remove().appendTo('#dock'); $(x).show('fast'); } // Bring window to front. JQD.util.window_flat(); $(y).addClass('window_stack').show(); }).live('mouseenter', function() { $(this).die('mouseenter').draggable({ revert: true, containment: 'parent' }); }); Making desktop icons interactive
// Taskbar buttons. $('#dock a').live('click', function() { // Get the link's target. var x = $($(this).attr('href')); // Hide, if visible. if (x.is(':visible')) { x.hide(); } else { // Bring window to front. JQD.util.window_flat(); x.show().addClass('window_stack'); } }); Taskbar / Dock buttons
// Show desktop button, ala Windows OS. $('#show_desktop').live('click', function() { // If any windows are visible, hide all. if ($('div.window:visible').length) { $('div.window').hide(); } else { // Otherwise, reveal hidden windows that are open. $('#dock li:visible a').each(function() { $($(this).attr('href')).show(); }); } }); Clicking the Show Desktop button
“Future plans include a tutorial on how to use jQuery to add styling hooks to form elements, since I know from experience that is no cup of tea.” — Source = Me when announcing 960.gs in 2008! — Excuse = New HTML5 elements set me back :) It’s been awhile in the making...
var IE6 = IE(6); var IE7 = IE(7); // Internet Explorer detection. function IE(version) { var b = document.createElement('b'); b.innerHTML = ''; return !!b.getElementsByTagName('br').length; } IE detection for Prototype.js http://formalize.me/assets/javascripts/prototype.formalize.js Prevents false positives since Opera can be made to impersonate IE. Note: I did this because Prototype doesn’t detect IE version number.
var ie = (function() { var undef, v = 3, div = document.createElement('div'), all = div.getElementsByTagName('i'); while ( div.innerHTML = '', all[0] ); return v > 4 ? v : undef; }()); James Padolsey's IE detection (whoa!) https://gist.github.com/527683
// FORMALIZE.init.full_input_size full_input_size: function() { ! if (!IE7 || !$('textarea, input.input_full').length) { ! ! return; ! } ! // This fixes width: 100% on and class="input_full". ! // It ensures that form elements don't go wider than container. ! $('textarea, input.input_full') .wrap(''); }, ... Basic structure of Formalize JS
// FORMALIZE.init.ie6_skin_inputs ie6_skin_inputs: function() { // Test for Internet Explorer 6. if (!IE6 || !$('input, select, textarea').length) { // Exit if the browser is not IE6, // or if no form elements exist. return; } // For , etc. var button_regex = /button|submit|reset/; // For , etc. var type_regex = /date|datetime|datetime-local|email|month|number|password|range|search|tel|text|time|url|week/; $('input').each(function() { var el = $(this); // Is it a button? if (this.getAttribute('type').match(button_regex)) { el.addClass('ie6_button'); /* Is it disabled? */ if (this.disabled) { el.addClass('ie6_button_disabled'); } } // Or is it a textual input? else if (this.getAttribute('type').match(type_regex)) { el.addClass('ie6_input'); /* Is it disabled? */ if (this.disabled) { el.addClass('ie6_input_disabled'); } } }); $('textarea, select').each(function() { /* Is it disabled? */ if (this.disabled) { $(this).addClass('ie6_input_disabled'); } }); }, Adding styling hooks for IE6
Learning jQuery – https://www.packtpub.com/learning-jquery-1.3 jQuery Enlightenment – http://jqueryenlightenment.com DOM Scripting – http://domscripting.com JavaScript: The Good Parts – http://oreilly.com/catalog/9780596517748 JavaScript: The Definitive Guide – http://oreilly.com/catalog/9780596101992 High Performance JavaScript – http://oreilly.com/catalog/9780596802806 Pro JavaScript Design Patterns – http://jsdesignpatterns.com Object-Oriented JavaScript – https://www.packtpub.com/object-oriented-javascript/book The Art and Science of JavaScript – http://www.sitepoint.com/books/jsdesign1 Test-Driven JavaScript Development – http://tddjs.com Recommended Books
For questions – Or just to say hi :) Contact – http://sonspring.com/contact Twitter – http://twitter.com/nathansmith http://www.slideshare.net/nathansmith/drupalcon-jquery