Your SlideShare is downloading. ×
0
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
Shkrubbel for Open Web Camp 3
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

Shkrubbel for Open Web Camp 3

1,458

Published on

Published in: Technology, Design
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
1,458
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
5
Comments
0
Likes
0
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
  • Hi! My name is Kitt hodsden!
  • A few months I went to a web tech workshop, expecting not much other than a day of head nodding and thoughts of, "yeah, I know that." To my delight, I walked out with pages of notes, tips and new topics to look up, and I thought to myself, next tech talk I do, I'm so way going to try for that. So, my hope is that you leave this talk with a spring in your step and more than a few inspirations on your next project.
  • My inspiration for this particular project was a conversation I had with Jonathan Snook*, who gives a number of talks* about HTML5 and CSS3 and javascript and mobile stuff. He commented that a number of the apps available in the Apple App Store could be done as web applications, and went on to build a number of them* and tweet* about them.
  • One of the applications he wanted to do was Words With Friends*, and I thought, eh, why not? It'll make a great walk through in creating a mobile application, because the hard part is done: figuring out WHAT you want to make, making it is the easy part.So, let's start out, with a Scrabble or Words with Friends board. That's easy, you need a grid for the board, a tray for the tiles, a few buttons for actions and a few extra elements for the game details like score and who's playing.
  • A board.Can even something as simple as a board have options?Yeah.
  • You can do a grid with a specified width and height and float them all to the left, clearing the floats on the last element. Need to make sure the row and board have widths, though.
  • Another option is { display: grid; } grid is a propose option for the display attribute that creates a layout grid much as tables were used for page layouts. You can have grid columns and rows and the equivalent of spans, and everything just lays out nicely. Unfortunately, unless your browser is IE 10, and pretty much no one's is quite yet, { display: grid; } isn't available. But sometimes "soon" we can use the { display: grid; } on our elements and have the browser generate the grid for us.
  • As a toss up between floating divs and using a table for the grid layout, I used the table. Floating divs have the advantage of fewer elements to get the rounded corners, as you can't style rounded corners on a table cell, but you add a div and style that inside the table data element.
  • Okay, so, the board. Technically, the board can be any number of tiles across that we want. Using both Scrabble and Words with Friends as inspiration, we'll have a 15 by 15 board. If you're inspiring younger players, fewer board spaces might be less intimidating.Now, how do we style the background?
  • We could style it exactly as we want it, we can do fun and exciting things with the background image, we can get pixel perfect across every single browser that supports background images, which is nominally all of them.
  • This approach has some disadvantages: you'll need to update your image when your colors change, or have multiple images for different board sizes, and you'll need to have different images for every screen resolution, including some of those that don't yet exist. If you decide to add a feature that the background won't support (in this case, say, random placement of the Double and Triple Words and Letters), you'll need new background images for the "random" boards.While the single background image isn't terribly flexible, but IS the correct solution for some applications. A side scrolling game with multiple repeating backgrounds sliding at different rates to fake parallax, for example, could be served with background images.
  • Okay, other than the single background image, we could still use images to style the individual tiles, also using background images. If you do this, you'll want to use sprites, merging all of your tile images together into one image. The round trip HTTP request for multiple images is more of a performance hit on mobile than it is on the desktop, though it is on the desktop also: better to have one big image than 110 small images each with its own request.
  • This technique has some of the issues of the previous image technique: having less flexibility, needing to scale the images or having differing images altogether for different screen resolutions, but you don't have the variable board size issue.
  • So, what are the characteristics of a tile? Well, it has rounded edges. We can get rounded corners with CSS with no effort these days:
  • So, what are the characteristics of a tile? Well, it has rounded edges. We can get rounded corners with CSS with no effort these days:<pre>-webkit-border-radius: 4px;-moz-border-radius: 4px;border-radius: 4px;</pre>
  • It also has texture. Okay, for texture, one of the easiest ways to get the texture is to use a patterned, tiling background. Want a site for such patterns? http://tileabl.es/ is a good one.
  • We can, however, use javascript to generate a random noise for a background. https://github.com/DanielRapp/Noisy
  • Okay, so we have the background, we have the colors, what about the big part staring at us in the face?The font face.
  • A quick search and we see that a consensus is that the font is "News Gothic". Now, this isn't one of the supported-by-default browser fonts. While we can choose another font that looks very similar, or use the background image technique we decided against earlier, we can use @font-face to render new fonts in the browser.And designers everywhere had a field day.Okay, so we download our new font from the 'net, and look at it.http://www.fontyukle.net/en/DownLoad-News+Gothic+Std+Medium.ttfIt's a True Type Font. We can go through the process of converting the font to the different formats, eot: embedded open type, .woff: web open font format, or we can do what Snook suggested, just use Font Squirrel.
  • Font Squirrel's font face generator gives a fantastic interface for converting various font formats to font-face web embeddable fonts. Be sure you have the right to distribute your font before creating and using a font on your site.There are font services available, use one of them if you are unsure:http://fontsquirrel.com/http://fontspring.com/http://typekit.com/http://www.google.com/webfonts
  • Okay, so, we have our basic page done, we're happy with the layout, we have the board, we have the tray, we have our starting buttons for the game.
  • Our default tile.<div class="tile"><span class="letter">O</span><span class="val">1</span></div></td>Let's start making it work!First thing we want to do, is start dragging the tiles from the tray to the board. Time to load in the javascript. Following the thought that many eyes make all bugs shallow, and idea of standing on the shoulders of giants, and the realization that there are some darn smart people who have worked on this stuff before me, instead of using the native HTML5 Drag and Drop or reinventing the wheel, I'm going to use a javascript library. For me, that means jQuery.For mobile apps, there are a number of framework options available, depending on what development style, approach and feature requirements, the big ones being jQTouch, Sencha Touch, jquery mobile, and phonegap. I'm a big believer in using the tools you're comfortable with, the ones you know, but continue to expand your knowledge. If you can't decide when starting out, use the ones that have the best documentation (and how do you define best? Can _you_ understand it? Great! Choose that.)In this case, we need drag and drop, and submit capabilities, and not much else: no location, no accelerometer, no GPS, no camera, which makes things considerably simpler.So, starting out, added jQuery to the document.
  • First thing we want to do, is start dragging the tiles from the tray to the board. Time to load in the javascript. Following the thought that many eyes make all bugs shallow, and idea of standing on the shoulders of giants, and the realization that there are some darn smart people who have worked on this stuff before me, instead of using the native HTML5 Drag and Drop or reinventing the wheel, I'm going to use a javascript library. For me, that means jQuery.For mobile apps, there are a number of framework options available, depending on what development style, approach and feature requirements, the big ones being jQTouch, Sencha Touch, jquery mobile, and phonegap. I'm a big believer in using the tools you're comfortable with, the ones you know, but continue to expand your knowledge. If you can't decide when starting out, use the ones that have the best documentation (and how do you define best? Can _you_ understand it? Great! Choose that.)In this case, we need drag and drop, and submit capabilities, and not much else: no location, no accelerometer, no GPS, no camera, which makes things considerably simpler.So, starting out, added jQuery to the document.Also added jQuery UI, which has drag and drop functionality with it. While I was at it, I also moved the CSS into an external style sheet, and created a new javascript file for the project. All of them included at the top of the page, along with the !DOCTYPE. Love that new doctype.
  • Preliminaries in, let's start dragging tiles, by adding draggable to the letters:
  • That's great!Except our letters are now floating out in the middle of nowhere. With no styling of their own, the letters appear to float.
  • Need to add opacity so that we see the board background, and a tile background color so that we can actually see it.
  • We want the letters to drop on the board tiles, not just randomly. jQuery UI makes it Easy enough to snap to the board squares:$(".tile").draggable( { snap: "#board td" });
  • Now, there are draggable objects in jQuery along with items that can be used as containers to receive the dropped elements, appropriately called "droppables": HTML elements that can have draggables dropped on them. We'll limit the tiles being dropped on the board for the moment, and give it red border around it so that we can see it dropped.
  • We need to keep track of of the changes to the board that we're making. We can let the board be the canonical source, extracting the data from the DOM (which can be slow) or we can keep track of the state elsewhere.Advantage of the board is that what is displayed is what we have, we don't have to keep two different sources. The disadvantage of that is that we're mixing our data with our view.
  • When a tile is dropped we can save its state this board array.This works fine with tiles from the tray, but not the board to board.But wait, if a tile is moved from one space to another, we need to remove its previous state from our board array. Do we need to keep track of every tray tile's placement? How do we identify which of the tray tiles we're playing?While we can use an extra div to store information, and just hide it:<div class="tilenum">14</div>.tilenum { display: none;}I
  • When a tile is dropped we can save its state this board array.This works fine with tiles from the tray, but not the board to board.But wait, if a tile is moved from one space to another, we need to remove its previous state from our board array. Do we need to keep track of every tray tile's placement? How do we identify which of the tray tiles we're playing?While we can use an extra div to store information, and just hide it:<div class="tilenum">14</div>.tilenum { display: none;}I
  • "Custom data attributes are intended to store custom data private to the page or application, for which there are no more appropriate attributes or elements."http://html5doctor.com/html5-custom-data-attributes/We can store the previous location in the tile itself, just as we store the tile number. A tile in the tray has no previous board location. Once a tile is dropped on the board, we can save its location.
  • data- attributes can be used for all sorts of things, just don't use them for things that should be public, like microformats, or an existing attribute.
  • SidenoteThe board space divs are named with an id of r followed by two hexadecimal numbers. The first is the row number, the second is the column number. Recalling we're in hex, we need to convert to decimal for storing into our array (okay, no, but it made it easier earlier):<td id="r9b"><div class="it"></div></td>var row = id.substring(1, 2); // 9varcol = id.substring(2, 3); // bb = 11, so need to convert from hex to decimalDo it this way:parseInt(row, 16);
  • Okay, so, we've dragged tiles to the board. As soon as we've dragged a tile, we can submit it to the server, right? Sure!A quick adjustment to the button to change it from a pass to a play link and we're good to go.// submit the board$('#bp').attr('href', (SHK.inplaycount()) ? 'go/play':'go/pass');$('#bp').html((SHK.inplaycount()) ? 'submit' : 'pass');Or, maybe not.
  • While dropping a tile on the board means we can submit the board, we should really verify all tiles are placed legally. In particular, we need to check the tiles are all in a row, and that they are all contiguous with the all letters on the board.
  • To check if all the placed letters are in a line, we can loop through the positions of the placed tiles and check that the row is the same for all the placed tiles or the column is the same. When only one tile is placed, we'll have both cases being true.To check if the tiles were placed contiguously, using whichever direction the line of letters were placed (up/down or left/right, as previously determined), find the minimum index on the board (so if the tiles were all placed on row 4, find the lowest indexed tile in row 4), then find the maximum index of all tiles onthe board in that same line, then loop through the line and check there are no gaps, by incrementing by one from the minimum to the maximum in that line.
  • At this point, we have a board, the player has played a word, how do we know it's a valid word? Can we submit the board now?In traditional scrabble games, one player plays a word and the other player challenges the word if she believes the word played isn't a valid word. At this point, however, not only do we want to demo more of the HTML5 features, but I also told you we were going to download a dictionary and store it in HTML5 local storage, so we're going to go the Words with Friends route: instead of challenge, we're going to check the word is valid before sending it to the server.To do that, though, we need to first get the dictionary. The uncompressed dictionary I have is just under 2MB in size. That is not going to fit into our 4K cookie space allotted.
  • Seriously, this is NOT the way to build a highly scalable multi-player application. Having users download 1.9MB of dictionary? Yeah, don't do that.There's another dictionary that we're going to go with, it's only 620kB, so let's download that, but do it only once so that people don't start throwing fits
  • // See if the property that we want is pre-cached in the localStorage if ( window.localStorage !== null && window.localStorage.shkrubbeldict ) {var words = window.localStorage.shkrubbeldict.split("\\n"); for ( vari = 0; i < words.length; i++ ) {SHK.dict[words[i]] = true; } } ... // Cache the dictionary, if possible if ( window.localStorage !== null ) {window.localStorage.shkrubbeldict = txt; }See: http://diveintohtml5.org/storage.html
  • Once we have it loaded into our dictionary array (did I mention don't do this?), we can check if the word is valid with a simple check:if (SHK.dict[word.toLowerCase()]) { // we have a word!}
  • Did I mention don't do this? There are more efficient ways of storing large dictionaries. http://ejohn.org/blog/dictionary-lookups-in-javascript/http://ejohn.org/blog/javascript-trie-performance-analysis/http://ejohn.org/blog/revised-javascript-dictionary-search/
  • While we're here, and I'm taking a breather, let's just implement that recall button...1. move the tiles back to the tray2. clear our inplay tiles3. clear their spots out of the board, using data prevloc as beforeAnd the resign button, that one's easy, too.
  • While we're here, and I'm taking a breather, let's just implement that recall button...1. move the tiles back to the tray2. clear our inplay tiles3. clear their spots out of the board, using data prevloc as beforeAnd the resign button, that one's easy, too.
  • Wait a second... you know what's been missing from this entire process?
  • Yeah, we should test this on an actual mobile device, eh?
  • First time I brought this up on an ipad and went to drag the tile, and the whole window dragged. While that happened to be a pretty simple issue to fix, and this project doesn't require a lot of interaction from the server, that isn't always the case
  • When testing across multiple devices, or on mobile devices in a non-test environments, when I need remote debugging, yeah, "winery" for the win: http://phonegap.github.com/weinre/While testing, wow, remember that part where I said don't do this? When you have a desktop or even laptop computer with a fast connection and lots of member, even running an emulator doesn't seem too bad or slow. You can fake the connection by having a proxy that can slow things down.http://www.charlesproxy.com/
  • This isn't a big application, but as the features and code base grow, we're going to need to start paying attention to performance, as well as loading time. One way to reduce loading time is, well, not to load resources you don't need. If we had gone with the background images, for example, wow, what a pain in the download to fetch that large background image, only not to use it.
  • Blech.So, downloading and handling those extra files, how do we avoid them?
  • Well, we *could* do browser detection, but have you seen the list of User-Agent strings (which is what you use to detect the browser)? The list grows,
  • Well, we *could* do browser detection, but have you seen the list of User-Agent strings (which is what you use to detect the browser)? The list grows,
  • People now do browser feature detection: what can the browser support?
  • Easiest way is with Modernizr, which includes yepnope.js. yepnope lets you choose which files are downloaded based on browser support (yep) and lack of browser support (nope).Depending on which features you need for your application, you can follow Modernizr's links for libraries and tools that fill in the missing pieces so that you can fake the features.
  • In this case, though, we can use media queries to adjust the CSS3 that we load.As long as we've been using the link element, we've pretty much been using the media attribute. Used to be, you'd see them for only print style sheets.<linkrel="stylesheet" type="text/css" href="theme.css" /><linkrel="stylesheet" type="text/css" href="print.css" media="print"/>
  • ut now with media queries in CSS3, we can be more selective based on browser information and our specified links./* iphone portrait */@media screen and {max-width: 320px) { ...}/* iphone landscape */@media screen and {min-width: 321px) and (max-width: 480px) { ...}See how that’s for only for iphone and ipad? Yeah, don’t do that either.
  • Alternately, we can use Adapt.js to dynamically load different style sheets based on changing browser size.Though, really, except for rotating between portrait and landscape, no one changes their browser sizes except designers.
  • http://developer.yahoo.com/yui/compressor/http://www.phpied.com/cssmin-js/
  • Reduce the image sizes, using compression or different image formats depending on your need (JPG is not always the smallest image). Use Smush.it or Image Optimizer to reduce image sizes.http://developer.yahoo.com/yslow/smushit/http://www.imageoptimizer.net/Pages/Home.aspxSprite your images when you can, reducing the number of calls for resources. Combine your CSS files into one cached version and send that over. On the server, gzip the files and send the compressed version to the browser. Remove unneeded whitespace when compressing: in production, white space is overrated.
  • Save the round trip for the HTTP requestWon’t have any 404s
  • If you can, maybe use Data URIs for images.http://css-tricks.com/5970-data-uris/
  • So, all of this is great, but I don't want to be connected to the internet in order to play. I'd like to have all of my games loaded up so that I can think about the game as I'm swinging in my hammock.First step, is back to localStorage. When saving the game to the server, we can save the game locally also, and on successful submit of a word, update the game's local copy with the new tray letters.
  • To be able to save to the device, however, we need to generate and deliver a MANIFESThttp://diveintohtml5.org/offline.htmlhttp://developer.apple.com/library/safari/#documentation/iPhone/Conceptual/SafariJSDatabaseGuide/OfflineApplicationCache/OfflineApplicationCache.htmleasier way:https://github.com/jamesgpearce/confess
  • Tell the mobile browser (well, apple anyway) that the app is available:<meta name="apple-mobile-web-app-capable" content="yes" /><linkrel="apple-touch-icon" href="icon.png" /><linkrel="apple-touch-startup-image" href="home.png" />
  • Push notificationsOkay, so I've played my game, and now it's time for "not kitt" to play her turn. With native applications, you have the ability to send notifications to other people for installed applications.Web applications are missing a number of these core features, but using web technologies doesn't mean your left out. Recall that point before about a lot of really smart people doing really cool shit?Yeah. http://www.phonegap.com/http://www.appcelerator.com/It's possible to access the phone features with other kits, if those are needed. Alternately, you could create a native application that wraps the application in a, say, UIWebView (for iPhone) so that the user sees the web app, but you can register for push notifications.Or just go with the smart guys.
  • So, what's next?I can think of a giant list of features that I'd like to put in.http://caniuse.com/#feat=dragndropI'm still trying to figure out how to get canvas or video into the application in a meaningful way.
  • Transcript

    • 1. shkrubbelOr, how to make a mobile app using web technologies
    • 2. Hi.
    • 3. Why?
    • 4. @snookca
    • 5. Why not?
    • 6.
    • 7. div.tile { float: left; }div.tile { display: grid }table td
    • 8. .tile {float: left; width: 3em; height: 3em;}<div class=“board”> <div class=“tilerow”> <div class=“tile”></div> <div class=“tile”></div> … <div class=“tile last”></div> …</div>
    • 9. display: grid;
      http://caniuse.com/css-grid
      http://dev.w3.org/csswg/css3-grid-align/
    • 10. Really now, tables for layout?
    • 11. styling the board
    • 12. one giant background image
    • 13. http://wordswithfriends.com/
    • 14. single tile images
    • 15. http://www.flickr.com/photos/lwr/3034478627/ by Leo Reynolds
    • 16. all CSS, all the time
    • 17. -webkit-border-radius: 4px;-moz-border-radius: 4px;border-radius: 4px;
    • 18. http://tileabl.es/
    • 19. $(’.tile').noisy({    'intensity' : 1,     'size' : 200,     'opacity' : 0.08,     'fallback' : '',     'monochrome' : false}).css('background-color', '#EDEBDE');
      https://github.com/DanielRapp/Noisy
    • 20. (You may hate me now.)
    • 21. http://www.fontyukle.net/en/DownLoad-News+Gothic+Std+Medium.ttf
    • 22. http://www.fontsquirrel.com/fontface/generator
    • 23.
    • 24. <div class="tile"> <span class="letter">O</span> <span class="val">1</span></div>
    • 25. <!DOCTYPE html><html><head><scriptsrc="js/jquery-1.6.2.js"></script><scriptsrc=”js/jquery-ui-1.8.14.js"></script><style>…
    • 26. $(document).ready(function() { $(".tile").draggable();});
    • 27.
    • 28. .tile { opacity: .9; background-color: AntiqueWhite; }
    • 29. $(".tile").draggable( { snap: "#board td" });
    • 30. .dropped { border: 1px solid red; } $("#board td").droppable({ drop: function(event, ui) { $(this).addClass("dropped"); ... } }
    • 31. Keep track of the played tile locations
    • 32. SHK.board = new Array(15); …for (vari = 0; i < 15; i++) {SHK.board[i] = new Array(15); for (varj = 0; j < 15; j++) {SHK.board[i][j] = ''; }}
    • 33. <div class="tilenum">14</div>.tilenum { display: none;}
    • 34. data-* to save the day!
    • 35. <td id="l1"> <div id="t1" class="tile" data-tilenum="1"> <span class="letter">U</span> <span class="val">2</span> </div> </td>
    • 36. // if previously placed on a board tile, clear the last positionvarp = ui.helper.data('prevloc');if (ui.helper.data('prevloc')) {varp = ui.helper.data('prevloc'); SHK.board[p[0]][p[1]] = '’;}// set the new positionui.helper.data('prevloc', [row, col]);
    • 37. <td id=”r9b"><div class="it"></div></td>var row = id.substring(1, 2); // 9varcol = id.substring(2, 3); // bb = 11, so need to convert from hex to decimalconvert to decimal this way:parseInt(row, 16);
    • 38. Submit the word!
    • 39.
    • 40. rc = 0 or rc = 1, depending on checking for row or column vart = false; for (vari in SHK.inplay) { if (i && SHK.inplay[i]) { if (t) { if (t != SHK.inplay[i][rc]) { return false; } } else {t = SHK.inplay[i][rc]; } } }
    • 41. But is it a word?
    • 42. localStorage FTW!
    • 43. // See if the property we want is pre-cached in localStorage if ( window.localStorage !== null && window.localStorage.shkrubbeldict ) {var words = window.localStorage.shkrubbeldict.split("n"); for ( vari = 0; i < words.length; i++ ) {SHK.dict[words[i]] = true; }…
      http://diveintohtml5.org/storage.html
    • 44. // easy check now… if (SHK.dict[word.toLowerCase()]) { // we have a word!}
    • 45. did I mention, don’t do this?read these instead:http://ejohn.org/blog/dictionary-lookups-in-javascript/http://ejohn.org/blog/javascript-trie-performance-analysis/http://ejohn.org/blog/revised-javascript-dictionary-search/
    • 46. While we’re here…
    • 47. for (vari = 0; i < 7; i++) { // we're using this in several places, so store in varvart = $('#t' + i); // move the tile back to its starting spott.animate({'top': '0px', 'left' : '0px'}); // clear the inplay tiles from the boardSHK.inplay[i] = false; // clear the tile from the board varp = t.data('prevloc'); if (p) { SHK.board[p[0]][p[1]] = '';t.data(‘prevloc’) = ‘’; } }
    • 48. Wait a second…
    • 49. http://www.techradar.com/reviews/pc-mac/tablets/apple-ipad-681021/review
    • 50. O_O
    • 51. http://phonegap.github.com/weinre
    • 52. Performance
    • 53. Send only what you need
    • 54. And I determine that how?
    • 55. Server side browser detection?(Have you seen a recent User-Agent list?)
    • 56. http://www.user-agents.org/
    • 57. Feature detection
    • 58. http://www.modernizr.com/
    • 59. Media Queries
    • 60. <link rel="stylesheet" href="theme.css" /><link rel="stylesheet” href="print.css" media="print” />
    • 61. /* iPhone Portrait */@media screen and (max-width: 320px) {    …}/* iPhone Landscape */@media screen and (min-width: 321px) and (max-width: 480px) {    …}/* iPad */@media only screen and (min-device-width: 768px) and (max-device-width: 1024px) { …}
    • 62. Adapt.jshttp://adapt.960.gs/
    • 63. Compress fileshttp://developer.yahoo.com/yui/compressor/http://www.phpied.com/cssmin-js/
    • 64. Reduce image sizeshttp://developer.yahoo.com/yslow/smushit/http://www.imageoptimizer.net/Pages/Home.aspx
    • 65. Use data URIs if you can
    • 66. background:    url(data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSAAA…)    no-repeat    left center;  padding: 5px 0 5px 25px;data:[<mime type>][;charset=<charset>][;base64],<encoded data>
    • 67. Taking it all offline
    • 68. Generate a MANIFESTwhy:http://diveintohtml5.org/offline.htmlhttp://bit.ly/g01Her (apple.com)how:https://github.com/jamesgpearce/confess
    • 69. Tell the mobile browser about it.
    • 70. <meta name="apple-mobile-web-app-capable" content="yes" /><link rel="apple-touch-startup-image" href="home.png" /><link rel="apple-touch-icon" href="icon.png" />
    • 71.
    • 72.
    • 73. Push it
    • 74. http://shkrubbel.com/https://github.com/kitt/shkrubbel@shkrubbel
    • 75. phew!http://ki.tt/owc3

    ×