At some point while learning, we've all come to this point, right?
Commercial or professional procedures that are accepted or prescribed as being correct or most effective.
==
a set of informal rules that the software development community has learned over time which can help improve the quality of software.
==
a belief without true understanding,
perception, or discrimination
Are Best Practices just blind faith in
people that came before us
or that we deem smarter than us?
To encourage everyone to look at best practices and know WHY they use the ones they do, and WHEN to discard ones that no longer are effective.
Make sure they really are, and know when to follow them
And when to ignore them
Let's take a look at some best practices
Some are obvious, others we'll talk about the why a bit more
Help screen readers, Google, and other
machines/bots parse meaning from markup
<div class="header">
<ul class="nav"></ul>
</div>
<div class="body"></div>
<div class="footer"></div>
<!-- vs -->
<header>
<nav></nav>
</header>
<section></section>
<footer></footer>
<!doctype html>
<html class="no-js" lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Place favicon.ico and apple-touch-icon(s) in the root directory -->
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/main.css">
<script src="js/vendor/modernizr-2.8.0.min.js"></script>
</head>
<body>
<!--[if lt IE 8]>
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
<![endif]-->
<!-- Add your site or application content here -->
<p>Hello world! This is HTML5 Boilerplate.</p>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/vendor/jquery-1.11.1.min.js"><\/script>')</script>
<script src="js/plugins.js"></script>
<script src="js/main.js"></script>
<!-- Google Analytics: change UA-XXXXX-X to be your site's ID. -->
<script>
(function(b,o,i,l,e,r){b.GoogleAnalyticsObject=l;b[l]||(b[l]=
function(){(b[l].q=b[l].q||[]).push(arguments)});b[l].l=+new Date;
e=o.createElement(i);r=o.getElementsByTagName(i)[0];
e.src='//www.google-analytics.com/analytics.js';
r.parentNode.insertBefore(e,r)}(window,document,'script','ga'));
ga('create','UA-XXXXX-X');ga('send','pageview');
</script>
</body>
</html>
<!doctype html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang=""> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8" lang=""> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9" lang=""> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang=""> <!--<![endif]-->
Provide Stylesheet information and indicate structure
/* stylesheet for Corp Bar
File created date: 09.15.2010
Last modified date: 06.04.2012
By: [name]
For: [section]
*/
/* Table of Contents
- Typeography
- Link Styles
- Other sitewide styles
- Actions
- Layout
- HEADER
- TOP NAV
- MAINCONTENT
- FOOTER
*/
(…later in the document…)
/* =Layout */ (etc.)
/* Bad */
#sidebar {
background-color: #fff;
background-image: (bg.png);
background-position: 0 0;
background-repeat: repeat-x;
border-width: 1px;
border-style: solid;
border-color: #ffff00;
font-family: Georgia, serif;
font-size: 1.33em;
line-height: 1.33em;
font-weight: normal;
margin: 10px 20px 10px 20px;
padding: .1em;
}
/* Better */
.sidebar {
background: #fff url(bg.png) repeat-x 0 0;
border: 1px solid #ff0;
font: normal 1.33em/1.33 Georgia, serif;
margin: 10px 20px;
padding: .1em;
}
Prefer multiple, smaller CSS files over a single monolithic file.
Concatenate and minify for performance
Quickly becoming best practice to use a preprocessor
Oh, which one, Sass, Less or Stylus? Flip a coin, draw
straws...or just base it on your framework
SMACSS is a popular style
<div class="fldr fldr-callout">
<h2 class="fldr-name">Folder Name</h2>
<span class="fldr-items">(32 items)</span>
</div>
Bootstrap and Foundation are very popular now
They are NOT best practices by themselves however
All together now...
Know the difference, and use them appropriately
... wait, what? You thought it was always use ===?
// Use === when both type and value equality matter
// or when inconsistent input may cause problems
if(1 === '1') //Returns false
if(1 == '1') //Returns true
if(0 === '') //Returns false
if(0 == '') //Returns true
// Use == when the types are predetermined and known
// Or when it is more concise and clear than otherwise
if (typeof foo == 'undefined') // typeof always returns a string
if (foo.indexOf(bar) != -1) // indexOf always returns a number
if (foo != null)
// more concise than checking null and undefined, but still clear
var a = obj
[a].forEach(logProp) // 'fail' : var a = obj[a].forEach(logProp)
Source - Ben Alman
Goto fail bug
hashOut.data = hashes + SSL_MD5_DIGEST_LEN;
hashOut.length = SSL_SHA1_DIGEST_LEN;
if ((err = SSLFreeBuffer(&hashCtx)) != 0)
goto fail;
if ((err = ReadyHash(&SSLHashSHA1, &hashCtx)) != 0)
goto fail;
// ...
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
goto fail;
goto fail; /* MISTAKE! THIS LINE SHOULD NOT BE HERE */
if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
goto fail;
err = sslRawVerify(...); /* SSL certs never fully verified */
Yes...this is C, not JavaScript...example was too good to pass up
Opening curly brace for blocks should go on the
same line as the declaration (in JavaScript)
function foo() {
var bar = 1;
return // Oops! Return == undefined
{
bar: bar
}
}
Use however many spaces per tab as you like
(you do have a standard, right?)
Catch errors before you refresh.
(function(){
'use strict';
name = 'Mike'; // Throws an error, no "var"
var obj = { foo: true, foo: false }; // Error, duplicate property names
}());
Catch potential errors quicker, no side effects for old browsers.[ref]
(function(){
// Do stuff here
}());
Along with "use strict", keeps your variables from leaking into the global scope, makes your code more modular
var app = (function(){
'use strict';
var settings;
return {
init: function(initialSettings) {
settings = initialSettings;
},
getOptions: function () {
return settings.options;
}
};
}());
Set a namespace, then expose just the parts of
your module that you need exposed
History of JavaScript module patterns and variety of examples and links to more reading
So LEARN JavaScript first (at least the basics)
Pass jQuery into your module
(function ($, undefined) {
// ... Do Stuff with $
// Now jQuery scoped locally to $
}(jQuery));
Bonus: undefined really is undefined
Don't put all your code here, just use the
DOM Ready event listener to kick off your init function
(function ($, undefined) {
var app = {
init: function() {
// Do init stuff here
}
}
$(app.init); // app.init called on DOM ready
// Same as: $(function() { app.init(); });
// or: $(document).ready(function() { app.init(); });
}(jQuery));
If you are using a jQuery lookup more than once,
cache the lookup in a variable
$('#item').text('Lorem Ipsum');
$('#item').css('color': '#c00');
// vs.
var $item = $('#item');
$item.text('Lorem Ipsum');
$item.css('color', '#c00');
Use a $ to designate that it is a jQuery object. Controversial?
Use chaining
Format it nicely, more readable, better for debugging also
$item
.text('Lorem Ipsum')
.css('color', '#c00');
But don't abuse chaining
$(this).html("Back")
.siblings("ul")
.stop()
.css({"top":0,"opacity":1.0})
.fadeOut(500)
.focus()
.find("li:last")
.addClass("lastTestimonial")
.parent()
.parent()
.parent()
.addClass("viewAll")
.animate({width:697+"px"}, 1000)
.find(".testimonialsCntnr")
.animate({width:697+"px"}, 1000,
function(){
$(".seeAllTestimonials")
.siblings("ul")
.addClass("isFullyOpen")
.fadeIn(500);
testimonialsBelt.resetBelt();
isAnimating = false;
});
More robust and succint than .children() or
.parent()/.parents() for traversing the DOM
<div class="wrap">
<ul>
<li>
<p><span class="elem">stuff</span></p>
</li>
</ul>
</div>
<script>
var $elem = $('.wrap').find('.elem');
var $wrap = $('.elam').closest('.wrap');
</script>
(function ($, undefined) {
var theater = {
init: function() {
// Setup control events
$('.thtrWrap').on('click', '.theaterNavLink', theater.changeSlide);
$('.thtrWrap').on('click', '.theaterLeft', theater.slideNavPrev);
$('.thtrWrap').on('click', '.theaterRight', theater.slideNavNext);
},
changeSlide: function(e) {
// ...
},
slideNavPrev: function(e) {
// ...
},
slideNavNext: function(e) {
// ...
}
}
$(theater.init);
}(jQuery));
Bonus: Event delegation. Tip: listen on the
closest parent element that isn't dynamic
jQuery Sizzle (selector engine) is very fast
Loops can be slow with .each(),
consider using a for loop
Not Best Practices
for tools to work
There is a reason we have so many people touting best practices, new frameworks, even new languages
We love this business, we love making things.
We set best practices to ensure the business
we love presents it's best face forward.
"Blindly following Best Practices
is not a Best Practice."