Coding guidelines
General
All code in a single library or code base should look like a single person wrote it. This means that contributors should adhere to the coding standard that exists within a library to keep the code consistent and avoid confusion.
- Indentation should be 2 spaces, no tabs.
- No trailing whitespace at the end of the line.
- Source files should have Unix line endings(\n).
- All binary and bit operators should be surrounded with whitespaces. Unary operators should not.
Control structures should be formatted like this:
if (foo && bar) { foobar(); } else if (foo || bar) { foo(bar); } else { bar(foo); } switch (foo) { case 1: bar(); break; default: foo(); }
Use camelCase. Classes / constructors start with a capital letter.
Use JSDoc style to document functions.
Remember to make it possible to localize all text strings in the GUI.
Filenames and URLs
An obvious filename is a great filename. If a user can look at the file and make an accurate guess about the contents of the file before ever opening it, you've done your job.
When creating filenames with multiple words in the format of a phrase, hyphens are best to separate the terms, e.g. drag-and-drop.js.
JavaScript
General
- Always declare variables, avoid polluting the global namespace.
- Var declarations should be at the beginning of their respective function scopes because declarations get hoisted to the top of their scope, but not their assignment.
- Use the literal syntax for array and object creation. E.g. var item = {}; not var item = new Object();
- Do not use reserved words as keys. A list of javascript reserved keywords can be found at MDN.
- Strings should be surrounded by single quotes. Strings longer than 80 characters should be concatenated across multiple lines.
- Use thoughtful naming and a readable structure.
- camelCase in functions and variables.
- PascalCase in constructor and library names.
- UPPERCASE_NAME in symbolic constants.
- Create an alias to this using self as an identifier inside scopes.
- Typechecking should check both typeof and instanceof (typeOf message === "string" || message instanceOf String)
- Use as few DOM insertions as possible, modifying detached nodes are significantly faster than when they are attached.
- Use dot notation when accessing objects.
- Use /** .... */ for multiline comments, use // for single line comments.
Structure
It might be wise sticking with a well-known design pattern. E.g. Revealing Module Pattern
var MyNamespace = MyNamespace || {}; /** * MyNamespace Test Module. */ MyNamespace.Test = (function ($) { // Cached. Context is shared between instances. var totalDevices = 0; /** * Test Device Constructor * * @param {String} name */ function TestDevice(name) { // Private var calls = 0; // Keep track of total number of devices on the page totalDevices++; /** * Private. Increase calls. */ var call = function () { calls++; }; /** * Public. * * @returns {String} */ this.toString = function () { call(); return 'My name is: ' + name; }; }; /** * Test Constructor * * @param {Object} parameters * @param {Number} id */ function Test(parameters, id) { // Pro Tip: Naming constructors makes it easier to debug! var testDevices = []; for (var i = 0; i < parameters.devices.length; i++) { testDevices.push(new TestDevice(parameters.devices])); } /** * Public. Attach html to the given container. * * @param {jQuery} $container */ this.attach = function ($container) { var html = ''; for (var i = 0; i < testDevices.length; i++) { html += testDevices[i]; } $container.addClass('mynamespce-test').html(html); }; }; /** * Public static. */ Test.getTotalDevices = function () { return totalDevices; }; return Test; })(H5P.jQuery);
To learn more about JavaScript Design Patterns check out this book.
Remember to use spacing when creating anonymous functions and put semi-colons after every expression!
Graphics
Try using graphics that scales well on different devices and browsers. Use fonts for icons and SVG for larger images.
Buttons
Try to stick with buttons for actions and anchor tags for links. Any tag can easily be transformed into a button:
<ul class="mynamespace-actions"> <li role="button" tabindex="1">Copy</li> <li role="button" tabindex="1">Paste</li> </ul>
Animations
Favor CSS3 animations over using JavaScript.
Modern browsers can leverage the GPU to animate the following styles very well:
- Position - transform: translateX(n) translateY(n) translateZ(n);
- Scale - transform: scale(n);
- Rotation - transform: rotate(ndeg);
- Opacity - opacity: n;
By favouring these solutions over e.g. "left: -1000px;", you will get much smoother animations.
You can read more details about these thechniques in this blog post.