Javascript

JavaScript-created markup also needs to be semantic and accessible

Back in the day you used to be able to view source on a web page to see the markup used to create it. These days, on many sites, a large portion of the markup is not visible when you view source because it is inserted by JavaScript functions.

That isn't necessarily a problem provided that you use progressive enhancement and unobtrusive JavaScript. If you follow those principles, content and basic functionality will still be there when scripting is unavailable. Many of us understand that. But one thing I’ve noticed is that some developers forget to consider semantics or accessibility in the markup they use JavaScript to insert.

Read full post

Posted in , , .

Copyright © Roger Johansson



An accessible, keyboard friendly custom select menu

I’ve always been wary of styling form elements too much. Possible usability and accessibility issues, browser quirks, and the fact that the CSS specification does not define form control styling are the main reasons.

With that said, sometimes you have to do things you don’t really want to. Like styling select elements, which I’ve recently had to find a way to do. There are quite a few workarounds for doing this out there. However, most of the ones I looked at replace the select element with a bunch of links which changes semantics and behaviour a bit too much for my tastes. I couldn’t find any implementation that I was completely happy with, so I took the best one I could find and tweaked it.

Read full post

Posted in , , .

Copyright © Roger Johansson



Lessons From A Review Of JavaScript Code





 



 


Before we start, I’d like to pose a question: when was the last time you asked someone to review your code? Reviewing code is possibly the single best technique to improve the overall quality of your solutions, and if you’re not actively taking advantage of it, then you’re missing out on identifying bugs and hearing suggestions that could make your code better.

None of us write 100% bug-free code all of the time, so don’t feel there’s a stigma attached to seeking help. Some of the most experienced developers in our industry, from framework authors to browser developers, regularly request reviews of their code from others; asking whether something could be tweaked should in no way be considered embarrassing. Reviews are a technique like any other and should be used where possible.

Today we’ll look at where to get your code reviewed, how to structure your requests, and what reviewers look for. I was recently asked to review some code for a new JavaScript application, and thought I’d like to share some of my feedback, because it covers some JavaScript fundamentals that are always useful to bear in mind.

Introduction

Reviewing code goes hand in hand with maintaining strong coding standards. That said, standards don’t usually prevent logical errors or misunderstandings about the quirks of a programming language, whether it’s JavaScript, Ruby, Objective-C or something else. Even the most experienced developers can make these kinds of mistakes, and reviewing code can greatly assist with catching them.

The first reaction most of us have to criticism is to defend ourselves (or our code), and perhaps lash back. While criticism can be slightly demoralizing, think of it as a learning experience that spurs us to do better and to improve ourselves; because in many cases, once we’ve calmed down, it actually does.

Also remember that no one is obliged to provide feedback on your work, and if the comments are indeed constructive, then be grateful for the time spent offering the input.

Reviews enable us to build on the experience of others and to benefit from a second pair of eyes. And at the end of the day, they are an opportunity for us to write better code. Whether we take advantage of them is entirely our choice.

Where Can I Get My Code Reviewed?

Often the most challenging part is actually finding an experienced developer who you trust to do the review. Below are some places where you can request others to review your code (sometimes in other languages, too).

  • JSMentors
    JSMentors is a mailing list that discusses everything to do with JavaScript (including Harmony), and a number of experienced developers are on its review panel (including JD Dalton, Angus Croll and Nicholas Zakas). These mentors might not always be readily available, but they do their best to provide useful, constructive feedback on code that’s been submitted. If you’re looking for assistance with a specific JavaScript framework beyond vanilla JavaScript, the majority of frameworks and libraries have mailing lists or forums that you can post to and that might provide a similar level of assistance.
  • freenode IRC
    Many chat rooms here are dedicated both to discussing the JavaScript language and to requests for help or review. The most popular rooms are obviously named, and #javascript is particularly useful for generic JavaScript requests, while channels such as #jquery and #dojo are better for questions and requests related to particular libraries and frameworks.
  • Code Review (beta)
    You would be forgiven for confusing Code Review with StackOverflow, but it’s actually a very useful, broad-spectrum, subjective tool for getting peer review of code. While on StackOverflow you might ask the question “Why isn’t my code working?,� Code Review is more suited to questions like “Why is my code so ugly?� If you still have any doubt about what it offers, I strongly recommend checking out the FAQs.
  • Twitter
    This might sound odd, but at least half of the code that I submit for review is through social networks. Social networks work best, of course, if your code is open source, but trying them never hurts. The only thing I suggest is to ensure that the developers who you follow and interact with are experienced; a review by a developer with insufficient experience can sometimes be worse than no review at all, so be careful!
  • GitHub + reviewth.is
    We all know that GitHub provides an excellent architecture for reviewing code. It comes with commits, file and line comments, update notifications, an easy way to track forks of gits and repositories, and more. All that’s missing is a way to actually initiate reviews. A tool called reviewth.is attempts to rectify that by giving you a post-commit hook that helps to automate this process, so changes that get posted in the wild have a clear #reviewthis hash tag, and you can tag any users who you wish to review your updates. If many of your colleagues happen to develop in the same language as you do, this set-up can work well for code reviews sourced closer to home. One workflow that works well with this (if you’re working on a team or on a collaborative project) is to perform your own work in a topic branch in a repository and then send through pull requests on that branch. Reviewers would examine the changes and commits and could then make line-by-line and file-by-file comments. You (the developer) would then take this feedback and do a destructive rebase on that topic branch, re-push it, and allow the review cycle to repeat until merging them would be acceptable.

How Should I Structure My Review Requests?

