SlideShare a Scribd company logo
1 of 36
Download to read offline
Beyond the DOM:
            Sane Structure for JS Apps
            Rebecca Murphey • @rmurphey • BVJS 2012

Wednesday, March 7, 12
github.com/rmurphey/bvjs




Wednesday, March 7, 12
function ObjInlineDown(e) {
                       if( is.ie ) e = event
                       if( is.ie && !is.ieMac && e.button!=1 && e.button!=2 ) return
                       if( is.ieMac && e.button != 0 ) return
                       if( is.ns && !is.ns4 && e.button!=0 && e.button!=2 ) return
                       if( is.ns4 && e.which!=1 && e.which!=3 ) return
                       this.onSelect()
                       this.onDown()
                     }

                     function ObjInlineUp(e) {
                       if( is.ie ) e = event
                       if( is.ie && !is.ieMac && e.button!=1 && e.button!=2 ) return
                       if( is.ieMac && e.button!=0 ) return
                       if( is.ns && !is.ns4 && !is.nsMac && e.button!=0 && e.button!=2 ) return
                       if( is.ns4 && e.which!=1 && e.which!=3 ) return
                       if( ( !is.ns4 && e.button==2 ) || ( is.ns4 && e.which==3 ) )
                       {
                         if( this.hasOnRUp )
                         {
                           document.oncontextmenu = ocmNone
                           this.onRUp()
                           setTimeout( "document.oncontextmenu = ocmOrig", 100)
                         }
                       }
                       else if( this.hasOnUp )
                         this.onUp()
                     }




Wednesday, March 7, 12
Wednesday, March 7, 12
Wednesday, March 7, 12
<!doctype html>
                     <html lang="en">
                     <head>
                       <meta charset="utf-8">
                       <title>Twitter Search</title>
                       <link rel="stylesheet" href="/assets/css/index.css">
                     </head>

                     <body>
                       <h1>Twitter Search</h1>
                       <div id="searchInput">
                         <form>
                            <input placeholder="enter your search term">
                            <button>submit</button>
                         </form>
                       </div>
                       <ul id="searchResults"></ul>

                       <script src="/assets/js/libs/jquery.js"></script>
                       <script src="/assets/js/app.js"></script>
                     </body>
                     </html>




Wednesday, March 7, 12
$('#searchInput form').submit(function(e){
                       e.preventDefault();

                         var term = $('#searchInput input').val(),
                             req = $.getJSON('http://search.twitter.com/search.json?callback=?&q=' +
                                   escape(term));

                         req.then(function(resp) {
                           var resultsHtml = $.map(resp.results, function(r) {
                             return '<li>' +
                               '<p class="tweet">' + r.text + '</p>' +
                               '<p class="username">' + r.from_user + '</p>' +
                             '</li>';
                           }).join('');

                         $('#searchResults').html(resultsHtml);
                       });
                     });




