Slide 1

Slide 1 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER CONTEXTUAL JQUERY In Practice

Slide 2

Slide 2 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER QUICK REVIEW

Slide 3

Slide 3 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER JQUERY CODE STYLES • Declarative • Large number of selectors running on document ready • Id-centric selections • Traditional Event Binding • Dynamic • Large number of selectors running on document ready • Class-centric selections • Mix of traditional event binding with some delegated events

Slide 4

Slide 4 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER JQUERY CODE STYLES • Contextual • Very few selectors run on document ready • Context-centric traversing and filtering • Heavy use of delegated events with some traditional binding

Slide 5

Slide 5 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER WRITE CODE LIKE YOU SPEND MONEY Opt to pay a little more later so you don’t risk losing it all on something that never happens

Slide 6

Slide 6 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER WRITE CODE LIKE YOU BUY A CAR Always weigh the difference between cost and quality

Slide 7

Slide 7 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER CONTEXTUAL JQUERY In Practice

Slide 8

Slide 8 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER OVERVIEW • Understanding the power of delegated events • Detecting probable user behavior • Automatic Initialization with Deferreds • Predicting user behavior with localStorage

Slide 9

Slide 9 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER DELEGATED POWER Understanding and using delegated events

Slide 10

Slide 10 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER UNDERSTANDING DELEGATION click click click click click click click click click click click click CONTAINER CONTAINER $( "#tile a" ) .bind( "click", … ); $( "#tile" ) .delegate( "a", "click", … ); $( "#tile" ) .on( "click", "a", … );

Slide 11

Slide 11 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER UNDERSTANDING DELEGATION • Event bubbling allows it to work (This is patched by jQuery as necessary) • One event on a parent vs. many events on children • Filtering vs. Traversal • Responsible events – only run on user action • Can be added before the document is ready • Forces a contextual approach

Slide 12