The following are some guidelines (based on experience) on how to structure your requests for code reviews, to increase the chances of them being accepted. You can be more liberal with them if the reviewer is on your team; but if the reviewer is external, then these might save you some time:

  • Isolate what you would like to be reviewed; ensure that it can be easily run, forked and commented; be clear about where you think improvements could be made; and, above all, be patient.
  • Make it as easy as possible for the reviewer to look at, demo and change your code.
  • Don’t submit a ZIP file of your entire website or project; very few people have the time to go through all of this. The only situation in which this would be acceptable is if your code absolutely required local testing.
  • Instead, isolate and reduce what you would like to be reviewed on jsFiddle, on jsbin or in a GitHub gist. This will allow the reviewer to easily fork what you’ve provided and to show changes and comments on what can be improved. If you would prefer a “diffâ€� between your work and any changes they’ve recommended, you might also be interested in PasteBin, which supports this.
  • Similarly, don’t just submit a link to a page and ask them to “View sourceâ€� in order to see what can be improved. On websites with a lot of scripts, this task would be challenging and lowers the chances of a reviewer agreeing to help. No one wants to work to find what you want reviewed.
  • Clearly indicate where you personally feel the implementation could be improved. This will help the reviewer quickly home in on what you’re most interested in having reviewed and will save them time. Many reviewers will still look at other parts of the code you’ve submitted regardless, but at least help them prioritize.
  • Indicate what (if any) research you’ve done into techniques for improving the code. The reviewer might very well suggest the same resources, but if they’re aware that you already know of them, then they might offer alternative suggestions (which is what you want).
  • If English isn’t your first language, there’s no harm in saying so. When other developers inform me of this, I know whether to keep the language in my review technical or simple.
  • Be patient. Some reviews take several days to get back to me, and nothing’s wrong with that. Other developers are usually busy with other projects, and someone who agrees to schedule a look at your work is being kind. Be patient, don’t spam them with reminders, and be understanding if they get delayed. Doing this sometimes pay off, because the reviewer can provide even more detailed feedback when they have more time.

What Should Code Reviews Provide?

Jonathan Betz, a former developer at Google, once said that a code review should ideally address six things:

  1. Correctness
    Does the code do everything it claims?
  2. Complexity
    Does it accomplish its goals in a straightforward way?
  3. Consistency
    Does it achieve its goals consistently?
  4. Maintainability
    Could the code be easily extended by another member of the team with a reasonable level of effort?
  5. Scalability
    Is the code written in such a way that it would work for both 100 users and 10,000? Is it optimized?
  6. Style
    Does the code adhere to a particular style guide (preferably one agreed upon by the team if the project is collaborative)?

While I agree with this list, expanding it into an action guide of what reviewers should practically aim to give developers would be useful. So, reviewers should do the following:

  • Provide clear comments, demonstrate knowledge, and communicate well.
  • Point out the shortfalls in an implementation (without being overly critical).
  • State why a particular approach isn’t recommended, and, if possible, refer to blog posts, gists, specifications, MDN pages and jsPerf tests to back up the statement.
  • Suggest alternative solutions, either in a separate runnable form or integrated in the code via a fork, so that the developer can clearly see what they did wrong.
  • Focus on solutions first, and style second. Suggestions on style can come later in the review, but address the fundamental problem as thoroughly as possible before paying attention to this.
  • Review beyond the scope of what was requested. This is entirely at the reviewer’s discretion, but if I notice issues with other aspects of a developer’s implementation, then I generally try to advise them on how those, too, might be improved. I’ve yet to receive a complaint about this, so I assume it’s not a bad thing.

Collaborative Code Reviews

Although a review by one developer can work well, an alternative approach is to bring more people into the process. This has a few distinct advantages, including reducing the load on individual reviewers and exposing more people to your implementation, which could potentially lead to more suggestions for improvements. It also allows a reviewer’s comments to be screened and corrected if they happen to make a mistake.

To assist the group, you may wish to employ a collaborative tool to allow all reviewers to simultaneously inspect and comment on your code. Luckily, a few decent ones out there are worth checking out:

  • Review Board
    This Web-based tool is available for free under the MIT license. It integrates with Git, CVS, Mercurial, Subversion and a number of other source-control systems. Review Board can be installed on any server running Apache or lighttpd and is free for personal and commercial use.
  • Crucible
    This tool by Australian software company Atlassian is also Web-based. It’s aimed at the enterprise and works best with distributed teams. Crucible facilitates both live review and live commenting and, like Review Board, integrates with a number of source-control tools, including Git and Subversion.
  • Rietveld
    Like the other two, Rietveld also supports collaborative review, but it was actually written by the creator of Python, Guido van Rossum. It is designed to run on Google’s cloud service and benefits from Guido’s experience writing Mondrian, the proprietary app that Google uses internally to review its code.
  • Others
    A number of other options for collaborative code review weren’t created for that purpose. These include CollabEdit (free and Web-based) and, my personal favorite, EtherPad (also free and Web-based).


(Image Source: joelogon)

Lessons From A JavaScript Code Review

On to the review.

A developer recently wrote in, asking me to review their code and provide some useful suggestions on how they might improve it. While I’m certainly not an expert on reviewing code (don’t let the above fool you), here are the problems and solutions that I proposed.

Problem 1

Problem: Functions and objects are passed as arguments to other functions without any type validation.

Feedback: Type validation is an essential step in ensuring that you’re working only with input of a desired type. Without sanitization checks in place, you run the risk of users passing in just about anything (a string, a date, an array, etc.), which could easily break your application if you haven’t developed it defensively. For functions, you should do the following at a minimum:

  1. Test to ensure that arguments being passed actually exist,
  2. Do a typeof check to prevent the app from executing input that is not a valid function at all.
if (callback && typeof callback === "function"){
    /* rest of your logic */
}else{
    /* not a valid function */
}

Unfortunately, a simple typeof check isn’t enough on its own. As Angus Croll points out in his post “Fixing the typeof operator,� you need to be aware of a number of issues with typeof checking if you’re using them for anything other than functions.

