HTML and CSS are pretty simple, I would spend almost no time reading about them (Unless this is for some sort of job interview) for the most part you will just be googling "How to I make round borders" until you can do it by rote memorization.
JS, on the other hand, is a tricky beast. I would spend a majority of my time learning not just how to write javascript, but how to write good javascript.
javascript the good parts and Javascript garden is where I would start out learning. Javascript is easy to write, but hard to write well. You need to follow strong conventions otherwise your code will end up looking like spaghetti right quick and in a hurry. If you start playing around with the language, I would suggest using JSLint to make sure you aren't doing anything stupid.
After getting a good strong base in javascript jquery shouldn't be too hard. It is just a javascript library. perusing through the docs and getting a feeling for what it can do is probably all you really need. Just like any library you've used. You didn't learn all of the .Net framework, rather you would google and lookup specifics as you needed them. That is much the way you are likely to use jQuery. It can do a lot and you don't need to know everything it can do to use it effectively.
In short, javascript is where the traps are. The other things you mentioned are "I'm going to google this anyways" so I wouldn't really spend a large amount of time learning them.
http://www.jslint.com/lint.html
> stupid
- true
if blocking (''...Sync'
') methods can be used.
It refers to Node's synchronous file handling functions such as readdirSync
.
> That's where stepping through instructions becomes invaluable. > > Two things greatly concern me about Javascript development: > > 1. lack of a debugger (especially for server-side), and > 2. no pre-execute warn/error phase
Every browser I know of has a debugger built in or one readily available where you can step through code. I'm not sure about server-side javascript though. However, this doesn't always help especially when it comes to events.
> I would like to run my scripts through a compiler/parser and have it tell me where I made syntax errors. Give me warnings. I'm not aware of any such tool for Javascript.
Javascript is an interpreted language so it doesn't need to be compiled. However, there is a pretty good compiler made by google. There is also jslint for syntax checking.
JSLint is a useful tool to check for errors in your code, but I don't see its value beyond that. Take this example of reasonable JavaScript:
function sum() { var total = 0, args = arguments; for (var ii = 0, len = args.length; ii < len; ii++) { total += args[ii]; } return total; }
Not only does this fail (not all vars declared at top of function, and the ++ operator) but the validator crashes at line #3. This is a known bug that Crockford refuses to fix. Try it yourself: http://www.jslint.com/
>I would like to run my scripts through a compiler/parser and have it tell me where I made syntax errors. Give me warnings. I'm not aware of any such tool for Javascript.
You're getting the errors because your linter doesn't know you're running this code in the browser and you have to explicitly configure the linter. There is a config option for jslint http://www.jslint.com/help.html#browser Set this to true. You're also going to want to set the 'devel' config option to true as well.
Or something similar such as jslint, eslint, etc.
I find it very crazy that you would write JavaScript without linting your code. Frighting crazy.
To quote Douglas Crockford
> JavaScript is a sloppy language, but hidden deep inside there is an elegant, better language. helps you to program in that better language and to avoid most of the slop. will reject programs that browsers will accept because is concerned with the quality of your code and browsers are not. You should gladly accept all of 's advice.
There are online tools like JSLint, but honestly you're better off just memorizing the conventions and preventing syntax errors before they occur. Sometimes mis-typed code results in a run-time error, so things like that wouldn't even help you. You should also be learning to write your code in such a way that it's easy to figure out what went wrong.
The "right way", at least according to JSLint, is to not use "for ... in" except in conjunction with hasOwnProperty.
Because of this and several other reasons, the use of "for ... in" is generally discouraged by the javascript community, in the same way that other "bad parts" of javascript (such as "==") are discouraged.
I'm in the same boat as you and have been using Notepad++ as my editor. Jslint / jshint works for reviewing code formatting, it doesn't fix bad code but it does help.
This book helped get my feet under me: https://www.amazon.com/Custom-SharePoint-Solutions-HTML-JavaScript/dp/1484205456
It's difficult. I do not ever use the module pattern (instead I recommend using a real module loader like browserify for CommonJS or require.js for AMD), so if I have a variable in the global scope it's just a variable and thus follows the same naming conventions as elsewhere.
I follow the same naming conventions strongly recommended by both idiomatic.js and Douglas Crockford:
regularVariableNames
are written in "snakeCase" (aka CamelCase starting with a lower case letter).ConstructorNames
, i.e. anything you call with new
, are written in "CamelCase" (starting with an upper case letter).Plus, in the few cases local variables should be treated as constants, those are written in UPPER_CASE_WITH_UNDERSCORES
to set them apart as special.
Additionally I follow the convention of using underscore prefixes for "private" methods and properties, i.e. "things you should probably not manipulate directly but we're all adults here so use them if you dare".
So to answer the specific question: library names should be capitalized the same way they would be capitalized if they were local variables.
The only exception I tolerate is React, which names components with CamelCase to set them apart from HTML element names in JSX.
one error I see is in the init function: setTimeout("changeBackground()", 2000); change it to: setTimeout(changeBackground, 2000); same goes for: setTimeout("fade()", 40);
and var images = new Array(); images[0] = 'url("content/restaurant.jpg")'; images[1] = 'url("content/restaurant2.jpg")'; images[2] = 'url("content/restaurant3.jpg")'; would look better as: var images = [ 'url("content/restaurant.jpg")', 'url("content/restaurant2.jpg")', 'url("content/restaurant3.jpg")', ];
as for making it run cross browser, jQuery is indeed a good idea, but if you want to do it yourself look into the specifics of each browser and then use prototype to add a set opacity function to you element that handles all the different browser quirks.
also JSLint will help a lot with writing good JS.
as for the functioning of your code, you're calling fade a lot of times using that set timeout, and then you cal getElementById a lot, you could store the current element in a variable or store all 3 of them in an array and cycle through that so document.getElementById("bg" + (i % 3)).style.opacity = h; would become bgElementsArray[i % 3].style.opacity = h; that would be a lot faster I think. (don't forget to initialize the array for all 3 elements!) that way you could easily add more elements to fade as well, just change the i % 3 to i % bgElementsArray.length and you can add to the array at will!
wrapping it in the function is to use the scope of that function, keeping private variables and functions private, check out monads and closures for javascript.
doing something on the window object means that it will be globally available.
when you just declare a function in JS you should be able to find it in the window object.
when you call document.getElementById() you're actually calling window.document.getElementById();
when you call alert(""); you're actually calling window.alert("");
a good JS checker which explains why it whines about things like this as well is JSLint
Implied global variables are evil. It's bad for one to use them and it's equally bad for IE to offer global DOM elements. The author even says it's not best practice to do what he's showing.
This is not "perfectly valid code" in practice because there are, indeed, some globals you cannot overwrite. You cannot overwrite document or window (even though you can have an element with ID document), and if you're running Firebug, you cannot overwrite console. Different browsers and environments offer different globals, which is a great reason to properly scope one's variables and explicitly declare them.
Speaking of Firebug, if you leave a stray global call to console.log in your production code, your script will silently fail for Firefox users and there won't be a visual indication unless you open Firefox's Error Console.
Implied globals are evil and is another reason to run code through JSLint.
Just because nobody else seemed to notice: you haven't declared i
anywhere, so it'll end up in the global namespace. You don't want that.
Instead, declare all your local variables at the beginning of each function (forget about declarations in loops and such -- JavaScript only knows function scope). Use a tool like jslint if you're unsure about your code quality.
Double space or die! Just kidding. All that matters is that you agree with the people you're working with up front. Most editors make it really easy to toggle back and forth.
E.g. in sublime, you can click "Spaces" in the bottom right and Convert between tabs and spaces. Also, setting up your projects with a Linter like JSLint can help you enforce standards like this more easily.
Don't run your Javascript through JSLint; in JSLint, those are required, and if you use the "var a = function"-style declarations, you also need a space between "function" and "(".
Here's an example if you're not a Javascript guy:
var a = function () { "use strict"; return 1; };
function b() { "use strict"; return 1; }
I will be the one to introduce you to every programmers favorite tool, a linter.
For JS, http://www.jslint.com/ is the way to go. Depending on what you're writing your code in, they're are plug-ins that can incorporate this logic inside your text-editor or ide.
Whenever I have a syntax error, I find the linter for that language and use it.
It's fine the way it is, but a slight improvement (per the suggestions of JSLint (a tool to check syntactic quality of your code)) would be this:
var x; for (x = 1; x <= 100; x = x + 1) { if (x % 3 === 0) { if (x % 5 === 0) { console.log("fizzbuzz"); } else { console.log("fizz"); } } else if (x % 5 === 0) { console.log("buzz"); } else { console.log(x); } }
The linter is JSLint so you may want to read up on it's instructions. That will explain how to configure it to annoy you less about things that aren't an issue (like jQuery not being defined, or console statements.)
=>
is not a javascript binary operator.
I suggest using a tool such as jslint (http://www.jslint.com/) to verify the syntax of your javascript code. (You might want to "tolerate" everything in jslint if you only care about syntactic correctness though.)
Alternatively, don't use Yoda Conditions because they're both weird to read and pointless if you're comparing variables to variables; and use a linter to catch these rookie mistakes.
I recommend you make it a habit to run your javascript code through JSLint [Link] it will help you find bugs like that in your code. It will also help you become a better JS developer.
The semicolons insertion is indeed a source of problems, especially when you start minifying you JavaScript files, but I don't think you need a bug-tracking system to solve this. Personally, I use JSLint to find missing semicolons and all other trivial, syntax-related "bugs".
short answer for the var i, elems on line 2 to make JSLint happy.
the long answer, you should always declare variables at the top of the scope they are used in, and since JS is function scoped you put them all on the top of the function.
anyway, what I'd do is use either a class on the surrounding element or a class for all the spans and then use document.getElementsByClassName (and then iterate over them in the same way as was done in the example with byTagName)
you can use the getElements functions on things other then document as well for instance:
but to truly make JS lint happy I already see 3 other problems, no "use strict"; the document is never declared as a var (you should technically have it on top of the script to declare it a public variable) and JSLint want to see i += 1 not i++ (i++ is for pointer increments which is something JS doesn't have)
just to show some more options (like selecting on something more specific then the document and the .parentNode attribute, u can navigate quite a long way using nextSibling previousSibling and parentNode
<div id="a"> <span>te</span>st<span>!</span> <button onclick="changeColor(document.getElementById("a"), '#F00');">change</button> <button onclick="changeColor(document.getElementById("a"), '#000');">back</button> </div> <div id="b"> <span>te</span>st<span>!</span> <button onclick="changeColor(this.parentNode, '#F00');">change</button> <button onclick="changeColor(this.parentNode, '#000');">back</button> </div>
js: var changeColor(parent, color) { var i, elems = parent.getElementsByTagName("span"); for (i = 0; i < elems.length; i += 1) { elems[i].style.color = color; } }
It's not only stylistic.
If you use multiple var statements throughout your code, when the code is interpreted, the interpreter will gather up all the declared variables, move them to the top of the block, and define them with a single var statement.
Also, the "anonymous function declaration" is not either. When you write code like this:
function foo () { // stuff here that does other stuff }
"foo" is going to be declared. It will be Global to the scope that you wrote it in. That is pretty black and white.
What are some IE-specific workarounds for problems with IE interpreting JavaScript?
JSLint, properly and constantly used, should whip anybody's JS code into a state that works fine with IE.