Slide 12 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER ONE TIME INITIALIZATION PATTERN $( document ) ! .delegate( "li:not(.widget-setup)", "click", function () { ! ! // Do something here ! ! $( this ).addClass( "widget-setup" ); ! });

Slide 13

Slide 13 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER PROBABLE USER ACTIONS Pre-initializing for anticipated use

Slide 14

Slide 14 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER CLICK • Action is definite • Often too late to avoid delays • Great for actions not requiring remote requests • Loading indicators will probably be needed

Slide 15

Slide 15 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER MOUSEENTER / MOUSELEAVE • Action has a high probability • More expensive to listen for • Many false positives • Great for drag and drop initialization

Slide 16

Slide 16 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER MOUSEENTER / MOUSELEAVE // Old Way $( document ).ready( function() { // 1000 item iteration, woah! $( "div.item" ).draggable(); }); // With Delegate $( document ) ! .delegate( "div.item:not( .ui-draggable )", "mouseenter", ! ! function ( e ) { // Only ended up running on 15 items $( this ).draggable({ … }); ! ! } ! );

Slide 17

Slide 17 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER EXAMPLE: TECH CRUNCH

Slide 18

Slide 18 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER MOUSE ENTER/LEAVE & DOTIMEOUT • jQuery.doTimeout is a plugin by Ben Alman: http://bit.ly/dotimeout • Action has a very high probability • May require a click safety net for fast movers • Fewer false positives

Slide 19

Slide 19 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER MOUSE ENTER/LEAVE & DOTIMEOUT function initializeSocialWidgets() { ! // Run setup here } $( document ) ! .delegate( "article", "mouseenter mouseleave", ! ! function ( e ) { ! ! ! var $el = $( this ); ! ! ! ! ! if ( e.type === "mouseenter" ) { ! ! ! ! $el.doTimeout( "social", 500, ! ! ! ! ! $.proxy( initializeSocialWidgets, $el ) ! ! ! ! ); ! ! ! } else { ! ! ! ! $el.doTimeout( "social" ); ! ! ! } ! ! } ! );

Slide 20

Slide 20 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER MOUSE ENTER/LEAVE & DOTIMEOUT $( document ) ! .delegate( "article", "mouseenter mouseleave click", ! ! function ( e ) { ! ! ! var $el = $( this ); ! ! ! ! ! if ( e.type === "mouseenter" ) { ! ! ! ! $el.doTimeout( "social", 500, ! ! ! ! ! $.proxy( initializeSocialWidgets, $el ) ! ! ! ! ); ! ! ! } else if ( e.type === "mouseenter" ) { ! ! ! ! $el.doTimeout( "social" ); ! ! ! } else { ! ! ! ! $el.doTimeout( "social", false ); ! ! ! } ! ! } ! );

Slide 21

Slide 21 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER SCROLLING • Action has a medium probability, but easy to detect when an action cannot happen • Could be expensive, try to use cached data • jQuery Waypoints: http://bit.ly/jquerywaypoints • jQuery Sonar: http://bit.ly/jquerysonar • Ideas • Initialize tabs widget in footer • Run markup changes on articles before they come into view

Slide 22

Slide 22 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER FOCUS • Action has high probability • Great time to initialize something like autocomplete, a date picker, or validation on a form • Remember: focusin and focusout • Ideas: • Load the rest of a multi-step wizard • Load assets for the web app after focus on a signup form

Slide 23

Slide 23 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER AUTOMATIC INITIALIZATION Using $.Deferred to handle initialization

Slide 24

Slide 24 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER SETUP CODE var contactPopover = ( function () { ! var contact_form; // Private variable ! ! return function () { ! ! if ( contact_form ) { ! ! ! return contact_form; ! ! } else { ! ! ! var dfd = $.Deferred(); ! ! ! $.get( '/contact', function ( data ) { ! ! ! ! contact_form = $( data ).hide().appendTo( document.body ); ! ! ! ! dfd.resolve( contact_form ); ! ! ! }); ! ! ! return dfd.promise(); ! ! } ! }; }());

Slide 25

Slide 25 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER SETUP CODE var contactPopover = ( function () { ! var contact_form; // Private variable ! ! return function () { ! ! if ( contact_form ) { ! ! ! return contact_form; ! ! } else { ! ! ! var dfd = $.Deferred(); ! ! ! $.get( '/contact', function ( data ) { ! ! ! ! contact_form = $( data ).hide().appendTo( document.body ); ! ! ! ! dfd.resolve( contact_form ); ! ! ! }); ! ! ! return dfd.promise(); ! ! } ! }; }());

Slide 26

Slide 26 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER SETUP CODE var contactPopover = ( function () { ! var contact_form; // Private variable ! ! return function () { ! ! if ( contact_form ) { ! ! ! return contact_form; ! ! } else { ! ! ! var dfd = contact_form = $.Deferred(); ! ! ! $.get( '/contact', function ( data ) { ! ! ! ! contact_form = $( data ).hide().appendTo( document.body ); ! ! ! ! dfd.resolve( contact_form ); ! ! ! }); ! ! ! return dfd.promise(); ! ! } ! }; }());

Slide 27

Slide 27 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER SETUP CODE var contactPopover = ( function () { ! var contact_form; // Private variable ! ! return function () { ! ! if ( contact_form ) { ! ! ! return contact_form; ! ! } else { ! ! ! var dfd = $.Deferred(); ! ! ! $.get( '/contact', function ( data ) { ! ! ! ! contact_form = $( data ).hide().appendTo( document.body ); ! ! ! ! dfd.resolve( contact_form ); ! ! ! }); ! ! ! return dfd.promise(); ! ! } ! }; }());

Slide 28

Slide 28 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER SETUP CODE var contactPopover = ( function () { ! var contact_form; // Private variable ! ! return function () { ! ! if ( contact_form ) { ! ! ! return contact_form; ! ! } else { ! ! ! var dfd = $.Deferred(); ! ! ! $.get( '/contact', function ( data ) { ! ! ! ! contact_form = $( data ).hide().appendTo( document.body ); ! ! ! ! dfd.resolve( contact_form ); ! ! ! }); ! ! ! return dfd.promise(); ! ! } ! }; }());

Slide 29

Slide 29 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER USE CODE // Immediate Use $.when( contactPopover() ).then( function ( $popover ) { $popover.show(); }); // Anticipated Use $( document ).delegate( ".contact:not(.init)", "mouseenter", function() { ! $( this ).addClass( "init" ); ! contactPopover(); } );

Slide 30

Slide 30 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER ADVANCED USE // Show loader after 0.5 seconds $.doTimeout( "contact", 500, showLoader ); $.when( contactPopover() ).then( function ( $popover ) { // Cancel showing loader or hide if showing $.doTimeout( "contact" ); hideLoader(); $popover.show(); });

Slide 31

Slide 31 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER BENEFITS • You can write your action code without a concern for the initialization status • All setup happens in one easy place • Can be triggered at any time to begin initialization

Slide 32

Slide 32 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER PREDICTING USER ACTIONS Using localStorage to track patterns

Slide 33

Slide 33 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER TRACKING USER ACTIONS • Store a small number of metrics as a user browses your site or application • Keep the information general – don't go overboard • Read this information on page load and respond accordingly • Amplify.store http://amplifyjs.com

Slide 34

Slide 34 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER LOGIN / APP PRELOADING // On the final step of signup, // or inside your web application amplify.store( "member", true ); // On the home page if ( amplify.store( "member" ) ) { // Load login popover loadLoginPopover(); // Preload web application assets loadAppAssets(); }

Slide 35

Slide 35 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER LESS USED ACTIONS // On the advanced Edit page or method var timesLoaded = amplify.store( "advancedEdit" ) || 0; timesLoaded += 1; amplify.store( "advancedEdit", timesLoaded ); // On the base page or init method of the app if ( amplify.store( "advancedEdit" ) > 3 ) { ! // Preload advancedEdit ! preoloadAdvanvedEdit(); }

Slide 36

Slide 36 text

CONTEXTUAL JQUERY IN PRACTICE DOUG NEINER dougneiner [email protected] dcneiner Doug Neiner Doug Neiner