For example, typeof null returns object, which is technically incorrect. In fact, when typeof is applied to any object type that isn’t a function, it returns object, not distinguishing between Array, Date, RegEx or whatever else.

The solution is to use Object.prototype.toString to call the underlying internal property of JavaScript objects known as [[Class]], the class property of the object. Unfortunately, specialized built-in objects generally overwrite Object.prototype.toString, but you can force the generic toString function on them:

Object.prototype.toString.call([1,2,3]); //"[object Array]"

You might also find Angus’s function below useful as a more reliable alternative to typeof. Try calling betterTypeOf() against objects, arrays and other types to see what happens.

function betterTypeOf( input ){
    return Object.prototype.toString.call(input).match(/^\[object\s(.*)\]$/)[1];
}

Here, parseInt() is being blindly used to parse an integer value of user input, but no base is specified. This can cause issues.

In JavaScript: The Good Parts, Douglas Crockford refers to parseInt() as being dangerous. Although you probably know that passing it a string argument returns an integer, you should also ideally specify a base or radix as the second argument, otherwise it might return unexpected output. Take the following example:

parseInt('20');       // returns what you expect, however…
parseInt('020');      // returns 16
parseInt('000020');   // returns 16
parseInt('020', 10);  // returns 20 as we've specified the base to use

You’d be surprised by how many developers omit the second argument, but it happens quite regularly. Remember that your users (if permitted to freely enter numeric input) won’t necessarily follow standard number conventions (because they’re crazy!). I’ve seen 020, ,20, ;'20 and many other variations used, so do your best to parse as broad a range of inputs as possible. The following tricks to using parseInt() are occasionally better:

Math.floor("020");   // returns 20
Math.floor("0020");  //returns 20
Number("020");  //returns 20
Number("0020"); //returns 20
+"020"; //returns 20

Problem 2

Problem: Checks for browser-specific conditions being met are repeated throughout the code base (for example, feature detection, checks for supported ES5 features, etc.).

Feedback: Ideally, your code base should be as DRY as possible, and there are some elegant solutions to this problem. For example, you might benefit from the load-time configuration pattern here (also called load-time and init-time branching). The basic idea is that you test a condition only once (when the application loads) and then access the result of that test for all subsequent checks. This pattern is commonly found in JavaScript libraries that configure themselves at load time to be optimized for a particular browser.

This pattern could be implemented as follows:

var tools = {
    addMethod: null,
    removeMethod: null
};

if(/* condition for native support */){
    tools.addMethod = function(/* params */){
        /* method logic */
    }
}else{
    /* fallback - eg. for IE */
    tools.addMethod = function(/* */){
        /* method logic */
    }
}

The example below demonstrates how this can be used to normalize getting an XMLHttpRequest object.

var utils = {
    getXHR: null
};

if(window.XMLHttpRequest){
    utils.getXHR = function(){
        return new XMLHttpRequest;
    }
}else if(window.ActiveXObject){
    utils.getXHR = function(){
        /* this has been simplified for example sakes */
        return new ActiveXObject(’Microsoft.XMLHTTP’);
    }
}

For a great example, Stoyan Stefanov applies this to attaching and removing event listeners cross-browser, in his book JavaScript Patterns:

var utils = {
    addListener: null,
    removeListener: null
};
// the implementation
if (typeof window.addEventListener === ’function’) {
    utils.addListener = function ( el, type, fn ) {
        el.addEventListener(type, fn, false);
    };
    utils.removeListener = function ( el, type, fn ) {
        el.removeEventListener(type, fn, false);
    };
} else if (typeof document.attachEvent === ’function’) { // IE
    utils.addListener = function ( el, type, fn ) {
        el.attachEvent(’on’ + type, fn);
    };
    utils.removeListener = function ( el, type, fn ) {
        el.detachEvent(’on’ + type, fn);
    };
} else { // older browsers
    utils.addListener = function ( el, type, fn ) {
        el[’on’ + type] = fn;
    };
    utils.removeListener = function ( el, type, fn ) {
        el[’on’ + type] = null;
    };
}

Problem 3

Problem: The native Object.prototype is being extended regularly.

Feedback: Extending native types is generally frowned upon, and few (if any) popular code bases should dare to extend Object.prototype. The reality is that there is not likely a situation in which you absolutely need to extend it in this way. In addition to breaking the object-as-hash tables in JavaScript and increasing the chance of naming collisions, it’s generally considered bad practice, and modifying it should only be a last resort (this is quite different from extending your own custom object properties).

If for some reason you do end up extending the object prototype, ensure that the method doesn’t already exist, and document it so that the rest of the team is aware why it’s necessary. You can use the following code sample as a guide:

if(typeof Object.prototype.myMethod != ’function’){
    Object.prototype.myMethod = function(){
        //implem
    };
}

Juriy Zaytsev has a great post on extending native and host objects, which may be of interest.

Problem 4

Problem: Some of the code is heavily blocking the page because it’s either waiting on processes to complete or data to load before executing anything further.

Feedback: Page-blocking makes for a poor user experience, and there are a number of ways to work around it without impairing the application.

One solution is to use “deferred execution� (via promises and futures). The basic idea with promises is that, rather than issuing blocking calls for resources, you immediately return a promise for a future value that will eventually be fulfilled. This rather easily allows you to write non-blocking logic that can be run asynchronously. It is common to introduce callbacks into this equation that execute once the request completes.

I’ve written a relatively comprehensive post on this with Julian Aubourg, if you’re interested in doing this through jQuery, but it can of course be implemented with vanilla JavaScript as well.

Micro-framework Q offers a CommonJS-compatible implementation of promises and futures that is relatively comprehensive and can be used as follows:

/* define a promise-only delay function that resolves when a timeout completes */
function delay(ms) {
    var deferred = Q.defer();
    setTimeout(deferred.resolve, ms);
    return deferred.promise;
}

