Your SlideShare is downloading. ×
BVJS
BVJS
BVJS
BVJS
BVJS
BVJS
BVJS
BVJS
BVJS
BVJS
BVJS
BVJS
BVJS
BVJS
BVJS
BVJS
BVJS
BVJS
BVJS
BVJS
BVJS
BVJS
BVJS
BVJS
BVJS
BVJS
BVJS
BVJS
BVJS
BVJS
BVJS
BVJS
BVJS
BVJS
BVJS
BVJS
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

BVJS

4,167

Published on

0 Comments
9 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
4,167
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
19
Comments
0
Likes
9
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Beyond the DOM: Sane Structure for JS Apps Rebecca Murphey • @rmurphey • BVJS 2012Wednesday, March 7, 12
  • 2. github.com/rmurphey/bvjsWednesday, 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
  • 4. Wednesday, March 7, 12
  • 5. 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
  • 8. Wednesday, March 7, 12
  • 9. // NAVIGATION function togglePage(section) { // if the clicked section is already the current section AND were 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 were NOT in full page mode // then lets 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
  • 12. Wednesday, March 7, 12
  • 13. Wednesday, March 7, 12
  • 14. 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
  • 16. <script data-main="app/config" src="/assets/js/libs/require.js"></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 were 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 were NOT in full page mode // then lets 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 updatingWednesday, March 7, 12
  • 21. component controller component service controllers set up components and broker communications between them, eliminating the need for direct communicationWednesday, March 7, 12
  • 22. component controller component service services expose an API for controllers to retrieve and persist dataWednesday, March 7, 12
  • 23. Wednesday, March 7, 12
  • 24. controller twitter searchWednesday, March 7, 12
  • 25. components display data, observe input, and broadcast messages that controllers can react to; may also provide an API for updatingWednesday, 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 communicationWednesday, 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 dataWednesday, 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
  • 35. github.com/rmurphey/bvjsWednesday, March 7, 12
  • 36. rmurphey.com • @rmurpheyWednesday, March 7, 12

×