Wednesday, March 7, 12
Wednesday, March 7, 12
// NAVIGATION
               function togglePage(section) {
                   // if the clicked section is already the current section AND we're in full page mode
                   // minimize the current tab
                   if (jQuery('#md_tab_'+ section).hasClass('current') && jQuery('#md_tab_'+ section + ' a').hasClass('md_fullpage')) {
                       // alert('clicked section is current section AND fullpage mode is active; teaser should load');
                   // Minimize
                       jQuery('#md_tabs_navigation a').removeClass('md_fullpage');
                       jQuery('.md_body').hide();
                       jQuery('#md_feature').slideDown('normal',function(){
                           var bodyContent = jQuery('#md_body_'+ section);
                            bodyContent.fadeOut('normal',function(){
                                jQuery('#md_tabs_navigation a').each(function(){
                                    var thisSection = jQuery(this).html().replace('<span<','').replace('</span<','');
                                    var thisSection_comp = thisSection.toLowerCase().replace(' ','_');
                                    jQuery('#md_body_'+ thisSection_comp).load(
                                        '/app/modules/info/loadTeaser.php?sect='+ thisSection_comp,
                                        function(){
                                            tb_init('.md_body a.thickbox, .md_body area.thickbox, .md_body input.thickbox');
                                            bodyContent.animate({ height: 'toggle', opacity: 'toggle' },"slow");
                                        }
                                    );
                                });
                            });
                       });
                       jQuery('#expandtabs span').empty().append('Expand Tabs');
                   } else {
                   // if the clicked section is NOT the current section OR we're NOT in full page mode
                   // then let's go to full page mode and show the whole tab
                   // Maximize
                       // alert('clicked section is not the current section OR full page mode is not active; full section should load');
                       jQuery('#md_tabs_navigation li').removeClass('current');
                       jQuery('#md_tab_'+ section).addClass('current');
                       jQuery('#md_tabs_navigation a').addClass('md_fullpage');
                       jQuery('.md_body').hide();
                       jQuery('#md_feature').slideUp('normal',function(){
                           var bodyContent = jQuery('#md_body_'+ section);
                            bodyContent.fadeOut('normal',function(){
                                bodyContent.empty();
                                var pageLoader = 'info/loadSection.php?sect='+ section;
                                if (section == 'contact_us') {
                                     pageLoader = 'contact/loadContactForm.php?form_id=1';
                                }
                                bodyContent.load('/app/modules/'+ pageLoader,function(){
                                    // ADD THICKBOXES
                                    tb_init('.md_body a.thickbox, .md_body area.thickbox, .md_body input.thickbox');
                                    $recent_news_links = jQuery('ul.md_news li a.recent_news_link');
                                    $recent_news_links
                                        .unbind('click')
                                        .each(function(){
                                            var hrefMod = this.href;
                                            hrefMod = hrefMod.replace(/article/,'loadNews').replace(/storyid/,'id');
                                            this.href = hrefMod;
                                        })
                                        .click(function(){
                                            var t = this.title || this.name || null;
                                            var a = this.href || this.alt;
                                            var g = this.rel || false;
                                            tb_show(t,a,g);
                                            this.blur();
                                            return false;
                                        });
Wednesday, March 7, 12              // ACCORDION
$('#btn-co-complete').live('click', function() {
            jobCompleted = true;
            $.mobile.changePage('#page-clockout-deficiency', {changeHash: false});
        });

        $('#btn-co-nocomplete').live('click', function() {
            jobCompleted = false;
            $.mobile.changePage('#page-clockout-deficiency', {changeHash: false});
        });

        $('#btn-co-nodef').live('click', function() {
            clockOut(activeJob, { completed:jobCompleted }, DW_JOB_COMPLETED);
        });

        $('#btn-co-otherdef').live('click', function() {
            $.mobile.changePage('#page-clockout-redtag', {changeHash: false});
        });

        $('#btn-co-redtag').live('click', function() {
            clockOut(activeJob, { completed:jobCompleted, redTag:true }, DW_JOB_FOLLOWUP)
        });

        $('#btn-co-noredtag').live('click', function() {
            $('#page-clockout-resolve').page();
            $.mobile.changePage('#page-clockout-resolve', {changeHash: false});
        });

             $('#btn-clockout-resolve').live('click', function() {
                       switch ($('#page-clockout-resolve :checked').val()) {
                       case 'return':
Wednesday, March 7, 12     clockOut(activeJob, { completed:false }, DW_JOB_RETURN);
search input   $('#searchInput form').submit(function(e){
                                          e.preventDefault();

                                          var term = $('#searchInput input').val(),
                                              req = $.getJSON('http://search.twitter.com/searc
                                                    escape(term));

                                          req.then(function(resp) {
                         search data        var resultsHtml = $.map(resp.results, function(r)
                                              return '<li>' +
                                                '<p class="tweet">' + r.text + '</p>' +
                                                '<p class="username">' + r.from_user + '</p>'
                                              '</li>';
                                            }).join('');

                                            $('#searchResults').html(resultsHtml);
                     search results       });
                                        });




Wednesday, March 7, 12
Wednesday, March 7, 12
Wednesday, March 7, 12
Wednesday, March 7, 12
<script   type="text/javascript"   src="http://static.a2cdn.net/misc/jquery.js?9"></script>
               <script   type="text/javascript"   src="http://static.a2cdn.net/misc/drupal.js?9"></script>
               <script   type="text/javascript"   src="/google_analytics/googleanalytics.js?9"></script>
               <script   type="text/javascript"   src="/mollom/mollom.js?9"></script>
               <script   type="text/javascript"   src="/js/jquery-1.4.2.min.js?9"></script>
               <script   type="text/javascript"   src="/js/jquery-ui-1.8.4.custom.min.js?9"></script>
               <script   type="text/javascript"   src="/js/jquery.infieldlabel.min.js?9"></script>
               <script   type="text/javascript"   src="/js/jquery.nivo.slider.js?9"></script>
               <script   type="text/javascript"   src="/js/validations.js?9"></script>
               <script   type="text/javascript"   src="/js/site.js?9"></script>
               <script   type="text/javascript"   src="/js/noconflict.js?9"></script>




Wednesday, March 7, 12
<script data-main="app/config" src="/assets/js/libs/require.js"></script>




Wednesday, March 7, 12
require.config({
                       deps: ["main"],

                         paths: {
                           // JavaScript folders
                           libs: "../assets/js/libs",
                           plugins: "../assets/js/plugins",

                           // Libraries
                           jquery: "../assets/js/libs/jquery",
                           underscore: "../assets/js/libs/underscore",
                           backbone: "../assets/js/libs/backbone"
                       }
                     });




Wednesday, March 7, 12
define([
                       "components/page",
                       "components/search/input",
                       "components/search/results",
                     ], function(Page, SearchInput, SearchResults) {
                       return {
                          // ...
                       };
                     });




Wednesday, March 7, 12
// NAVIGATION
               function togglePage(section) {
                   // if the clicked section is already the current section AND we're in full page mode
                   // minimize the current tab
                   if (jQuery('#md_tab_'+ section).hasClass('current') && jQuery('#md_tab_'+ section + ' a').hasClass('md_fullpage')) {
                       // alert('clicked section is current section AND fullpage mode is active; teaser should load');
                   // Minimize
                       jQuery('#md_tabs_navigation a').removeClass('md_fullpage');
                       jQuery('.md_body').hide();
                       jQuery('#md_feature').slideDown('normal',function(){
                           var bodyContent = jQuery('#md_body_'+ section);
                            bodyContent.fadeOut('normal',function(){
                                jQuery('#md_tabs_navigation a').each(function(){
                                    var thisSection = jQuery(this).html().replace('<span<','').replace('</span<','');
                                    var thisSection_comp = thisSection.toLowerCase().replace(' ','_');
                                    jQuery('#md_body_'+ thisSection_comp).load(
                                        '/app/modules/info/loadTeaser.php?sect='+ thisSection_comp,
                                        function(){
                                            tb_init('.md_body a.thickbox, .md_body area.thickbox, .md_body input.thickbox');
                                            bodyContent.animate({ height: 'toggle', opacity: 'toggle' },"slow");
                                        }
                                    );
                                });
                            });
                       });
                       jQuery('#expandtabs span').empty().append('Expand Tabs');
                   } else {
                   // if the clicked section is NOT the current section OR we're NOT in full page mode
                   // then let's go to full page mode and show the whole tab
                   // Maximize
                       // alert('clicked section is not the current section OR full page mode is not active; full section should load');
                       jQuery('#md_tabs_navigation li').removeClass('current');
                       jQuery('#md_tab_'+ section).addClass('current');
                       jQuery('#md_tabs_navigation a').addClass('md_fullpage');
                       jQuery('.md_body').hide();
                       jQuery('#md_feature').slideUp('normal',function(){
                           var bodyContent = jQuery('#md_body_'+ section);
                            bodyContent.fadeOut('normal',function(){
                                bodyContent.empty();
                                var pageLoader = 'info/loadSection.php?sect='+ section;
                                if (section == 'contact_us') {
                                     pageLoader = 'contact/loadContactForm.php?form_id=1';
                                }
                                bodyContent.load('/app/modules/'+ pageLoader,function(){
                                    // ADD THICKBOXES
                                    tb_init('.md_body a.thickbox, .md_body area.thickbox, .md_body input.thickbox');
                                    $recent_news_links = jQuery('ul.md_news li a.recent_news_link');
                                    $recent_news_links
                                        .unbind('click')
                                        .each(function(){
                                            var hrefMod = this.href;
                                            hrefMod = hrefMod.replace(/article/,'loadNews').replace(/storyid/,'id');
                                            this.href = hrefMod;
                                        })
                                        .click(function(){
                                            var t = this.title || this.name || null;
                                            var a = this.href || this.alt;
                                            var g = this.rel || false;
                                            tb_show(t,a,g);
                                            this.blur();
                                            return false;
                                        });
                                    // ACCORDION
                                    jQuery('div.applemenu div.submenu').hide();
                                    jQuery('div.applemenu div.silverheader < a').click(
Wednesday, March 7, 12                  function(){
component              controller


                         component




                                                 service



               components display data, observe input, and
               broadcast messages that controllers can react
               to; may also provide an API for updating


Wednesday, March 7, 12
component            controller


                         component




                                               service



               controllers set up components and broker
               communications between them, eliminating
               the need for direct communication


Wednesday, March 7, 12
component              controller


                         component




                                                 service




               services expose an API for controllers
               to retrieve and persist data


Wednesday, March 7, 12
Wednesday, March 7, 12
controller




                         twitter search




Wednesday, March 7, 12
components display data, observe input, and
               broadcast messages that controllers can react
               to; may also provide an API for updating




Wednesday, March 7, 12
define([
                 "components/base"
               ], function(Component) {
                 return Component({
                   template : "app/templates/search/input.html",
                   className : 'search-input',

                         events : {
                            "submit form"   :   "_onSubmit"
                         },

                   _onSubmit : function(e) {
                     e.preventDefault();
                     var term = $.trim(this.$el.find('input')[0].value);
                     if (!term) { return; }
                     this.trigger('search', term);
                   }
                 });
               });




Wednesday, March 7, 12
<form>
                 <input placeholder="enter your search term">
                 <button>submit</button>
               </form>




Wednesday, March 7, 12
controllers set up components and broker
               communications between them, eliminating
               the need for direct communication




Wednesday, March 7, 12
<!doctype html>
                     <html lang="en">
                     <head>
                       <meta charset="utf-8">
                       <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
                       <meta name="viewport" content="width=device-width,initial-scale=1">

                         <title>Searchr</title>

                       <!-- Application styles -->
                       <link rel="stylesheet" href="/assets/css/index.css">
                     </head>

                     <body>
                       <!-- Main container -->
                       <div role="main" id="main"></div>

                       <!-- Application source -->
                       <script data-main="app/config" src="/assets/js/libs/require.js"></
                     script>
                     </body>
                     </html>




Wednesday, March 7, 12
var Router = Backbone.Router.extend({
                      routes: {
                         "": "twitter",
                         ":hash": "twitter"
                      },

                      twitter : function(hash) {
                        SearchController.init();
                      }
                    });




Wednesday, March 7, 12
define([
                 "components/page", "components/search/input",
                 "components/search/results", "services/twitter"
               ], function(Page, SearchInput, SearchResults, twitterService) {
                 return {
                   init : function() {
                     this.page = new Page({ template : 'app/templates/pages/search.html' });
                     this.page.render().then(_.bind(this.setupPage, this));
                   },

                         setupPage : function() {
                           var p = this.page;
                           this.searchInput = p.place(new SearchInput(), 'searchInput');
                           this.searchResults = p.place(new SearchResults(), 'searchResults');
                           this.searchInput.on('search', _.bind(this.handleSearch, this));
                         },

                         handleSearch : function(term) {
                            twitterService.query(term).then(_.bind(this.showResults, this));
                         },

                         showResults : function(results) {
                           this.searchResults.show(results);
                         }
                 };
               });




Wednesday, March 7, 12
services expose an API for controllers
               to interact with data




Wednesday, March 7, 12
define([
                 "use!backbone"
               ], function(Backbone) {
                 var TwitterResult = Backbone.Model.extend({
                   // ...
                 });

                   var TwitterResults = Backbone.Collection.extend({
                     type : 'twitter', model : TwitterResult
                   });

                   return {
                     query : function(term) {
                       var req = $.getJSON('http://search.twitter.com/search.json?callback=?&q=' +
                            escape(term)),
                            dfd = $.Deferred();

                         req.then(function(resp) {
                           dfd.resolve(new TwitterResults(resp.results));
                         });

                         return dfd.promise();
                   }
                 };
               });




Wednesday, March 7, 12
“Writing to be read means writing code ... with
               the idea that someone else will read it. is
               fact alone will make you edit and think of better
               ways to solve the problem you have at hand.”
                                       Stoyan Stefanov, “JavaScript Patterns”



Wednesday, March 7, 12
github.com/rmurphey/bvjs




Wednesday, March 7, 12
rmurphey.com • @rmurphey




Wednesday, March 7, 12

More Related Content

What's hot

jQuery Namespace Pattern
jQuery Namespace PatternjQuery Namespace Pattern
jQuery Namespace PatternDiego Fleury
 
jQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journeyjQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journeyHuiyi Yan
 
A New Baseline for Front-End Devs
A New Baseline for Front-End DevsA New Baseline for Front-End Devs
A New Baseline for Front-End DevsRebecca Murphey
 
Intro to Advanced JavaScript
Intro to Advanced JavaScriptIntro to Advanced JavaScript
Intro to Advanced JavaScriptryanstout
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScriptAndrew Dupont
 
Using Objects to Organize your jQuery Code
Using Objects to Organize your jQuery CodeUsing Objects to Organize your jQuery Code
Using Objects to Organize your jQuery CodeRebecca Murphey
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
 
Kick start with j query
Kick start with j queryKick start with j query
Kick start with j queryMd. Ziaul Haq
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony AppsKris Wallsmith
 
Advanced jQuery
Advanced jQueryAdvanced jQuery
Advanced jQuerysergioafp
 
Jqeury ajax plugins
Jqeury ajax pluginsJqeury ajax plugins
Jqeury ajax pluginsInbal Geffen
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mockingKonstantin Kudryashov
 
Command-Oriented Architecture
Command-Oriented ArchitectureCommand-Oriented Architecture
Command-Oriented ArchitectureLuiz Messias
 

What's hot (20)

jQuery Namespace Pattern
jQuery Namespace PatternjQuery Namespace Pattern
jQuery Namespace Pattern
 
jQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journeyjQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journey
 
Dojo Confessions
Dojo ConfessionsDojo Confessions
Dojo Confessions
 
A New Baseline for Front-End Devs
A New Baseline for Front-End DevsA New Baseline for Front-End Devs
A New Baseline for Front-End Devs
 
Intro to Advanced JavaScript
Intro to Advanced JavaScriptIntro to Advanced JavaScript
Intro to Advanced JavaScript
 
Bacbkone js
Bacbkone jsBacbkone js
Bacbkone js
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScript
 
Using Objects to Organize your jQuery Code
Using Objects to Organize your jQuery CodeUsing Objects to Organize your jQuery Code
Using Objects to Organize your jQuery Code
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
Kick start with j query
Kick start with j queryKick start with j query
Kick start with j query
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony Apps
 
Advanced jQuery
Advanced jQueryAdvanced jQuery
Advanced jQuery
 
jQuery
jQueryjQuery
jQuery
 
jQuery
jQueryjQuery
jQuery
 
jQuery secrets
jQuery secretsjQuery secrets
jQuery secrets
 
Jqeury ajax plugins
Jqeury ajax pluginsJqeury ajax plugins
Jqeury ajax plugins
 
Matters of State
Matters of StateMatters of State
Matters of State
 
JQuery
JQueryJQuery
JQuery
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mocking
 
Command-Oriented Architecture
Command-Oriented ArchitectureCommand-Oriented Architecture
Command-Oriented Architecture
 

Similar to BVJS

[removed] $file, removeRemove}, list #su.docx
[removed] $file, removeRemove}, list #su.docx[removed] $file, removeRemove}, list #su.docx
[removed] $file, removeRemove}, list #su.docxgerardkortney
 
Taming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsTaming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsJarod Ferguson
 
Building evented single page applications
Building evented single page applicationsBuilding evented single page applications
Building evented single page applicationsSteve Smith
 
Building Evented Single Page Applications
Building Evented Single Page ApplicationsBuilding Evented Single Page Applications
Building Evented Single Page ApplicationsSteve Smith
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ EtsyNishan Subedi
 
international PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretsinternational PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretssmueller_sandsmedia
 
jQuery and Rails, Sitting in a Tree
jQuery and Rails, Sitting in a TreejQuery and Rails, Sitting in a Tree
jQuery and Rails, Sitting in a Treeadamlogic
 
Ten useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesTen useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesAnkit Rastogi
 
Object-Oriented Javascript
Object-Oriented JavascriptObject-Oriented Javascript
Object-Oriented Javascriptkvangork
 
Object-Oriented JavaScript
Object-Oriented JavaScriptObject-Oriented JavaScript
Object-Oriented JavaScriptkvangork
 
jQuery: Tips, tricks and hints for better development and Performance
jQuery: Tips, tricks and hints for better development and PerformancejQuery: Tips, tricks and hints for better development and Performance
jQuery: Tips, tricks and hints for better development and PerformanceJonas De Smet
 
JQuery Presentation
JQuery PresentationJQuery Presentation
JQuery PresentationSony Jain
 

Similar to BVJS (20)

Clean Javascript
Clean JavascriptClean Javascript
Clean Javascript
 
[removed] $file, removeRemove}, list #su.docx
[removed] $file, removeRemove}, list #su.docx[removed] $file, removeRemove}, list #su.docx
[removed] $file, removeRemove}, list #su.docx
 
Introducing jQuery
Introducing jQueryIntroducing jQuery
Introducing jQuery
 
Taming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsTaming that client side mess with Backbone.js
Taming that client side mess with Backbone.js
 
Building evented single page applications
Building evented single page applicationsBuilding evented single page applications
Building evented single page applications
 
Building Evented Single Page Applications
Building Evented Single Page ApplicationsBuilding Evented Single Page Applications
Building Evented Single Page Applications
 
jQuery secrets
jQuery secretsjQuery secrets
jQuery secrets
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ Etsy
 
international PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretsinternational PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secrets
 
Unit – II (1).pptx
Unit – II (1).pptxUnit – II (1).pptx
Unit – II (1).pptx
 
jQuery and Rails, Sitting in a Tree
jQuery and Rails, Sitting in a TreejQuery and Rails, Sitting in a Tree
jQuery and Rails, Sitting in a Tree
 
Ten useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesTen useful JavaScript tips & best practices
Ten useful JavaScript tips & best practices
 
Object-Oriented Javascript
Object-Oriented JavascriptObject-Oriented Javascript
Object-Oriented Javascript
 
Object-Oriented JavaScript
Object-Oriented JavaScriptObject-Oriented JavaScript
Object-Oriented JavaScript
 
jQuery: Events, Animation, Ajax
jQuery: Events, Animation, AjaxjQuery: Events, Animation, Ajax
jQuery: Events, Animation, Ajax
 
jQuery: Tips, tricks and hints for better development and Performance
jQuery: Tips, tricks and hints for better development and PerformancejQuery: Tips, tricks and hints for better development and Performance
jQuery: Tips, tricks and hints for better development and Performance
 
course js day 3
course js day 3course js day 3
course js day 3
 
Backbone - TDC 2011 Floripa
Backbone - TDC 2011 FloripaBackbone - TDC 2011 Floripa
Backbone - TDC 2011 Floripa
 
JQuery Presentation
JQuery PresentationJQuery Presentation
JQuery Presentation
 
Jquery examples
Jquery examplesJquery examples
Jquery examples
 

More from Rebecca Murphey

More from Rebecca Murphey (7)

Getting Started with Mulberry
Getting Started with MulberryGetting Started with Mulberry
Getting Started with Mulberry
 
Introducing Mulberry
Introducing MulberryIntroducing Mulberry
Introducing Mulberry
 
DojoConf: Building Large Apps
DojoConf: Building Large AppsDojoConf: Building Large Apps
DojoConf: Building Large Apps
 
Lessons from-a-rewrite-gotham
Lessons from-a-rewrite-gothamLessons from-a-rewrite-gotham
Lessons from-a-rewrite-gotham
 
Lessons from a Rewrite
Lessons from a RewriteLessons from a Rewrite
Lessons from a Rewrite
 
Modern JavaScript
Modern JavaScriptModern JavaScript
Modern JavaScript
 
The jQuery Divide
The jQuery DivideThe jQuery Divide
The jQuery Divide
 

Recently uploaded

Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDGMarianaLemus7
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 

Recently uploaded (20)

Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDG
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 

BVJS

  • 1. Beyond the DOM: Sane Structure for JS Apps Rebecca Murphey • @rmurphey • BVJS 2012 Wednesday, March 7, 12
  • 3. function ObjInlineDown(e) { if( is.ie ) e = event if( is.ie && !is.ieMac && e.button!=1 && e.button!=2 ) return if( is.ieMac && e.button != 0 ) return if( is.ns && !is.ns4 && e.button!=0 && e.button!=2 ) return if( is.ns4 && e.which!=1 && e.which!=3 ) return this.onSelect() this.onDown() } function ObjInlineUp(e) { if( is.ie ) e = event if( is.ie && !is.ieMac && e.button!=1 && e.button!=2 ) return if( is.ieMac && e.button!=0 ) return if( is.ns && !is.ns4 && !is.nsMac && e.button!=0 && e.button!=2 ) return if( is.ns4 && e.which!=1 && e.which!=3 ) return if( ( !is.ns4 && e.button==2 ) || ( is.ns4 && e.which==3 ) ) { if( this.hasOnRUp ) { document.oncontextmenu = ocmNone this.onRUp() setTimeout( "document.oncontextmenu = ocmOrig", 100) } } else if( this.hasOnUp ) this.onUp() } Wednesday, March 7, 12
  • 6. <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>Twitter Search</title> <link rel="stylesheet" href="/assets/css/index.css"> </head> <body> <h1>Twitter Search</h1> <div id="searchInput"> <form> <input placeholder="enter your search term"> <button>submit</button> </form> </div> <ul id="searchResults"></ul> <script src="/assets/js/libs/jquery.js"></script> <script src="/assets/js/app.js"></script> </body> </html> Wednesday, March 7, 12
  • 7. $('#searchInput form').submit(function(e){ e.preventDefault(); var term = $('#searchInput input').val(), req = $.getJSON('http://search.twitter.com/search.json?callback=?&q=' + escape(term)); req.then(function(resp) { var resultsHtml = $.map(resp.results, function(r) { return '<li>' + '<p class="tweet">' + r.text + '</p>' + '<p class="username">' + r.from_user + '</p>' + '</li>'; }).join(''); $('#searchResults').html(resultsHtml); }); }); Wednesday, March 7, 12
  • 9. // NAVIGATION function togglePage(section) { // if the clicked section is already the current section AND we're in full page mode // minimize the current tab if (jQuery('#md_tab_'+ section).hasClass('current') && jQuery('#md_tab_'+ section + ' a').hasClass('md_fullpage')) { // alert('clicked section is current section AND fullpage mode is active; teaser should load'); // Minimize jQuery('#md_tabs_navigation a').removeClass('md_fullpage'); jQuery('.md_body').hide(); jQuery('#md_feature').slideDown('normal',function(){ var bodyContent = jQuery('#md_body_'+ section); bodyContent.fadeOut('normal',function(){ jQuery('#md_tabs_navigation a').each(function(){ var thisSection = jQuery(this).html().replace('<span<','').replace('</span<',''); var thisSection_comp = thisSection.toLowerCase().replace(' ','_'); jQuery('#md_body_'+ thisSection_comp).load( '/app/modules/info/loadTeaser.php?sect='+ thisSection_comp, function(){ tb_init('.md_body a.thickbox, .md_body area.thickbox, .md_body input.thickbox'); bodyContent.animate({ height: 'toggle', opacity: 'toggle' },"slow"); } ); }); }); }); jQuery('#expandtabs span').empty().append('Expand Tabs'); } else { // if the clicked section is NOT the current section OR we're NOT in full page mode // then let's go to full page mode and show the whole tab // Maximize // alert('clicked section is not the current section OR full page mode is not active; full section should load'); jQuery('#md_tabs_navigation li').removeClass('current'); jQuery('#md_tab_'+ section).addClass('current'); jQuery('#md_tabs_navigation a').addClass('md_fullpage'); jQuery('.md_body').hide(); jQuery('#md_feature').slideUp('normal',function(){ var bodyContent = jQuery('#md_body_'+ section); bodyContent.fadeOut('normal',function(){ bodyContent.empty(); var pageLoader = 'info/loadSection.php?sect='+ section; if (section == 'contact_us') { pageLoader = 'contact/loadContactForm.php?form_id=1'; } bodyContent.load('/app/modules/'+ pageLoader,function(){ // ADD THICKBOXES tb_init('.md_body a.thickbox, .md_body area.thickbox, .md_body input.thickbox'); $recent_news_links = jQuery('ul.md_news li a.recent_news_link'); $recent_news_links .unbind('click') .each(function(){ var hrefMod = this.href; hrefMod = hrefMod.replace(/article/,'loadNews').replace(/storyid/,'id'); this.href = hrefMod; }) .click(function(){ var t = this.title || this.name || null; var a = this.href || this.alt; var g = this.rel || false; tb_show(t,a,g); this.blur(); return false; }); Wednesday, March 7, 12 // ACCORDION
  • 10. $('#btn-co-complete').live('click', function() { jobCompleted = true; $.mobile.changePage('#page-clockout-deficiency', {changeHash: false}); }); $('#btn-co-nocomplete').live('click', function() { jobCompleted = false; $.mobile.changePage('#page-clockout-deficiency', {changeHash: false}); }); $('#btn-co-nodef').live('click', function() { clockOut(activeJob, { completed:jobCompleted }, DW_JOB_COMPLETED); }); $('#btn-co-otherdef').live('click', function() { $.mobile.changePage('#page-clockout-redtag', {changeHash: false}); }); $('#btn-co-redtag').live('click', function() { clockOut(activeJob, { completed:jobCompleted, redTag:true }, DW_JOB_FOLLOWUP) }); $('#btn-co-noredtag').live('click', function() { $('#page-clockout-resolve').page(); $.mobile.changePage('#page-clockout-resolve', {changeHash: false}); }); $('#btn-clockout-resolve').live('click', function() { switch ($('#page-clockout-resolve :checked').val()) { case 'return': Wednesday, March 7, 12 clockOut(activeJob, { completed:false }, DW_JOB_RETURN);
  • 11. search input $('#searchInput form').submit(function(e){ e.preventDefault(); var term = $('#searchInput input').val(), req = $.getJSON('http://search.twitter.com/searc escape(term)); req.then(function(resp) { search data var resultsHtml = $.map(resp.results, function(r) return '<li>' + '<p class="tweet">' + r.text + '</p>' + '<p class="username">' + r.from_user + '</p>' '</li>'; }).join(''); $('#searchResults').html(resultsHtml); search results }); }); Wednesday, March 7, 12
  • 15. <script type="text/javascript" src="http://static.a2cdn.net/misc/jquery.js?9"></script> <script type="text/javascript" src="http://static.a2cdn.net/misc/drupal.js?9"></script> <script type="text/javascript" src="/google_analytics/googleanalytics.js?9"></script> <script type="text/javascript" src="/mollom/mollom.js?9"></script> <script type="text/javascript" src="/js/jquery-1.4.2.min.js?9"></script> <script type="text/javascript" src="/js/jquery-ui-1.8.4.custom.min.js?9"></script> <script type="text/javascript" src="/js/jquery.infieldlabel.min.js?9"></script> <script type="text/javascript" src="/js/jquery.nivo.slider.js?9"></script> <script type="text/javascript" src="/js/validations.js?9"></script> <script type="text/javascript" src="/js/site.js?9"></script> <script type="text/javascript" src="/js/noconflict.js?9"></script> Wednesday, March 7, 12
  • 17. require.config({ deps: ["main"], paths: { // JavaScript folders libs: "../assets/js/libs", plugins: "../assets/js/plugins", // Libraries jquery: "../assets/js/libs/jquery", underscore: "../assets/js/libs/underscore", backbone: "../assets/js/libs/backbone" } }); Wednesday, March 7, 12
  • 18. define([ "components/page", "components/search/input", "components/search/results", ], function(Page, SearchInput, SearchResults) { return { // ... }; }); Wednesday, March 7, 12
  • 19. // NAVIGATION function togglePage(section) { // if the clicked section is already the current section AND we're in full page mode // minimize the current tab if (jQuery('#md_tab_'+ section).hasClass('current') && jQuery('#md_tab_'+ section + ' a').hasClass('md_fullpage')) { // alert('clicked section is current section AND fullpage mode is active; teaser should load'); // Minimize jQuery('#md_tabs_navigation a').removeClass('md_fullpage'); jQuery('.md_body').hide(); jQuery('#md_feature').slideDown('normal',function(){ var bodyContent = jQuery('#md_body_'+ section); bodyContent.fadeOut('normal',function(){ jQuery('#md_tabs_navigation a').each(function(){ var thisSection = jQuery(this).html().replace('<span<','').replace('</span<',''); var thisSection_comp = thisSection.toLowerCase().replace(' ','_'); jQuery('#md_body_'+ thisSection_comp).load( '/app/modules/info/loadTeaser.php?sect='+ thisSection_comp, function(){ tb_init('.md_body a.thickbox, .md_body area.thickbox, .md_body input.thickbox'); bodyContent.animate({ height: 'toggle', opacity: 'toggle' },"slow"); } ); }); }); }); jQuery('#expandtabs span').empty().append('Expand Tabs'); } else { // if the clicked section is NOT the current section OR we're NOT in full page mode // then let's go to full page mode and show the whole tab // Maximize // alert('clicked section is not the current section OR full page mode is not active; full section should load'); jQuery('#md_tabs_navigation li').removeClass('current'); jQuery('#md_tab_'+ section).addClass('current'); jQuery('#md_tabs_navigation a').addClass('md_fullpage'); jQuery('.md_body').hide(); jQuery('#md_feature').slideUp('normal',function(){ var bodyContent = jQuery('#md_body_'+ section); bodyContent.fadeOut('normal',function(){ bodyContent.empty(); var pageLoader = 'info/loadSection.php?sect='+ section; if (section == 'contact_us') { pageLoader = 'contact/loadContactForm.php?form_id=1'; } bodyContent.load('/app/modules/'+ pageLoader,function(){ // ADD THICKBOXES tb_init('.md_body a.thickbox, .md_body area.thickbox, .md_body input.thickbox'); $recent_news_links = jQuery('ul.md_news li a.recent_news_link'); $recent_news_links .unbind('click') .each(function(){ var hrefMod = this.href; hrefMod = hrefMod.replace(/article/,'loadNews').replace(/storyid/,'id'); this.href = hrefMod; }) .click(function(){ var t = this.title || this.name || null; var a = this.href || this.alt; var g = this.rel || false; tb_show(t,a,g); this.blur(); return false; }); // ACCORDION jQuery('div.applemenu div.submenu').hide(); jQuery('div.applemenu div.silverheader < a').click( Wednesday, March 7, 12 function(){
  • 20. component controller component service components display data, observe input, and broadcast messages that controllers can react to; may also provide an API for updating Wednesday, March 7, 12
  • 21. component controller component service controllers set up components and broker communications between them, eliminating the need for direct communication Wednesday, March 7, 12
  • 22. component controller component service services expose an API for controllers to retrieve and persist data Wednesday, March 7, 12
  • 24. controller twitter search Wednesday, March 7, 12
  • 25. components display data, observe input, and broadcast messages that controllers can react to; may also provide an API for updating Wednesday, March 7, 12
  • 26. define([ "components/base" ], function(Component) { return Component({ template : "app/templates/search/input.html", className : 'search-input', events : { "submit form" : "_onSubmit" }, _onSubmit : function(e) { e.preventDefault(); var term = $.trim(this.$el.find('input')[0].value); if (!term) { return; } this.trigger('search', term); } }); }); Wednesday, March 7, 12
  • 27. <form> <input placeholder="enter your search term"> <button>submit</button> </form> Wednesday, March 7, 12
  • 28. controllers set up components and broker communications between them, eliminating the need for direct communication Wednesday, March 7, 12
  • 29. <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="viewport" content="width=device-width,initial-scale=1"> <title>Searchr</title> <!-- Application styles --> <link rel="stylesheet" href="/assets/css/index.css"> </head> <body> <!-- Main container --> <div role="main" id="main"></div> <!-- Application source --> <script data-main="app/config" src="/assets/js/libs/require.js"></ script> </body> </html> Wednesday, March 7, 12
  • 30. var Router = Backbone.Router.extend({ routes: { "": "twitter", ":hash": "twitter" }, twitter : function(hash) { SearchController.init(); } }); Wednesday, March 7, 12
  • 31. define([ "components/page", "components/search/input", "components/search/results", "services/twitter" ], function(Page, SearchInput, SearchResults, twitterService) { return { init : function() { this.page = new Page({ template : 'app/templates/pages/search.html' }); this.page.render().then(_.bind(this.setupPage, this)); }, setupPage : function() { var p = this.page; this.searchInput = p.place(new SearchInput(), 'searchInput'); this.searchResults = p.place(new SearchResults(), 'searchResults'); this.searchInput.on('search', _.bind(this.handleSearch, this)); }, handleSearch : function(term) { twitterService.query(term).then(_.bind(this.showResults, this)); }, showResults : function(results) { this.searchResults.show(results); } }; }); Wednesday, March 7, 12
  • 32. services expose an API for controllers to interact with data Wednesday, March 7, 12
  • 33. define([ "use!backbone" ], function(Backbone) { var TwitterResult = Backbone.Model.extend({ // ... }); var TwitterResults = Backbone.Collection.extend({ type : 'twitter', model : TwitterResult }); return { query : function(term) { var req = $.getJSON('http://search.twitter.com/search.json?callback=?&q=' + escape(term)), dfd = $.Deferred(); req.then(function(resp) { dfd.resolve(new TwitterResults(resp.results)); }); return dfd.promise(); } }; }); Wednesday, March 7, 12
  • 34. “Writing to be read means writing code ... with the idea that someone else will read it. is fact alone will make you edit and think of better ways to solve the problem you have at hand.” Stoyan Stefanov, “JavaScript Patterns” Wednesday, March 7, 12