/* usage of Q with the 'when' pattern to execute a callback once delay fulfils the promise */
Q.when(delay(500), function () {
        /* do stuff in the callback */
});

If you’re looking for something more basic that can be read through, then here is Douglas Crockford’s implementation of promises:

function make_promise() {
  var status = ’unresolved’,
      outcome,
      waiting = [],
      dreading = []; 

  function vouch( deed, func ) {
    switch (status) {
    case ’unresolved’:
      (deed === ’fulfilled’ ? waiting : dreading).push(func);
      break;
    case deed:
      func(outcome);
      break;
    }
  };

  function resolve( deed, value ) {
    if (status !== ’unresolved’) {
      throw new Error(’The promise has already been resolved:’ + status);
    }
    status = deed;
    outcome = value;
    (deed == ’fulfilled’ ? waiting : dreading).forEach(function (func) {
      try {
        func(outcome);
      } catch (ignore) {}
    });
    waiting = null;
    dreading = null;
  };

  return {
    when: function ( func ) {
      vouch(’fulfilled’, func);
    },
    fail: function ( func ) {
      vouch(’smashed’, func);
    },
    fulfill: function ( value ) {
      resolve(’fulfilled’, value);
    },
    smash: function ( string ) {
      resolve(’smashed’, string);
    },
    status: function () {
      return status;
    }
  };
};

Problem 5

Problem: You’re testing for explicit numeric equality of a property using the == operator, but you should probably be using === instead

Feedback: As you may or may not know, the identity == operator in JavaScript is fairly liberal and considers values to be equal even if they’re of completely different types. This is due to the operator forcing a coercion of values into a single type (usually a number) prior to performing any comparison. The === operator will, however, not do this conversion, so if the two values being compared are not of the same type, then === will just return false.

The reason I recommend considering === for more specific type comparison (in this case) is that == is known to have a number of gotchas and is considered to be unreliable by many developers.

You might also be interested to know that in abstractions of the language, such as CoffeeScript, the == operator is completely dropped in favor of === beneath the hood due to the former’s unreliability.

Rather than take my word for it, see the examples below of boolean checks for equality using ==, some of which result in rather unexpected outputs.

3 == "3" // true
3 == "03" // true
3 == "0003" // true
3 == "+3" //true
3 == [3] //true
3 == (true+2) //true
’ \t\r\n ’ == 0 //true
"\t\r\n" == 0 //true
"\t" == 0 // true
"\t\n" == 0 // true
"\t\r" == 0 // true
" " == 0 // true
" \t" == 0 // true
" \ " == 0 // true
" \r\n\ " == 0 //true

The reason that many of the (stranger) results in this list evaluate to true is because JavaScript is a weakly typed language: it applies type coercion wherever possible. If you’re interested in learning more about why some of the expressions above evaluate to true, look at the Annotated ES5 guide, whose explanations are rather fascinating.

Back to the review. If you’re 100% certain that the values being compared cannot be interfered with by the user, then proceed with using the == operator with caution. Just remember that === covers your bases better in the event of an unexpected input.

Problem 6

Problem: An uncached array length is being used in all for loops. This is particularly bad because you’re using it when iterating through an HTMLCollection.

Here’s an example:

for( var i=0; i<myArray.length;i++ ){
    /* do stuff */
}

Feedback: The problem with this approach (which I still see a number of developers using) is that the array length is unnecessarily re-accessed on each loop’s iteration. This can be very slow, especially when working with HTMLCollections (in which case, caching the length can be anywhere up to 190 times faster than repeatedly accessing it, as Nicholas C. Zakas mentions in his book High-Performance JavaScript). Below are some options for caching the array length.

/* cached outside loop */
var len = myArray.length;
for ( var i = 0; i < len; i++ ) {
}

/* cached inside loop */
for ( var i = 0, len = myArray.length; i < len; i++ ) {
}

/* cached outside loop using while */
var len = myArray.length;
while (len--) {
}

A jsPerf test that compares the performance benefits of caching the array length inside and outside the loop, using prefix increments, counting down and more is also available, if you would like to study which performs the best.

Problem 7

Problem: jQuery’s $.each() is being used to iterate over objects and arrays, in some cases while for is being used in others.

Feedback: In jQuery, we have two ways to seamlessly iterate over objects and arrays. The generic $.each iterates over both of these types, whereas $.fn.each() iterates over a jQuery object specifically (where standard objects can be wrapped with $() should you wish to use them with the latter). While the lower-level $.each performs better than $.fn.each(), both standard JavaScript for and while loops perform much better than either, as proven by this jsPerf test. Below are some examples of loop alternatives that also perform better:

/* jQuery $.each */
$.each(a, function() {
 e = $(this);
});

/* classic for loop */
var len = a.length;
for ( var i = 0; i < len; i++ ) {
    //if this must be a jQuery object do..
    e = $(a[i]);
    //otherwise just e = a[i] should suffice
};

/* reverse for loop */
for ( var i = a.length; i-- ) {
    e = $(a[i]);
}

/* classic while loop */
var i = a.length;
while (i--) {
    e = $(a[i]);
}

/* alternative while loop */
var i = a.length - 1;

while ( e = a[i--] ) {
    $(e)
};

You might find Angus Croll’s post on “Rethinking JavaScript for Loops� an interesting extension to these suggestions.

Given that this is a data-centric application with a potentially large quantity of data in each object or array, you should consider a refactor to use one of these. From a scalability perspective, you want to shave off as many milliseconds as possible from process-heavy routines, because these can build up when hundreds or thousands of elements are on the page.

Problem 8

Problem: JSON strings are being built in-memory using string concatenation.

Feedback: This could be approached in more optimal ways. For example, why not use JSON.stringify(), a method that accepts a JavaScript object and returns its JSON equivalent. Objects can generally be as complex or as deeply nested as you wish, and this will almost certainly result in a simpler, shorter solution.

var myData = {};
myData.dataA = [’a’, ’b’, ’c’, ’d’];
myData.dataB = {
    ’animal’: ’cat’,
    ’color’: ’brown’
};
myData.dataC = {
    ’vehicles’: [{
        ’type’: ’ford’,
        ’tint’: ’silver’,
        ’year’: ’2015’
    }, {
        ’type’: ’honda’,
        ’tint’: ’black’,
        ’year’: ’2012’
    }]
};
myData.dataD = {
    ’buildings’: [{
        ’houses’: [{
            ’streetName’: ’sycamore close’,
            ’number’: ’252’
        }, {
            ’streetName’: ’slimdon close’,
            ’number’: ’101’
        }]
    }]
};
console.log(myData); //object
var jsonData = JSON.stringify(myData);

console.log(jsonData);
/*
{"dataA":["a","b","c","d"],"dataB":{"animal":"cat","color":"brown"},"dataC":{"vehicles":[{"type":"ford","tint":"silver","year":"2015"},{"type":"honda","tint":"black","year":"2012"}]},"dataD":{"buildings":[{"houses":[{"streetName":"sycamore close","number":"252"},{"streetName":"slimdon close","number":"101"}]}]}}
 */

As an extra debugging tip, if you would like to pretty-print JSON in your console for easier reading, then the following extra arguments to stringify() will achieve this:

JSON.stringify({ foo: "hello", bar: "world" }, null, 4);

Problem 9

Problem: The namespacing pattern used is technically invalid.

Feedback: While namespacing is implemented correctly across the rest of the application, the initial check for namespace existence is invalid. Here’s what you currently have:

if ( !MyNamespace ) {
  MyNamespace = { };
}

The problem is that !MyNamespace will throw a ReferenceError, because the MyNamespace variable was never declared. A better pattern would take advantage of boolean conversion with an inner variable declaration, as follows:

if ( !MyNamespace ) {
  var MyNamespace = { };
}

//or
var myNamespace = myNamespace || {};

// Although a more efficient way of doing this is:
// myNamespace || ( myNamespace = {} );
// jsPerf test: http://jsperf.com/conditional-assignment

//or
if ( typeof MyNamespace == ’undefined’ ) {
  var MyNamespace = { };
}

This could, of course, be done in numerous other ways. If you’re interested in reading about more namespacing patterns (as well as some ideas on namespace extension), I recently wrote “Essential JavaScript Namespacing Patterns.� Juriy Zaytsev also has a pretty comprehensive post on namespacing patterns.

Conclusion

That’s it. Reviewing code is a great way to enforce and maintain quality, correctness and consistency in coding standards at as high a level as possible. I strongly recommend that all developers give them a try in their daily projects, because they’re an excellent learning tool for both the developer and the reviewer. Until next time, try getting your code reviewed, and good luck with the rest of your project!

(al) (il)


© Addy Osmani for Smashing Magazine, 2011.


A Quick Look Into The Math Of Animations With JavaScript





 



 


In school, I hated math. It was a dire, dry and boring thing with stuffy old books and very theoretical problems. Even worse, a lot of the tasks were repetitive, with a simple logical change in every iteration (dividing numbers by hand, differentials, etc.). It was exactly the reason why we invented computers. Suffice it to say, a lot of my math homework was actually done by my trusty Commodore 64 and some lines of Basic, with me just copying the results later on.

These tools and the few geometry lessons I had gave me the time and inspiration to make math interesting for myself. I did this first and foremost by creating visual effects that followed mathematical rules in demos, intros and other seemingly pointless things.

There is a lot of math in the visual things we do, even if we don’t realize it. If you want to make something look natural and move naturally, you need to add a bit of physics and rounding to it. Nature doesn’t work in right angles or linear acceleration. This is why zombies in movies are so creepy. This was covered here before in relation to CSS animation, but today let’s go a bit deeper and look at the simple math behind the smooth looks.

Going From 0 To 1 Without Being Boring

If you’ve just started programming and are asked to go from 0 to 1 with a few steps in between, you would probably go for a for loop:

for ( i = 0; i <= 1; i += 0.1 ) {
  x = i;
  y = i;
…
}

This would result in a line on a graph that is 45 degrees. Nothing in nature moves with this precision:

45 degree graph, a result of a simple for loop

A simple way to make this movement a bit more natural would be to simply multiply the value by itself:

for ( i = 0; i <= 1; i += 0.1 ) {
  x = i;
  y = i * i;
}

This means that 0.1 is 0.01, 0.2 is 0.04, 0.3 is 0.09, 0.4 is 0.16, 0.5 is 0.25 and so on. The result is a curve that starts flat and then gets steeper towards the end:

graph of the value multiplied with itself

You can make this even more pronounced by continuing to multiply or by using the “to the power of� Math.pow() function:

for ( i = 0; i <= 1; i += 0.1 ) {
  x = i;
  y = Math.pow( i, 4 );
}

graph with several multiplications

This is one of the tricks of the easing functions used in libraries such as jQuery and YUI, as well as in CSS transitions and animations in modern browsers.

You can use this the same way, but there is an even simpler option for getting a value between 0 and 1 that follows a natural motion.

Not A Sin, Just A Natural Motion

Sine waves are probably the best thing ever for smooth animation. They happen in nature: witness a spring with a weight on it, ocean waves, sound and light.
In our case, we want to move from 0 to 1 smoothly.

To create a movement that goes from 0 to 1 and back to 0 smoothly, we can use a sine wave that goes from 0 to π in a few steps. The full sine wave going from 0 to π × 2 (i.e. a whole circle) would result in values from -1 to 1, and we don’t want that (yet).

var counter = 0;

// 100 iterations
var increase = Math.PI / 100;

for ( i = 0; i <= 1; i += 0.01 ) {
  x = i;
  y = Math.sin(counter);
  counter += increase;
}

half a sine wave

A quick aside on numbers for sine and cosine: Both Math.sin() and Math.cos() take as the parameter an angle that should be in radians. As humans, however, degrees ranging from 0 to 360 are much easier to read. That’s why you can and should convert between them with this simple formula:

var toRadian = Math.PI / 180;
var toDegree = 180 / Math.PI;

var angle = 30;

var angleInRadians = angle * toRadian;
var angleInDegrees = angleInRadians * toDegree;

Back to our sine waves. You can play with this a lot. For example, you could use the absolute value of a full 2 × π loop:

var counter = 0;
// 100 iterations
var increase = Math.PI * 2 / 100;

for ( i = 0; i <= 1; i += 0.01 ) {
  x = i;
  y = Math.abs( Math.sin( counter ) );
  counter += increase;
}

absolute value of a sine wave

But again, this looks dirty. If you want the full up and down, without a break in the middle, then you need to shift the values. You have to half the sine and then add 0.5 to it:

var counter = 0;
// 100 iterations
var increase = Math.PI * 2 / 100;

for ( i = 0; i <= 1; i += 0.01 ) {
  x = i;
  y = Math.sin( counter ) / 2 + 0.5;
  counter += increase;
}

halfed and moved sine wave

So, how can you use this? Having a function that returns -1 to 1 to whatever you feed it can be very cool. All you need to do is multiply it by the values that you want and add an offset to avoid negative numbers.

For example, check out this sine movement demo:

Sine jump demo

Looks neat, doesn’t it? A lot of the trickery is already in the CSS:

.stage {
  width:200px;
  height:200px;
  margin:2em;
  position:relative;
  background:#6cf;
  overflow:hidden;
}

.stage div {
  line-height:40px;
  width:100%;
  text-align:center;
  background:#369;
  color:#fff;
  font-weight:bold;
  position:absolute;
}

The stage element has a fixed dimension and is positioned relative. This means that everything that is positioned absolutely inside it will be relative to the element itself.

The div inside the stage is 40 pixels high and positioned absolutely. Now, all we need to do is move the div with JavaScript in a sine wave:

var banner = document.querySelector( '.stage div' ),
    start = 0;
function sine(){
  banner.style.top = 50 * Math.sin( start ) + 80 + 'px';
  start += 0.05;
}
window.setInterval( sine, 1000/30 );

The start value changes constantly, and with Math.sin() we get a nice wave movement. We multiply this by 50 to get a wider wave, and we add 80 pixels to center it in the stage element. Yes, the element is 200 pixels high and 100 is half of that, but because the banner is 40 pixels high, we need to subtract half of that to center it.

Right now, this is a simple up-and-down movement. Nothing stops you, though, from making it more interesting. The multiplying factor of 50, for example, could be a sine wave itself with a different value:

var banner = document.querySelector( '.stage div' ),
    start = 0,
    multiplier = 0;
function sine(){
  multiplier = 50 * Math.sin( start * 2 );
  banner.style.top = multiplier * Math.sin( start ) + 80 + 'px';
  start += 0.05;
}
window.setInterval( sine, 1000/30 );

The result of this is a banner that seems to tentatively move up and down. Back in the day and on the very slow Commodore 64, calculating the sine wave live was too slow. Instead, we had tools to generate sine tables (arrays, if you will), and we plotted those directly. One of the tools for creating great sine waves so that you could have bouncing scroll texts was the Wix Bouncer:

Wixbouncer - a tool to create sine waves

Circles In The Sand, Round And Round…

Circular motion is a thing of beauty. It pleases the eye, reminds us of spinning wheels and the earth we stand on, and in general has a “this is not computer stuff� feel to it. The math of plotting something on a circle is not hard.

It goes back to Pythagoras, who, as rumor has it, drew a lot of circles in the sand until he found his famous theorem. If you want to use all the good stuff that comes from this theorem, then try to find a triangle with a right angle. If this triangle’s hypothenuse is 1, then you can easily calculate the horizontal leg as the cosine of the angle and the vertical leg as the sine of the angle:

Sincos

How is this relevant to a circle? Well, it is pretty simple to find a right-angle triangle in a circle to every point of it:

Circle

This means that if you want to plot something on a circle (or draw one), you can do it with a loop and sine and cosine. A full circle is 360°, or 2 × π in radians. We could have a go at it — but first, some plotting code needs to be done.

A Quick DOM Plotting Routine

Normally, my weapon of choice here would be canvas, but in order to play nice with older browsers, let’s do it in plain DOM. The following helper function adds div elements to a stage element and allows us to position them, change their dimensions, set their color, change their content and rotate them without having to go through the annoying style settings on DOM elements.

Plot = function ( stage ) {

  this.setDimensions = function( x, y ) {
    this.elm.style.width = x + 'px';
    this.elm.style.height = y + 'px';
    this.width = x;
    this.height = y;
  }
  this.position = function( x, y ) {
    var xoffset = arguments[2] ? 0 : this.width / 2;
    var yoffset = arguments[2] ? 0 : this.height / 2;
    this.elm.style.left = (x - xoffset) + 'px';
    this.elm.style.top = (y - yoffset) + 'px';
    this.x = x;
    this.y = y;
  };
  this.setbackground = function( col ) {
    this.elm.style.background = col;
  }
  this.kill = function() {
    stage.removeChild( this.elm );
  }
  this.rotate = function( str ) {
    this.elm.style.webkitTransform = this.elm.style.MozTransform =
    this.elm.style.OTransform = this.elm.style.transform =
    'rotate('+str+')';
  }
  this.content = function( content ) {
    this.elm.innerHTML = content;
  }
  this.round = function( round ) {
    this.elm.style.borderRadius = round ? '50%/50%' : '';
  }
  this.elm = document.createElement( 'div' );
  this.elm.style.position = 'absolute';
  stage.appendChild( this.elm );

};

The only things that might be new here are the transformation with different browser prefixes and the positioning. People often make the mistake of creating a div with the dimensions w and h and then set it to x and y on the screen. This means you will always have to deal with the offset of the height and width. By subtracting half the width and height before positioning the div, you really set it where you want it — regardless of the dimensions. Here’s a proof:

offset issue

Now, let’s use that to plot 10 rectangles in a circle, shall we?

Simple circle

var stage = document.querySelector('.stage'),
    plots = 10;
    increase = Math.PI * 2 / plots,
    angle = 0,
    x = 0,
    y = 0;

for( var i = 0; i < plots; i++ ) {
  var p = new Plot( stage );
  p.setBackground( 'green' );
  p.setDimensions( 40, 40 );
  x = 100 * Math.cos( angle ) + 200;
  y = 100 * Math.sin( angle ) + 200;
  p.position( x, y );
  angle += increase;
}

We want 10 things in a circle, so we need to find the angle that we want to put them at. A full circle is two times Math.PI, so all we need to do is divide this. The x and y position of our rectangles can be calculated by the angle we want them at. The x is the cosine, and the y is the sine, as explained earlier in the bit on Pythagoras. All we need to do, then, is center the circle that we’re painting in the stage (200,200 is the center of the stage), and we are done. We’ve painted a circle with a radius of 100 pixels on the canvas in 10 steps.

The problem is that this looks terrible. If we really want to plot things on a circle, then their angles should also point to the center, right? For this, we need to calculate the tangent of the right-angle square, as explained in this charming “Math is fun� page. In JavaScript, we can use Math.atan2() as a shortcut. The result looks much better:

Tancircle

var stage = document.querySelector('.stage'),
    plots = 10;
    increase = Math.PI * 2 / plots,
    angle = 0,
    x = 0,
    y = 0;

for( var i = 0; i < plots; i++ ) {
  var p = new Plot( stage );
  p.setBackground( 'green' );
  p.setDimensions( 40, 40 );
  x = 100 * Math.cos( angle ) + 200;
  y = 100 * Math.sin( angle ) + 200;
  p.rotate( Math.atan2( y - 200, x - 200 ) + 'rad' );
  p.position( x, y );
  angle += increase;
}

Notice that the rotate transformation in CSS helps us heaps in this case. Otherwise, the math to rotate our rectangles would be much less fun. CSS transformations also take radians and degrees as their value. In this case, we use rad; if you want to rotate with degrees, simply use deg as the value.

How about animating the circle now? Well, the first thing to do is change the script a bit, because we don’t want to have to keep creating new plots. Other than that, all we need to do to rotate the circle is to keep increasing the start angle:

var stage = document.querySelector('.stage'),
    plots = 10;
    increase = Math.PI * 2 / plots,
    angle = 0,
    x = 0,
    y = 0,
    plotcache = [];

for( var i = 0; i < plots; i++ ) {
  var p = new Plot( stage );
  p.setBackground( 'green' );
  p.setDimensions( 40, 40 );
  plotcache.push( p );
}

function rotate(){
  for( var i = 0; i < plots; i++ ) {
    x = 100 * Math.cos( angle ) + 200;
    y = 100 * Math.sin( angle ) + 200;
    plotcache[ i ].rotate( Math.atan2( y - 200, x - 200 ) + 'rad' );
    plotcache[ i ].position( x, y );
    angle += increase;
  }
  angle += 0.06;
}

setInterval( rotate, 1000/30 );

Want more? How about a rotating text message based on this? The tricky thing about this is that we also need to turn the characters 90° on each iteration:

Rotated message

var stage = document.querySelector('.stage'),
    message = 'Smashing Magazine '.toUpperCase(),
    plots = message.length;
    increase = Math.PI * 2 / plots,
    angle = -Math.PI,
    turnangle = 0,
    x = 0,
    y = 0,
    plotcache = [];

for( var i = 0; i < plots; i++ ) {
  var p = new Plot( stage );
  p.content( message.substr(i,1) );
  p.setDimensions( 40, 40 );
  plotcache.push( p );
}
function rotate(){
  for( var i = 0; i < plots; i++ ) {
    x = 100 * Math.cos( angle ) + 200;
    y = 100 * Math.sin( angle ) + 200;
    // rotation and rotating the text 90 degrees
    turnangle = Math.atan2( y - 200, x - 200 ) * 180 / Math.PI + 90 + 'deg';
    plotcache[ i ].rotate( turnangle );
    plotcache[ i ].position( x, y );
    angle += increase;
  }
  angle += 0.06;
}

setInterval( rotate, 1000/40 );

Again, nothing here is fixed. You can make the radius of the circle change constantly, as we did with the bouncing banner message earlier (below is only an excerpt):

multiplier = 80 * Math.sin( angle );
for( var i = 0; i < plots; i++ ) {
  x = multiplier * Math.cos( angle ) + 200;
  y = multiplier * Math.sin( angle ) + 200;
  turnangle = Math.atan2( y - 200, x - 200 ) * 180 / Math.PI + 90 + 'deg';
  plotcache[ i ].rotate( turnangle );
  plotcache[ i ].position( x, y );
  angle += increase;
}
angle += 0.06;

And, of course, you can move the center of the circle, too:

rx = 50 * Math.cos( angle ) + 200;
ry = 50 * Math.sin( angle ) + 200;
for( var i = 0; i < plots; i++ ) {
  x = 100 * Math.cos( angle ) + rx;
  y = 100 * Math.sin( angle ) + ry;
  turnangle = Math.atan2( y - ry, x - rx ) * 180 / Math.PI + 90 + 'deg';
  plotcache[ i ].rotate( turnangle );
  plotcache[ i ].position( x, y );
  angle += increase;
}
angle += 0.06;

For a final tip, how about allowing only a certain range of coordinates?

function rotate() {
  rx = 70 * Math.cos( angle ) + 200;
  ry = 70 * Math.sin( angle ) + 200;
  for( var i = 0; i < plots; i++ ) {
    x = 100 * Math.cos( angle ) + rx;
    y = 100 * Math.sin( angle ) + ry;
    x = contain( 70, 320, x );
    y = contain( 70, 320, y );
    turnangle = Math.atan2( y - ry, x - rx ) * 180 / Math.PI + 90 + 'deg';
    plotcache[ i ].rotate( turnangle );
    plotcache[ i ].position( x, y );
    angle += increase;
  }
  angle += 0.06;
}
function contain( min, max, value ) {
  return Math.min( max, Math.max( min, value ) );
}

Summary

This was just a quick introduction to using exponentials and sine waves and to plotting things on a circle. Have a go with the code, and play with the numbers. It is amazing how many cool effects you can create with a few changes to the radius or by multiplying the angles. To make it easier for you to do this, below are the examples on JSFiddle to play with:

(il) (al)


© Christian Heilmann for Smashing Magazine, 2011.


Designers Know Your Code: Web Design Tutorials


  

As almost any web designer worth their salt, and a large percentage of web developers will tell you, to be fully considered a web designer you have to have some background in code. Not to the depth that full on developers must, but it really is unfair to the rest of those working on a website with us if we do not have some knowledge in a handful of key areas. Which is where these web design tutorials come in.

In this post we have gathered a handful of useful tutorials from these various areas of code that designers should have their hands in. We have standard CSS and CSS3 tutorials, HTML5 and also Javascript tuts as well. A little something for all three of the main code branches that web designers need to always be improving their grasps on. We hope that you find these web design tutorials helpful in your next or current project!

CSS Tutorials

30 CSS Best Practices for Beginners – CSS is a language that is used by nearly every developer at some point. While it’s a language that we sometimes take for granted, it is powerful and has many nuances that can help (or hurt) our designs. Here are thirty of the best CSS practices that will keep you writing solid CSS and avoiding some costly mistakes.

6 Ways To Improve Your Web Typography – Typography on the web is anything but simple, and for many, it is a troubling mystery. Today, we’re going to review six ways that web designers and developers can improve the typography of the sites they create.

3 Easy and Fast CSS Techniques for Faux Image Cropping – This article is a summary of a 3 fast and easy CSS techniques you can use to display only a portion of an image in your content. All techniques explained here actually need only couple of lines of CSS.

Build Multi-level Multi-column Multi Menus with pure CSS – works perfectly in most browsers, including IE 6, using absolutely no javascript

CSS Absolute Positioning: Create A Fancy Link Block – some tricks to create a fancy link block that make our links more attractive.

How to Create a Beautiful Dropdown Blogroll Without JavaScript – Dropdown menus are a great way of including a long list of links without cluttering up your page. The issue though is that they can be hard to style, but look quite ugly if you don’t. There isn’t a lot of flexibility with HTML’s select tags.

CSS3 Tutorials

CSS3 Minimalistic Navigation Menu – a simple CSS3 animated navigation menu, which degrades gracefully in older browsers and is future-proofed to work with the next generation of browsers.

CSS3 Tutorial: Sleek Card Pockets using CSS Only – learn how to create web card pockets using some great new CSS3 techniques.

CSS3 Animated Vignette Buttons – This tutorial uses a patterned background and places vignette-style .pngs over the top which are animated using transition.

CSS3 Music Player Menu – This tutorial maximizes power of CSS3 to create a CSS Music Player Menu with a Photoshop-like effect.

3D Animation Using Pure CSS3 – This tutorial uses the perspective property to create the 3d effect and transform and transition, to animate it.

Create a Swish CSS3 Folded Ribbon in 5 Minutes – Take one line of markup, a couple of CSS3 rules (no images), and you can have yourself a swish folded ribbon effect in five minutes.

HTML5 Tutorials

HTML5 : The Basics – This tutorial introduces HTML5 and its basic features as well as explains the key differences from HTML 4.01 and XHTML 1.0 so you can start preparing yourself and your sites for the transition.

Have A Field Day With HTML5 Forms – Take a look at how to style a beautiful HTML5 form using some advanced CSS and latest CSS3 techniques.

Preparing for HTML5 with Semantic Class Names – A brief introduction to the new structural elements in the HTML 5 Working Draft, and how to use semantic class names in HTML 4.01 or XHTML 1.0 markup that correspond to the names of those structural elements.

Drag and Drop – This tutorial will teach you how to create a HTML 5 page that uses the new drag and drop feature.

How to Make an HTML5 iPhone App – This tutorial will show you how to create an offline HTML5 iPhone application, specifically, a tetris game.

Create Vector Masks Using the HTML5 Canvas – This tutorial looks at how to use the canvas tag and clipping to create images that aren’t so rectangular.

Javascript Tutorials

Javascript – An easy introduction – Javascript is used to add interactivity and functionality to a site. It has many uses, from detecting the viewers web browser to validating form input.

Nested Arrays in Javascript – Like most programming languages, JavaScript lets you create arrays inside arrays, known as nested arrays. In a nested array, the elements of one array are themselves arrays.

jQuery for Absolute Beginners – Fifteen video tutorials that teach you EXACTLY how to use the jQuery library. Start by downloading the library and eventually work up to creating an AJAX style-switcher.

iPhoto-like image resizing using Javascript – This tutorial uses the script.aculo.us slider control to capture input values, then converts those values into something useful.

Learn How To Detect Browser in Javascript – In this tutorial you will learn how to detect the browser in javascript so that you can then serve the suitable information.

Words Validation with Javascript – This tutorial will explain you how to filter out inappropriate words from being updated or sent from your website.

(rb)


  •   
  • Copyright © 1996-2010 BlogmyQuery - BMQ. All rights reserved.
    iDream theme by Templates Next | Powered by WordPress