text:
When writing a bingo game I discovered there is a lot about JavaScript (and HTML, CSS and marketing web sites) that is not covered in most tutorials. I am not an expert so I hope you will be inspired to find out more about the following topics on the web.
Chrome says there is not enough contrast in my headings of red text on an white background
I use the '' feature of the ' '
I add a '
viewport' '
meta' tag to make my web pages adapt to mobiles:
<meta name="viewport" content="width=device-width, initial-scale=1">
I make my images respond to different screen sizes by adding:
img {
max-width: 100%;
height: auto;
I also remove the '
width' and '
height' for each image
to centre a '
fixed' positioned element, say '
left: 50%' and give '
margin-left' a value of minus half the element width
You do a similar thing vertically with '
top' and '
it seems you cannot use font sizes less than the default to be mobile friendly, according to the '' checks in Chrome
you cannot use '
clip-path' in CSS, with a gradient for the background
It seems you can with SVG
I seem to get duplicate points in the CSS generated by the 'clippy'' tool
give your '
clip-path' a descriptive name
You cannot tell what they are otherwise
there is a snowflake symbol in Unicode
This symbol is useful for snowfall animations.
The symbol has been in Unicode for a long time
my free web hosting provide, '000webhost.com', puts a banner in the bottom right corner of the screen
This banner obscures part my animations.
The computers in my library put a clock in the bottom-right of the screen too
you can use percent sizes in a '
translate' transform
For example: '
in a '
translate' transform, a percentage size relates to the size of the element not its parent
I could not upload files to '000webhost.com' for a week
There was a problem with the 'ftp'.
Windows7 has an 'ftp' program. I type 'ftp' at the ' ' menu
I had a bug, but Chrome carried on, creating duplicate '
input' fields
I found the bug by looking at the console in the ''
there is a competition for javascript programs under 1k in size
enter '
chrome://gpu' to get details of the GPU
the older, lower numbered, smiley emojis in Unicode are drawn as lines, and are not painted on Apple devices
the Unicode emojis for a person raising their hands, show a woman on Apple devices
I had almost given up on people downloading the sound files
Instead I directed people to the online game which has all the sound. Then people started downloading the sound
I set variables to '
null' that are big objects to free up the memory
Examples are the variables that persist in the module pattern
my web page of 'credits' or 'acknowledgments' is a good way of remembering where bits of code came from
if you take a piece of code from elsewhere then make a note of where it came from, so you can add it to your credits
it seems you cannot use CSS animations on '
span' elements
I felt queasy doing an animation of the rays of the sun
I remembered you can have fits looking at strobe lighting.
I made the rays bigger with light colors like the background. I turn the rays very slowly
my first real link comes from a University in Namibia and the link is to my list of first names
I had almost given up on the list. The list does not have much to do with my game
I create an SVG with GIMP, so I can animate the drawing of the letters with '
I use the 'GIMP' option in the ' ' menu. In the ' ' tab on the ' ' dialog, I right click and choose ' '. I have an old copy of
It was not hard to use the '
matrix3d' transform
I adapted examples on the Web.
I want to do a '
skew' on the 'x' axis as a 3D transform to run on the GPU
you can use a '
flex' layout to centre an item vertically and horizontally
it is easier to set the shorthand '
animation' CSS property in JavaScript rather than setting '
animation-duration' etc
You could set constant animation properties in a stylesheet and dynamic properties in JavaScript, but I found this too complicated
if I make a prototype then I make a list of things to tidy up when finished
with Internet Explorer, if you select a link with an access key and the link has '
text-description' set to '
none', then sometimes no outline appears on the link
the outline reminds you to press 'enter' to activate the link
in Chrome, I get an exception (in the 'promise') when I play a sound before the user has clicked anything
This code traps the exception:
var playPromise = audioElement.play();
if (playPromise !== undefined) {
But my old Konqueror browser will not compile this code.
I will fix the problem by only playing the sound on a click
I could not restart a CSS animation on Firefox. The HTML was fixed
One solution is to have 2 identical '
keyframes' with different names and alternate between the '
Another solution is to 'clone' the HTML and remove the original HTML.
Setting the element's '
offsetWidth' to itself did not work
I had a lot of fun adding CSS animations (and transitions). It is easy to make them dynamic:
var stylesheet = document.createElement('style');
stylesheet.innerHTML = 'keyframe ...';
var headElement = document.getElementsByTagName('head')[0];
finding a bug in an old piece of code can take just as much skill as writing new code
I try to be 'humble' when writing code
I am a pretty average programmer, nothing special
some of my early animations seem quite crude now. But they were a step towards the more complex ones I do now
I have learnt a lot by looking at the code when doing 'mash-ups' of other people's animations
I run the W3C link checker several times, as new problems with links are reported as I fix the problems
if you do not put '
var' before a variable when you first set it, it will be global
you can declare variables anywhere in a function, unlike the original 'C' language
if you declare a variable inside a
for/while loop or '
if' block, it is visible in the enclosing function. This is different from the 'C' language where the variable is private to the block
For example, I declare variables inside a '
for' loop like this:
for (var i = 0; i < len; i++) { }
But this is a bit misleading as the variable is available outside the loop. It might be simpler to just declare the variable at the top of the function.
It may be slightly quicker for the JavaScript interpreter if you put all your variable definitions at the top of each function
a JavaScript variable has to defined before you can use its value, but an object property that is not previously defined has an '
undefined' value
I seem to end up with lots of global variables.
I wish I had grouped them together into several objects
simple objects are just pairs of keys and values stored in a hash. For example:
var myObject = { name1 : value1,
name2 : value2,
func1 : function () { alert('hi'); } };
The values can be function definitions
a class in JavaScript is just a normal function definition where you set up properties with '
this' variables. You create an instance of a class with the '
new' operator. For example:
function Play(aim)
this.aim = aim;
var play = new Play(playAim);
The instance is an object with a list of key/value pairs just like simpler objects.
Again, '
this' variables can be function definitions. However, you can share the functions between instances of a class by adding them to the class's prototype:
Play.prototype.setPhrase = function (phrase)
this.phrase = phrase;
play.setPhrase('hello world');
Here 'prototype' means a sort of template for the class. At run-time if the instance does not have a variable defined, the JavaScript interpreter will look in the instance's class's prototype.
The '
this' context variable given to an instance of a class is again just a simple object with a list of key/value pairs.
You can add plain class variables to a class's prototype too
you have to clone an object by hand.
However, there is a '
cloneNode()' function for copying HTML fragments via the Document Object Model (DOM)
objects are references:
you always deal with references to objects (i.e. 'pointers') rather than the objects themselves. For example, objects are passed by reference into functions as parameters.
Arrays are objects in this respect. It is thought to be quicker to to create an array like
"var a = ['a', 1]" rather than using
"var a = new Array('a', 1)". I think the two are equivalent now - maybe they were not in the early days of JavaScript.
(Note that saying
"var a = new Array(1)" just creates an array with one empty element)
you can extend built-in objects like
you can add new member functions and variables to built-in objects (classes) such as Array. For example:
Array.prototype.myFunction = function () { };
But, when you go through the elements of an associative array with '
for (element in array) { }' , your new member functions and variables will be included. (By an 'associative' array, I mean an array with indexes that are not numeric.)
You can exclude these by testing the type of the element with '
typeof' or '
instanceof', or by using the '
hasOwnProperty()' method. I add the prefix 'my' to the name of these member functions
consider adding a
toString() function to your classes (objects):
you can add a
'toString()' member function to your classes to show the values of their instances nicely. For example:
myClass.prototype.toString =
function() { return '(' + this.a + ', ' + this.i + ')'; }
If the instances are in an array, JavaScript will show each instance nicely in a list.
This is useful when debugging, in alert messages and writing trace output
creating new instances of class objects may take time, so sometimes I just use an array with maybe several different datatypes. For example:
phrases[3] = [ 1, "hello world" ];
functions are variables:
functions can assigned to variables, for example:
function f() { alert('hi'); }
var r = f;
You can also say:
var r = function () { }
If you have put a reference to a function in a variable, you can call the function by simply adding brackets (e.g. '
()') after the variable name, for example:
But, if you put a reference to an object method in a variable, then when you call the method by adding brackets after the variable, the method will not have the 'this' variable available.
Of cource, you can also use '
call()' and '
apply()' to call functions.
Saying '
var f = new Function()' is thought to be slower than saying '
var f = function () { };'
you can have functions inside functions:
But, in an object method, inner functions do not have the '
this' variable available to them. '
this' refers to the object. To get around this, I set a variable '
that' to be '
this' in the outer function, i.e. '
var that = this', and use '
that' in the inner function instead.
JavaScript uses prototypes for inheritance.
It is really about getting JavaScript to look for variables in other classes. There are other languages that use prototypes. There are some good explanations on the web.
I have not used inheritance much with JavaScript. Prototypes are not easy to understand. Also the extra lookups for variables it involves is the sort of thing that might slow JavaScript down.
I did use prototypes where I had different sets of program options based on a normal set of options:
var normal = {};
var n = normal;
function Quiet() {}
Quiet.prototype = normal;
var quiet = new Quiet();
var q = quiet;
n.joins = 50;
n.leaves = 30;
q.leaves = 15;
Here, at runtime, if the interpreter cannot find a '
quiet' option in the set of '
quiet' settings, it looks for a value in the '
normal' settings. So, the value of '
q.joins' is
50. I have read that the 'new' operator as used here was only added to JavaScript to please people used to normal inheritance.
Before I came across prototypes, I used the '
JavaScript has closures. A closure is a function within another function that can hold onto variables it can see after the outer function has finished. It is best to read about this on the web
a function inside another function, used as a closure, keeps the values of variables in the outer function at the time that the outer function exits
I hoped the closure would keep the values each time I stored a reference to the closure.
For example:
function of()
var x = 1;
function inf() { alert(x); }
var ret = inf;
x = 2;
return ret;
var r = of();
results in an alert box showing '2'
to get a variable that keeps its value across different calls to a function, you can use a closure rather than a global variable
For example:
var f = function()
var v;
function c()
return c;
there is a good explanation of closures on Stack Overflow
you do not need to do much locking.
JavaScript will ignore your mouse clicks, and code starting after a timeout, until your current functions finish. I do sometimes use locks to hold onto control during pauses and animations.
Conveniently, the sequence of testing a value and setting a value is therefore always atomic.
I read that the designer of JavaScript did not like the complications of multi-threaded programming.
Read more about this on the web
when you make JavaScript show an alert box, your JavaScript program completely stops. All threads of execution freeze
locking is a bit complicated if the computer can switch between processes at any instruction
My locking only really works because JavaScript is single threaded
JavaScript runs your code until it is complete. This works well with asynchronous API's
if you do not supply all the arguments to a function, they are just set to '
So you can test if optional arguments are given by seeing if they are not '
undefined' rather than checking '
you can give varying arguments to a function with the built-in functions '
apply()' and '
call()'. For example:
myFunction.apply(this, arrayOfArguments);
myFunction.call(this, parameter1, parameter2);
The first argument is the 'context': an object in which you would like to look up variables in
if you have many optional parameters to a function, you can make them properties of an object and pass the object through to the function instead. For example:
params = { player : 1, number : 45 };
However, I find it sometimes simpler to pass a long list of parameters, with a '
null' value for any optional parameters that are not used.
JavaScript does not have named parameters like:
'myFunction( number => 45, player => 1 );'
if you want to pass the arguments of the current function to another function you can say:
otherFunction.apply(this, arguments);
where '
arguments' is the built in array of function arguments;
it is probably neater and quicker to use a reference to a function as the first parameter of
Otherwise you have to pass a JavaScript statement as a string and therefore convert all parameters to strings. This makes it difficult to pass objects (which are references) as parameters to a function. Also the JavaScript interpreter has less idea what is in the statement string as opposed to a function reference.
Internet Explorer does not let you pass pass parameters at the end of setTimeout but you can if you use a closure to do this. For example:
function btmp(param)
var localVar;
function callNext()
// a closure - holds onto local variables after
// outer function has finished
nextFunc(param, localVar);
setTimeout(callNext, 5000);
you can pass parameters to functions that do not take parameters. For example:
func() { }
func(1, 'a', 7);
You can get at the parameters with the '
arguments' object. You can also pass more paramters to a function than it needs
Originally JavaScript interpreters seem to have done little optimisation. Of course, they do not have much time to do this and obviously the code has not been compiled and therefore optimised beforehand. I tried out some tips I found in books and on the Internet with varying results:
using local variables to store the values of global variables when you use them repeatedly.
This seems good style but I did not notice any difference in performance. And how far do you go? Should I put constant values defined globally at the top of the program back down in the code itself?
A related tip is to put the results of some DOM functions into local variables as referring to them repeatedly apparently re-executes them in case the DOM has changed
using '
while(i--) {}' when possible, combining the decrement and test.
I found that if this form was not obvious to use then it took too much time to think about and interrupted my flow of writing code
moving constants outside loops and repeated functions.
For example, try not to code something obviously bad like:
var a = [1,2,3];
for (var i = 0; i < a.length; i++) { }
as the length is evaluated each time through the loop
checking just once for features that vary between browsers.
For example, finding where you click the mouse by using either '
event.target' or '
not having too many sub-functions if they are small, to avoid the overhead of the function call, like compilers 'inline' code.
similarly, avoiding function calls within a loop that repeats many times
removing spaces and comments, and shortening names.
I use '
tr -s' to reduce multiple spaces to one space (mainly indentation), and a little
perl to remove comments. Just doing this reduces the size of the page by about half and the page loads much quicker. I leave in newlines as this makes it easier to find bugs.
Some programmers use short variable and function names. I use
sed and simple
perl to shorten mine. I make use of my own coding style, for example I always indent global definitions by eight spaces. The program did not seem much quicker, but the size of the page is about 25% smaller.
I wrote my own scripts rather than using one of the 'minimizing' utilities generally available because I did not completely trust them. Also writing the scripts gave me something to do whilst I was testing my game. I also use my scripts to completely remove some debugging code.
My own suggestions would be to think carefully about what algorithms you use and try hard not to repeatedly execute any code unnecessarily.
Simple examples of these are that I use a binary search to look up values in a long list, and only make changes related to some settings values once the user has finally left the settings screen so the user can change the values within the settings screen many times and still get a quick response.
The following ways of coding may also slightly speed up the parsing of you code:
it may be a little quicker to say '
window.alert()' rathen than just '
it is easy to forget to put semicolons after statements as newlines will often do the job.
However the JavaScript interpreter may parse the code quicker if you put semicolons in
if you code something like:
msg = x +
rather than:
msg = x
+ y;
then it may help the JavaScript interpreter to parse your code faster as newlines can end statements
variables and functions do not have to be defined in the code above where they are used. But JavaScript may parse your code quicker if they are defined above.
Of course, variables have to be defined before they are used as the program runs
instead of using the '
replace' function with a regular expression, I can sometimes just concatenate the parts of the string with the replacements
trying to write faster if larger code works well for me
my 'mimimising' scripts replace some variables that are constants with their values
I mark variable that are constants with a comment after the definition of the variable.
I use 'Perl' to generate 'sed' scripts which are a bit slow
my 'mimimising' scripts put stylesheets all on one line and remove most spaces in the CSS
Some CSS needs spaces, for example: '
border: 1px solid red'
it seems much harder to replace 'constant expressions' with their values rather than replacing just constants
you can 'minimise' many statements like: '
obj.prototype.f = {}' by saying '
s = obj.prototype' and '
s.f = {}'
you can 'minimise' the '
arguments' array by saying '
var a = arguments' and using '
a[1]' etc
This is a bit slower as a variable is declared.
I also say '
var _ = this'
you can 'minimise' the use of '
undefined' by declaring '
var u' and using '
u' instead of '
a good way to 'minimise' your code is to have lots of common functions
Unfortunately, I tend to copy and paste code
you can shorten '
a = 1; b = 1' to 'a = b = 1'
you can shorten '
typeof e === "undefined"' to '
e === undefined' if the variable '
e' exists
I read that WebKit has a 'Just in Time' compiler that optimises the JavaScript code
I have common functions with short names for '
setTimeout' and '
I changed '
if (v === true)' to '
if(v)', and '
if (v === false)' to '
if (!v)' if possible
the variable names '
$' and '
$$' are used by common libraries but '
$a' to '
$z' are not
You can shorten variable names to names like '
my common '
getElementById' caches a reference to the document:
var $_ = function()
var d = document;
function gebi(element)
return d.getElementById(element);
return gebi;
you can reduce the size of the code by replacing '
true' and '
false' with '
1' and '
the online Google Closure Compiler with the 'advanced' option gives lots of warnings when I add functions to the prototype of
String etc
I also get warnings when I use properties that are not listed in the constructor of their object.
I also get warnings if I do not have a JSDoc '
@constructor' comment above my constructors
with the online Google Closure Compiler with the 'advanced' option, you need to quote properties that you do not want renamed
For example:
o['p'] or
{ 'p' : 3 }. The latter allow you to use reserved words
Another example is where I had '
the online Google Closure Compiler with the 'advanced' option says it cannot optimise regular expressions where I use the global '
RegExp' object
I use '
RegExp' to get parts of a match in the '
$1', '
$2' properties
So I use the '
match' function instead and the parts from the elements of the returned array
the Google Closure Compiler has an option to 'pretty print' its output which makes debugging easier
I use the online Google Closure Compiler at: 'closure-compiler.appspot.com', but you can run the Java program
the Google Closure Compiler replaces '
undefined' with '
void 0'
void' evaluates an expression and returns '
undefined'. You used to be able to give '
undefined' a different value as it was a global variable.
The Closure Compiler also:
replaces '
true' with '
!0' and '
false' with '
replaces '
if' statements with '
&&' and '
||' and '
? :'. For example, '
if (t) { f(); g(); }' becomes '
t && (f(), g())'
uses the comma operator to combine statements often in the conditions of a '
for(;;)' loop, or ending with a condition
combines assignments to be like '
a = b = c = !1'
changes '
if (v > 3)' to '
if (3 < v)'
replaces '
while (true)' with '
changes '
var a = 3; var b;' with '
var a = 3, b;'
replaces an early '
return' from a function with a conditional expressed with the '
? :' operator or an '
if' statement
may inline functions that are inside another function. The 'advanced' option also inlines separate functions
changes '
if (a == 0 || a == 2) { f(); }' to 'a != 0 && a != 2 || f();'
changes '
if (a) { f(); } if (b) { f(); }' to '
if (a || b) { f(); }'
changes '
10000' to '
['Jean','Joan', ... 'Vera'] to
'Jean Joan Vera'.split(' ')
shortens the names of local variables. The 'advanced' option also shortens the names of global variables and properties of objects
Unfortunately, the Closure Compiler with the 'advanced' option sometimes removes local copies of references to global objects, so I use the 'simple' option
the online Google Closure Compiler with the simple option reduces the size of my game by 25 %, and with the advanced option by 35%
I run the Closure Compiler on the results of my own shortenings
my game sometimes hangs when minimised with the Google Closure Compiler
The game hangs when I press a button to show a new screen.
So I do not use the Closure Compiler
the online Google Closure Compiler with the 'advanced' option set gives an error for '
the Google Closure Compiler does not shorten HTML '
id' and CSS '
class' names
I modified 'JSMin' to leave in newlines and not add a blank line at the start
My browser just gives the line number when there is an error
the Perl version of the 'packer' minifier does not shorten local variables as the online version does
the author of the 'packer' minifier says the option to shorten variables may be a bit buggy
I use keys to copy and paste when I give a large script to the 'packer' minifier
the online Google Closure Compiler gives an error when I try to compile the JavaScript from my game which is about 0.7 megabtyes
people seem to recommend using the 'simple optimizations' of the Google Closure Compiler which shortens local variable names and shortens function parameters
the 'packer' minifier, with the 'shorten local variables' option, reduces the size of my (already minimised) game by 17%
it may be quicker to say '
a[a.length] = v' rather than '
a.push(v)' where '
a' is an array
Also it may be quicker to write the code yourself rather than use '
Math.min' and '
the 'UglifyJS' minifier reduces the size of my game by 22% over and above my own minifying
the 'packer' minifier, with the 'shorten local variables' option, reduces the same code by 17%
the 'UglifyJS' minifier seems to make my game run faster
'UglifyJS' rewrites the code, making much use of the 'comma' operator to combine statements
'UglifyJS' reduces the size of the JavaScript in my game by 27% over and above my own minifying
the 'UglifyJS' minifier seems to maybe change a '\u00A0' code into the actual control code
the 'UglifyJS' minifier does not shorten the names of global variables
You are not meant to use globals.
So I put the whole script in a self-executing anonymous function.
I had a problem where I passed a string, containing a call to a function, to '
setTimeout'. The JavaScript interpreter looked for a global function. I now pass a reference to a closure (an inner function) to '
the UglifyJS' minifier turns '
true' to '
!0', '
false' to '
!1' and '
undefined' to '
void 0'
I found 'JSHint', the static code analyser, to be very useful. It is more flexible than 'JSLint' on which it is based. As an example, 'JSLint' stops when it comes to places where I declare variables inside 'for' loops, for example: '
for (var i = 0; i < 3; i++)'. JSHint pointed out that:
I had forgotten to end many statements with a semicolon.
In particular I had used the form '
obj.prototype.func = (){}' but missed off the semicolon at the end
I had sometimes forgotten to declare variables as local variables with a '
var', leaving them to be global variables which might be slower to look up
I had defined variables more than once in functions with multiple '
var' statements
I had declared some classes (objects) and variables below where they were used in the source file.
Sometimes I had something like:
function func() {
function subFunc() { i = 3; }
var i;
where it might be slightly better to declare the variable i at the start of the outer function
I still occasionally used '
==' and '
!=' rather than '
===' and '
The former may convert its arguments to a different type leading to subtle errors
I had sometimes coded something like:
var msg = 'hello' +
+ 'world
it expects you to restrict the results of '
for in' statements by using the '
hasOwnProperty()' method.
I was just worried about my extensions to the built-in '
Array' type being returned with the values of associative arrays and so just checked to see if the values had the '
function' type
it did not like me sometimes letting code 'fall through' '
case' statement in '
switch' blocks
it warned me when I put the '
default' statement of a '
switch' block in the middle of other '
case' statements
it would say I was using a variable 'out of scope' when I declared it in an '
if' block and later used it in a similar '
if' block
You can increase the number of errors that the 'jshint.org' website shows if you include a comment like the following at the top of your script:
/*jshint maxerr: 500 */
I think it is best to use 'JSHint' as you are writing your code so you can adjust your coding style. If you wait until you finished, like I did, you will get a huge number of warnings!
JSHint gives an warning if you use a variable in a sub-function when the variable is declared afterwards
I set JSHint options at the top of my JavaScript with:
/*jshint maxerr:1000, funcscope:true, laxcomma:true, forin:false, noempty:false, elision:true, nonstandard:true, laxbreak:true, strict:false , browser:true, devel:true */'
JSHint does not point out properties of objects where the properties are not used
JSHint does not tell you about unused globals or functions
JSHint is good if you want to turn a rough prototype into a finished piece of code
the memory a JavaScript variable uses does not always seem to be freed immediately when the variable is not longer used
this may be because JavaScript uses garbage collection
then my Linux system 'thrashes', spending almost all its time swapping processes from memory to disk and back
when it runs out of memory, Internet Explorer seems to just 'hang' and Windows® says "the application is not responding"
this happens when there are too many JavaScript variables or too many HTML elements on the page
my browser seems to create all the parts of a page even though you need to scroll down to see them
my browser appears to run out of memory because of all the off-screen parts
I like to be precise and use '
===' and '
!==' to test equality as then the types have to be the same. I had a nasty bug with values being implicitly converted to true or false
you can remove an element from an array with splice. For example:
array.splice(index, 1); // remove item at index
usually the built-in array functions on arrays return a new array
you can clear out an array by saying:
array.length = 0
associative arrays are like objects and vice versa:
arrays with indexes that are not numbers are like objects and do not support all the Array object's functionality. For example, associative arrays do not have a '
length' and you cannot get the nth element by saying '
assocArray[n]'. You can go through the elements of an associative array with the '
for in' statement:
for (var key in assocArray) {
value = assocArray[key];
You can get the value in an object using array notation. For example:
var n = 'name';
var value = object[n];
is the same as:
var value = object.name
And so:
assocArray['key'] can be written as
Maybe this is all because the JavaScript interpreter stores arrays and objects as hashes
you can use JavaScript's internal '
Object' class directly rather than using associative arrays at all.
For example:
var o = new Object();
var o2 = {};
o[123] = 3;
o2[456] = 4;
I have read that numeric arrays are stored by key like a hash rather than as a series of values and can naturally be sparse
you can have arrays of arrays like multi-dimensional arrays.
For example:
var a = [];
var aa = a['k'] = [];
alert(a['k'][0]); // shows '3'
you can pass multiple parameters to the array '
push', '
unshift' and '
concat' functions
some people like to put all of their script into an object.
One reason is that it avoids name classes with libraries.
For example:
var myscript = {
get : function () { },
put : function () { },
ary : [ 1, 2, 3]
I find it easier to create classes (objects) and add member functions to their
prototoypes and then create an instance of a class at the start (with
'new'). For example:
function Game() { this.v = 3; }
Game.prototype.set = function() { }
var game = new Game();
something like this can be a bit puzzling at first:
( function() { alert('hi'); } )();
it just defines an anonymous function and runs it.
you can have class variables and functions (sort of), like:
function myClass () {}
myClass.v = 3;
myClass.f = function () { alert('hi'); }
I find it easier to use the traditional
on'event' handlers like '
onclick' as in:
HTMLElement.onclick = clickfunction;
They work on the most browsers. Events 'bubble up' when you use the traditional event handlers.
Some browsers prefer to 'capture' events from the outside in. Read more about this on the web
if you quickly move the mouse, JavaScript may only fire events on the page element the mouse settles on and may miss events on elements the mouse passes over
you can capture right clicks.
You can read about this on the web.
I use an element's '
onmousedown' handler where I check if the '
event.button' attribute has a value of
I stop the normal right-click context menu appearing by calling '
event.preventDefault()' on my Konqueror browser. However, on Internet Explorer I have to set up a 'oncontextmenu' handler to return false.
I do not know what happens if your mouse has just one button
I avoid getting 'computed' values of style values of HTML elements, as this can be a bit slow, differs between browsers and may not work at all in particular browsers
I use '
try catch' exception handling blocks to continue when JavaScript finds an error as a script runs.
An example is when you try to read '
event.target' when there is no current event and the '
event' object has the value '
You cannot catch errors which the JavaScript interpreter finds when it first loads a script, such as simple syntax errors.
The scope of a '
catch try' block ends when you pause with the '
setTimeout()' function.
I had a bug which I could not replicate so I put the likely bits of code in '
try catch' blocks
the '
onchange' action on a HTML text input element may not always fire.
For example, on my browser if you move the mouse away and hide the input element before clicking elsewhere the '
onchange' action may not fire
My crude solution is to add a '
onmouseout' action which calls the '
onchange' code and have this code check to see if the input element's value has changed by storing the old value
JavaScript libraries such as 'prototype.js' take a few seconds to load on my old PC.
I learnt a lot by coding things myself. Writing animations yourself is fun as you can see the results right away
the page displays quicker if you put your script at the end of the HTML '
However, I put the '
noscript' message in the document header so it appears first in a text browser
it really is a good idea to look at your page in a text browser like 'lynx'
I understand that all numbers are stored as floating point numbers in JavaScript and that there is no integer type
I have read that the bit manipulation operators in JavaScript can be slow.
This may be because the floating point numbers have to be converted to integers and then converted back
dividing a number by zero gives the value '
Number.POSITIVE_INFINITY' and does not cause an error
if you pass a string to the functions '
parseInt()' or '
parseFloat()' that does not represent a number, the functions return a number value that converts to a string as '
NaN'. This does not raise an error.
You do not seem to be able to compare the return value to '
Number.NaN', maybe because one
NaN may not be the same as another. You can use the built-in function '
isNaN()' to do this
One way to test if a variable is '
NaN' is to test if '
x != x'
the function '
parseInt()' really takes a second parameter - the 'radix' or number base, e.g. 10 or 16
The '
toString()' function on a number also takes a number base as a parameter
you can round a number with the '
num.toFixed(precision)' function
the expression '
a || b || c' evaluates to the first of '
a' then '
b' and then '
c', which is not an empty string (
false or '
you do not need to put brackets around the arguments to the '
typeof' and '
instanceof' operators.
It is really '
typeof v' not '
the '
const' keyword does not work in all browsers.
I think saying '
for (var i = 0, j = 0; i < 3; i++) {}' creates a variable '
I believe JavaScript does not see the comma between the '
i' and '
j' as the comma operator but as part of a long '
var' definition. I understand the comman operator is almost bottom in the order of precedence of operators.
I get confused because in the 'C' language if you say '
for (i = 0, j = 0; i < 3; i++) {}', then '
i = 0' and '
j = 0' are like two statements
you use the '
getDate()' function to get the day of the month from a JavaScript date
if you miss out an element in a list of array elements, e.g. '
a = [1,,3]', then you get an element with a value of '
I read somewhere that it may be quicker for the JavaScript interpreter to parse C style '
/* */' comments rather than C++ '
//' ones!
However, you can just strip out all the comments when you 'minimise' your code using utilities that remove spaces, shorten variable names and more
it really is a bad idea to use the same name for a global variable as for a local variable inside a function.
It makes it more difficult to write a simple 'minimizing' script.
I also had trouble when using the same variable name in an inner-function as the enclosing function
you can shorten built-in function names like this:
Array.prototype.p = Array.prototype.push
I do not change the source code but make the changes in my 'minimising' scripts.
on Internet Explorer (version 8.0), if you add a function to the prototype of '
Object' then you can not use the function on the '
document' object, but you can on the '
Math' object
On my browser it works on both.
I have read that Internet Explorer (IE) does not allow you to extend HTML elements through their '
prototype'. I understand that IE generally handles HTML elements a little differently to objects of the JavaScript language
Math.f = Math.floor
acts the same as:
Math.prototype.f = Math.prototype.floor
Both see the '
this' instance variables
if you forget to end statements with semicolons and rely on newlines then you will get syntax errors if your 'minimising' utility combines lines
I have read that it is best not to use the '
caller' property of functions
Using it makes it difficult for JavaScript to optimise your code by 'inlining' the functions.
I put the name of the function in a variable at the top of most functions and use this for debugging. I pass this through as a parameter when calling some functions. I remove most of these variable in my 'minimising' scripts
You can find out other ways to help the optimiser by reading about the new '
strict mode' for JavaScript
some programmers say that it is better to use:
typeof objectProperty === 'undefined'
rather than:
objectProperty === undefined
undefined', or give a value to JavaScript's '
undefined' variable
you can use the first version with simple JavaScript variables that are not set
Also notice that:
null == undefined
true, as JavaScript treats a
null value quite like an
undefined one
if you declare a variable in the middle of a function, JavaScript actually declares the variable at the start of the function
For example:
alert(v === undefined);
if (false) {
var v = 3;
alerts '
true' and then '
reference error'.
Some call this 'hoisting'
you can pass scalar parameters by reference to a function by putting them inside an object. For example:
var obj = {};
function func(param) { param.v = 3; }
obj.v = 5;
alert(obj.v); // gives 5
alert(obj.v); // gives 3
you can add properties to numeric arrays. For example:
var a = [1,2,4];
a.count = a.length;
alert(a[2] + ', ' + a.count);
to append an array to another array you can say:
array = array.concat(anotherArray)
sometimes I mistakenly just write:
I try to use numeric codes rather than string values
Before I did this, I used tests like "
aim === 'house'"
it may be quicker to use 'protoypes' to do inheritance rather than copying the properties as some libraries do
sometimes my browser does not respond when I click on an HTML button and the browser is busy
At first, I thought it was a problem with my game, but there may be a problem with my browser or my windowing system
the '
push' method of arrays returns the length of the array
I had a problem when I thought '
push' returned the array
the '
typeof' of an array is '
I thought it might be '
an assignment is an expression
You can say:
i = j = 3;
to delete a cookie, I set the expiry date to the first second of 1st Jan 1970
Unix timestamps start at 1970.
Setting the expiry date to a a few days ago might not delete the cookie if the user has set the time wrong
you can delete all the elements of an array with '
arr.splice(0, arr.length)'
you can get the new length of the array from the return value of '
you can test if an array has a value with a given key with '
if (key in arr)'
you can convert something to a string with '
part of the Dojo code uses '
new Array()'. People seem to recommend using '
The Dojo code also uses the '
with' statement and puts '
var' declarations in '
for' loops (e.g. '
for (var i = 0; i < l; i++)'. People recommend against using these too
you can convert numbers to different bases by giving the base as a parameter of '
you can use the return values of '
splice()' to get a range of elements from an array
the function '
document.getElementById' returns '
null' if the '
id' does not refer to a HTMLelement
you can label loops and use '
break' and '
continue' with labels to jump out of nested loops
you do not get an error if you '
delete' a property of an object and the property does not exist
the Dojo code has some variable names that are just 2 letters. This does make the code smaller
My minimising scripts use about 6 characters when they shorten my long variable names. In the future, I will use more variable names that are single letters
Internet Explorer 6 and 7 give an error if I delete a property I added to a button
the '
cloneNode' function does not copy event listeners such as '
the '
cloneNode' function seems surprisingly fast
you can use '
getElementsByTagName' on any HTML element
getElementById' only works on the '
document' node
a quick way to get the position on the screen of a HTML element is to use the '
getBoundingClientRect' function. This works on Internet Explorer and the latest Firefox browsers
you can turn off a stylesheet with something like:
document.styleSheets[2].disabled = true
the Opera browser, after version 10, has a 'user agent' string that says '
The developers of Opera thought that '
Opera/10' might be confused with '
Opera 15 uses the 'Webkit' render. Previously Opera used its own 'Presto' renderer
if you shorten:
o.prototype.f = function() { }
var x
o.prototype.f = function() { }var x
you get an error without a semicolon before the '
I used '
char' as the name of a variable but '
char' used to be a reserved word
The Google Closure Compiler pointed this out. Browsers do not give an error. The reserved words used to include: '
int', '
long', '
float' and '
double'. ECMAScript Edition 5 has much fewer reserved words than ECMAScript Edition 3
there is a global '
this' variable, which refers to the '
window' object
For example:
function t() {}
Also 'global' functions like '
parseInt' seem to be properties of the '
window' object
the keys of an associative array seem to be converted to strings
if the '
mousedown' event changes the part of the page that is under the cursor, then a following '
click' event will fire on the new part of the page under the cursor
the browser-specific CSS attribute '
-khtml-border-radius' becomes '
KhtmlBorderRadius' when used in JavaScript
it seems hard to identify the Safari browser as both the words 'Safari' and 'AppleWebKit' appear in the '
userAgent' string of other 'WebKit' browsers like Chrome
when I dynamically change a CSS rule on my old browser, the browser takes a few seconds to redraw the page
changing a CSS rule with JavaScript was simpler than I thought
For example,
if (document.styleSheets[0].cssRules) {
} else if (document.styleSheets[0].rules) {
firstRule = crossrule[0];
firstRule.style.color = 'red';
changes the first rule of the first stylesheet
My game changes over 25 CSS rules
on the iPad and iPhone, it seems that when you touch the screen, the '
onmouseover' event is fired
I read that the CSS '
:hover' event also fires
if you set the '
innerHTML' value of a page element, then the values change of any elements inside the '
innerHTML', even if you just say "
innerHTML += 'x'"
Internet Explorer 8 gives an error if you set the '
type' of an '
input' element to '
number' to get a 'spinner'
The 'Modernizr' library does this
if you use '
alert' to show the value of a link, then the alert shows the value of the '
href' attribute
if you try to get a 'spinner' in Internet Explorer 10 by setting an input element's '
type' to '
number', then the type is set but no 'spinner' appears just the normal text box
the test for mobile phones on the 'detectmobilebrowser.com' website does not include tablets. The 'about' section of the website says how to test for tablets
the test for mobile phones on the 'detectmobilebrowser.com' website is essentially:
|avantgo|bada\/|blackberry| ... |phone)|xda|xiino/i
/1207|6310|6590| ... |your|zeto|zte\-/i
) window.location=b
This is an anonymous function with two tests on the '
userAgent'. If the tests succeed then the address in the browser is changed to a website
Apple touch screen devices have a '
window.Touch' object
you can use the results of CSS 'media queries' in JavaScript like this:
<style type="text/css">
@media touch-enabled, -webkit-touch-enabled, -moz-touch-enabled,
-o-touch-enabled), -ms-touch-enabled
#touchTest { top:9px; position: absolute }
<script type="text/javascript">
testdiv = document.createElement('div'),
testdiv.id = 'touchTest';
touchMediaRuleHasEffect = testdiv.offsetTop === 9;
my browser gives a parse error if you say:
try { } catch() { }
rather than:
try { } catch(e) { }
You do not need to declare '
e' as a local variable
the test for touch in the 'Modernizr' library seems to say that the Chrome browser on Windows 7 and Internet Explorer 9 support touch
what seems to be bugs with my browser may be bugs with the 'threads' library the browser uses
I have had other problems with 'threads'. I built my Linux system from the source files.
The bugs with my browser seem to be where global variables are shared by different 'threads' started by '
it seems you cannot replace the normal right-click menu on phones and tablets with your own
On touch-screen devices it seems a right-click is a 'long press' or a 'double tap' (pressing with two fingers at once)
on Internet Explorer 8, when you access CSS rules from Javascript, rules with many selectors appear as many individual rules, e.g. '
#a, #b { color : blue }'
with '
createTextNode' you do not need to turn '
<' into '<' and '>' into '>' as you do if you set '
I cannot rotate the orientation of the iPad
An article on the web says to set '
document.body.orient' to '
portrait' or '
landscape' but this does not seem to work
I read that it is best not to use '
window.open' as this may confuse users or be blocked by the browser
I have an animation that creates 3000 '
div' elements
clicking either side of the '
caption' of a table seems to be like clicking on the table
if '
window.Touch' was defined it used to mean you had an iPhone or iPad but now Chrome defines it
on my browser, it sometimes seems the page width and height include any scrollbars
it seems that if you set a CSS attribute to an invalid value then the old value is still there
Internet Explorer 8 gives an error which you can trap with a '
try catch' statement
I remove the '
clip' CSS attribute on Internet Explorer 8 by setting the attribute to '
On Internet Explorer 8, setting the '
clip' attribute to an empty string gives an error. Setting the attribute to '
auto' seems to set the clipping to the width and height of the element. This also happens on my Konqueror browser. But, I want to move parts of the element outside of it by giving the parts a '
relative' position.
Using '
removeAttribute' does not seem to have any effect. Setting the right and bottom '
clip' parameters to high values does not work, sometimes leaving a blank screen
I have a problem with Internet Explorer 8 where I create a span which holds other bits of HTML. I put a reference to the span in an array. I then append the span to the page. I clear the element which contains the span by setting '
innerHTML' to
''. Now the reference to the array does not point to anything
I do not put '
getElementById' in a function with a short name like 'prototype.js' does with '
I think calling a function is slower
I put a reference to '
document' in a local variable when there are lots of calls to '
I hide a mail address by having the letters as numbers in the parameters to the '
String.fromCharCode' function
to set the CSS attribute '
float' from JavasSript, you may need to set the '
cssFloat' attribute or '
styleFloat' attribute (on Internet Explorer)
float' may be a reserved word in JavaScript
The rule applies to about 100 HTML elements. My browser crashes after the rule has been changed a few times
you check for '
MozTransform' not '
-moz-transform' 'in' the '
style' object of an HTML element
Also it is '
On Chrome, '
-webkit-transform' works
the way to test if the browser supports a value of a CSS attribute is to first see if the '
style' object of an HTML element has the attribute and then see if when you set the value then the value is there afterwards
on my browser, you can test if '
KhtmlBorderRadius' or '
-khtml-border-radius' are '
in' the '
style' object of an HTML element, but the '
style' object only has the more specific properties like '
the debugger with Internet Explorer 8 takes a few minutes to load a large script of 3.5 megabytes
the '
value' of a '
number' input field is the empty string when the field has an invalid value
Maybe the browser does not want to store an invalid value
on Internet Explorer 11, the '
valid' property of the '
validity' object is '
true' for a 'number' field with a value like '
On Chrome and Firefox the '
valid' property is '
the browser will store values in a '
number' field where the value is outside the '
min', '
max' and '
step' attributes of the field
The '
validity' object of the field has '
rangeUnderflow', '
rangeOverflow' and '
stepMismatch' properties for these
the following code works on Internet Explorer and Safari on Macs but not Chrome or Firefox (both on Windows) as of July 2014:
if (isIPad) {
true = false;
I have read that the 'V8' JavaScipt engine in Chrome turns the Javascript code in machine code
I check for missing semi-colons, at the end of function definitions set by adding to the prototype of an object, using my editor '
vi' with a pattern search '
^ }$'
I do this before releasing a new version
Google's style guide says not to use associative arrays, but to use objects
I had a bug where a change to one of the '
span' elements in a '
div' was not reflected on the screen
This was on my old Konqueror browser and Internet Explorer 8.
I solved this by putting the '
span' in its own '
I tried to copy the '
arguments' object with: '
[].concat(arguments)' but I got just one element - the '
arguments' object
Instead you can say '
Array.prototype.slice.call(arguments)' or '
[].slice.call(arguments)'. This may stop some optimisations with the V8 JavaScript engine of Chrome.
If the argument to the '
concat()' method of the '
Array' object is not a true array but an array-like object such as '
arguments' then '
concat()' adds its argument as a single element.
The '
call' syntax makes '
arguments' the object on which the '
slice()' is made, so '
arguments' is the '
this' object for '
The '
slice()' method of arrays is often used to make a copy of an array.
You can change the elements of '
arguments' which may change the value of the function parameters
if you say '
for (prop in obj)' then you need to declare '
prop' as a local variable otherwise '
prop' will be a global variable
if you give a local variable the same name as a parameter to the function then the variable and parameter seem to be the same thing
sometimes I click on a button, but the JavaScript moves the screen up before the JavaScript pauses and takes the click, so the button is not pressed
This is with my old Konqueror browser on Linux
with Chrome, it is difficult to save cookies when running an HTML page locally rather than on a website
'Web Storage' does not work on Chrome if the page is local, like cookies
on mobile Safari, it is hard to set 'focus' on an '
input' element except from a user's tap
if I miss off the '
}' in an '
if' statement then I get an error at the end of the script
if you set the title of an HTML element to
'' (an empty string) then if the tip is showing then the tip is hidden, but not on Internet Explorer 8
on Interner Explorer 10 and 11 and most other browsers, there is a '
filter' property on the style object of an HTML element, but the element does not retain the value of the '
filter' property if the property is set
to check to see if a CSS attribute is support by a brower, see if the attribute is defined and then set a valid value and see if the attribute retains the value
you can have tags like '
<b>' in text if you use '
createTextNode()' rather than setting the '
my animation that uses '
cloneNode' to make copies of most of the page is slow on an iPad but fine on a Galaxy Tab running Android
you can get the text in a '
span' with '
firstChild.data' This does not turn '
>' into '
>' as using '
innerHTML' does
with Internet Explorer 8, '
clearTimeout' did not seem to work when I moved away from the browser window
on Chrome, the border of a table does not seem to be included in the '
offsetLeft' of a table cell
On Internet Explorer 11, the border is included.
one way to get the position of an element is by using the function '
getBoundingClientRect' on modern browsers
the '
offsetParent' of an HTML element may not be the parent of the element
For example, the '
offsetParent' of a table cell is the table not the row
you can mark an element in the HTML by adding a dummy rule name to the '
class' attribute of the HTML
If you add a dummy attribute to the HTML element in the HTML then the attribute does not seem to show up in the JavaScript unless you use the '
getAttribute()' function
Adding your own attributes to the HTML may make the HTML invalid
borders within table rows are not part of the rows
For example, an '
onmouseover' event on the row does not fire when the mouse is over the borders between cells
the expression '
false || undefined' gives '
undefined' not
I use arrays rather than objects as the code is smaller: there are no names of properties and no constructors
a good article on the web suggests the following for a cursive font:
font-family: 'Lucida Handwriting', 'Monotype Corsiva', Zapfino,
'URW Chancery L', 'Courier New', Courier, monospace;
This avoids using '
Comic Sans MS' and has fonts for Windows, Mac and Linux
you can chain several '
replace()' functions together like:
r = s.replace(/a/g, 'x').replace(/b/g, 'y');
you can convert a string to a number by adding a unary plus sign like:
n = +s;
sometimes JavaScript will insert a semicolon into valid code
In the example below a semicolon is inserted after the '
return' statement so the function returns '
function btmp()
A semicolon may not be actually be added but the JavaScript interpreter will parse the code that way.
The rule is there so that a '
return' can be terminated by a newline and the following line can be a fresh expression.
Also there cannot be a newline between an expression and the postfix operators '
++' and '
--', between a '
break' or '
continue' statement and a following label, and between a '
throw' and its exception
you do not need to name a closure if you just return it like:
function btmp()
return function () { return 3; }
However the name may be useful for debuggers
a global variable '
g' appears as '
this.g' globally and '
The '
this' object is the enclosing function or global environment
the following is called an 'Immediately Invoked Function Expression' an IIFE, or 'iffy':
(function() { alert('iife'); })();
you can add '
toString()' and '
valueOf()' functions to simple objects like:
o = { toString: function() { return 'toStr'; },
valueOf: function() { return 3; } };
the expression '
!!v' turns '
v' into a '
true' or '
false' value
you can handle optional arguments to a function by saying:
o = a || 'default'
rather than:
a === undefined ? 'default' : a"
if the empty string and '
null' are to be changed to a default value
with optional arguments to be a function, if you check whether the value of an argument is '
undefined' rather than checking the length of the arguments then you also handle the case where the argument is given as '
;;;' is valid code - it is just three empty statements
there may be a minimum delay of 4 milliseconds for the '
setTimeout()' function when calls to this function are nested The minimum delay may be longer due to the operating system taking time to change threads or processes
a good book about design patterns with JavaScript is 'Learning JavaScript Design Patterns' by Addy Osmani
You can read it for free
an example of the 'Module' pattern is:
var Module = (function () {
var _privateArray = [];
var _privateMethod = function () {
var publicMethod = function (e) {
return {
publicMethod : publicMethod
The 'Module' pattern lets you have private methods and variables. The functions inside the module are closures
I adapted this example from a good article
an example of the 'Observer' pattern is:
var Observable = function() {
this.subscribers = [];
Observable.prototype = {
subscribe: function(callback) {
unsubscribe: function(callback) {
var i, len = this.subscribers.length;
for (i = 0; i < len; i++) {
if (this.subscribers[i] === callback) {
this.subscribers.splice(i, 1);
publish: function(data) {
var i, len = this.subscribers.length;
for (i = 0; i < len; i++) {
var Observer = function (data) {
var observable = new Observable();
I took this example from an article on the web
a simple example of the 'Publish and Subscribe' pattern is:
var EventBus = {
topics: {},
subscribe: function(topic, listener) {
if(!this.topics[topic]) this.topics[topic] = [];
publish: function(topic, data) {
var topicListeners = this.topics[topic];
if (!topicListeners) return;
var countTopicListeners = topicListeners.length;
if (countTopicListeners < 1) return;
var i;
var listener;
for (i = 0; i < countTopicListeners; i++) {
listener = topicListeners[i];
listener(data || {});
EventBus.subscribe('foo', alert);
EventBus.publish('foo', 'Hello World!');
I adapted this example from an article
I found a free copy of 'JavaScript Patterns' by Stoyan Sefanov on the web
But it is now gone
I would put a '
g' at the start of the names of my globals If I was starting again
the '
push' method of arrays returns the new length of the array
the expression '
x >>> 0' gives '
x' or zero if '
x' is undefined
it seems that with 'IndexedDB' you can save data locally with Chrome when running an HTML page locally rather than on a website
It seems you cannot save data with Chrome with cookies or 'Web Storage' when running an HTML page locally
you can see the contents of 'IndexedDB' databases on Chrome under the ' ' option of the ' '
To get to the '' click on the three bars in the top right and choose ' '
with 'IndexedDB', "to determine if a transaction has completed successfully, listen to the transaction's complete event rather than the success event of a particular request, because the transaction may still fail after the success event fires"
This is from the Recommendation of the W3C.
Requests have '
success' events whereas transactions have '
complete' events
'IndexedDB' error objects have '
name' and '
message' properties
Internet Explorer 11 does not support 'IndexedDB' if the webpage is accessed through the 'file://' protocol
Apparently Edge does support this
Here is a simple example of storing data with 'IndexedDB':
var dbName = 'britishbingo';
var dbVersion = 1;
var storeName = 'settings';
var keyName = 'cookie';
var myIndexedDB = window.indexedDB || window.webkitIndexedDB ||
if (myIndexedDB) {
alert('support idxdb');
} else {
alert('not support idxdb');
function createStore(db)
if(!db.objectStoreNames.contains(storeName)) {
db.createObjectStore(storeName, { keyPath : 'name' });
} else {
alert('database already contains store: ' + storeName);
function alertEventError(prefix, event) {
var eventTargetError = event.target.error;
alert(prefix + ': ' + eventTargetError.name + ': ' +
var openRequest = myIndexedDB.open(dbName, dbVersion);
openRequest.onsuccess = function(event) {
try {
var db = event.target.result;
var trans = db.transaction( [ storeName ], 'readwrite');
var store = trans.objectStore(storeName);
var putRequest = store.put({ name : keyName, value : 'opt:val'});
putRequest.onsuccess = function() {
alert('store: success');
putRequest.onerror = function(event) {
alertEventError('store err', event);
} catch(e) {
alert('openRequest.onsuccess: excep: ' + e);
openRequest.onupgradeneeded = function(event) {
try {
var db = event.target.result;
} catch(e) {
alert('openRequest.onupgradeneeded: excep: ' + e);
openRequest.onerror = function(event) {
alertEventError('open err', event);
Here is a simple example of getting data from 'IndexedDB':
var myIndexedDB = window.indexedDB || window.webkitIndexedDB ||
if (myIndexedDB) {
alert('support idxdb');
} else {
alert('not support idxdb');
var dbName = 'britishbingo';
var storeName = 'settings';
var keyName = 'cookie';
function alertEventError(prefix, event) {
var eventTargetError = event.target.error;
alert(prefix + ': ' + eventTargetError.name + ': ' +
var openRequest = myIndexedDB.open(dbName);
openRequest.onsuccess = function(event) {
try {
alert('openRequest.onsuccess: start');
var db = event.target.result;
var trans = db.transaction( [ storeName ], 'readonly');
var store = trans.objectStore(storeName);
var getRequest = store.get(keyName);
getRequest.onsuccess = function(event) {
alert('data is ' + event.target.result.value);
getRequest.onerror = function(event) {
alertEventError('get err', event);
} catch(e) {
alert('openRequest.onsuccess: excep: ' + e);
openRequest.onerror = function(event) {
alertEventError('open err', event);
references to objects are treated as 'true' in boolean expressions
I thought a reference with an address of zero might be 'false'
It is worth reading 'JavaScript The Definitive Guide' by David Flanagan. But it is not an easy read
It may be best if you know most of it already.
It is more of a reference guide.
There are free copies in PDF format available on the web, although these may be pirated. I borrowed it from may local library.
the '
resize' event does not fire on 'text-areas'
You can use '
mouseup' and check if the size has changed.
On Firefox, you can double-click to return the 'text-area' to its original size. I use '
setTimeout' with a small delay on the '
dblclick' event to check if the size of the 'text-area' has changed
I could not get the '
delete' method of an IndexedDB database to work
It seems to abort the transaction
the '
open' method an an IndexedDB database may sometimes hang after the '
deleteDatabase' method
with Chrome, the values for an IndexedDB database shown in the '' option of the ' ' settings do not update immediately
some say it is bad practice to use a '
for in' loop with an array
It may be slow going up the prototype chain.
You will get back any objects that you have added to the prototype of '
The array elements may not come out in order
some people always define functions as variables
For example: '
var f = function(){}'.
This emphasises that functions are just another object.
Also this avoids functions being 'hoisted' to the top of the script.
if you style a button and remove the style by setting the '
border' to
'' then the button does not go back to the default '3D' style.
The button now has a simpler '2D' look.
To get around this, add or remove a CSS class. Put the styling in the CSS class
if you use '
innerHTML' to set help text then you can have tags to set color, set italic and include lists with bullets
graphs render surprisingly quickly when drawn just with HTML
Tool tips are easier and the graphs show on old bowsers
you cannot really use references to objects as the keys of a hash
JavaScript stores the same string representation for all objects
you can pass a number by reference to a function by putting the number in an object
For example: '
n = { value : 3 }; f(n)'
the '
atan2' function may be better than '
You give '
atan2' values for 'y' and 'x' separately, so '
atan2' can return a larger range of angles
There is a good explanation on 'stackoverflow.com'
the 'user agent' string used by Edge looks much like Chrome's but with '
Edge' at the end
the 'File API' is mainly used to manipulate files selected by the user with an '
input' HTML element of type '
You cannot read (or write) any file
it is hard to style an '
input' field of type '
One way is to hide the field and click an associated '
label' which activates the field. You can style the '
label' making it look like a button.
I use a button with an '
onclick' event that fires '
click' on the '
file' input field.
Use an '
onchange' event on the '
file' input field to copy the file name to a visible area.
You cannot set the value of a '
file' input field
I use '
window.location' to tell if my game is being played online
window.location' starts with '
file://' if offline versus '
http://' or '
https://' if online.
Internet Explorer adds '
file://' if you just start the address with a drive letter such as '
I could not hide an '
option' tag in a '
select' tag by setting '
display' to '
I had to remove the '
option' tag
when I drew a pie chart with '
canvas', I spent a lot of time on the tip that appears when the mouse hovers over each segment of the pie
The browser just tells me the position of the cursor on the whole '
you can use '
isNan' to test if the whole of a string is a decimal number
parseFloat' just checks if the first part of a string is a number.
You can also say '
+s' and you will get '
NaN' if the whole of the string '
s' is not a decimal number
to get a random number between 1 and 10 you can write:
Math.ceil(Math.Random() * 10)
I was writing:
Math.floor(Math.Random() * 10) + 1
I wish I had written a common function to get a random number in a range
one way to remove the outline that the browser adds to a link when you click on the link, is to call the '
blur' function of the link in a '
click' event handler
I had a bug with a regular expression to match a number followed by a percent symbol:
/\b\d+(\.\d+)?(%)?\b/g with
The '
%' was not included in the match. It seems the last word boundary '
\b' matches the '
I used this regular expression instead:
/\b(\d+(\.\d+)?(%)?)(\W|$)/g with
$1 and
Note that I now capture the last word boundary as it is included in the match '
(\W|$)' unlike '
\b'. I am using the regular expression with '
setTimeout' is not accurate to the nearest milliseond
setTimeout' may have to wait for the browser and operating system to do other things
I had a bug where I stored the score in an array keyed by the name of the user. If the user gives a name of '
length' then my code fails on the line '
scores["length"] = scoreObject'
If the name of the user is '
pop' then the line '
scores.pop()' will fail.
I should use an object not an array but I get the same problem
I called a function that was within a function, when the '
transitionend' event fired. The inner function acted as a closure 'holding onto' the variables of the outer function. But the event sees the 'values' the variables had when the outer function finished, but not when the event was set up
you can dynamically create '
keyframes' for CSS animations
Create a '
style' HTML element, attach it to the '
head' element, and set the content of the '
style' with '
you can write the character '
\\u00A0' as the shorter '
browsers may not include CSS rules they do not recognise in the array of rules in the DOM
I found some browser-specific rules to style sliders were not included
with Chrome, an '
alert' box stops a CSS animation, but lets a CSS transition continue
If you show an HTML element and then immediately apply a CSS transition, then the transition may not show
You may need to force the browser to repaint the element. I query a property like '
offsetWidth' and have a short timeout
with sliders on Firefox, when I remove my styling, the slider is a bit small
I fix this by hiding the slider for a short time, then showing the slider, making it be repainted
Safari and Internet Explorer will not do a 360 degree turn with '
rotate3d'. Chrome does
The maths in the specification mean it should not work.
You can use a '2D' rotate instead.
Alternatively, I used 4 '
divs' within each other, each rotated 90 degrees after a delay with '
You can say '
1turn' rather than '
if I am using the '
this' variable a lot in a function then I assign '
this' to a one letter variable and use that
This helps with minifying the code.
I do the same with the '
arguments' variable
dynamic HTML is not as difficult as it looks.
I got away with only using these functions:
childNodes(), hasChildNodes(), firstChild(), lastChild(), nextSibling(), previousSibling(), createElement() createTextNode(), appendChild(), insertBefore(), replaceChild() and removeChild()
it is more precise and maybe faster to create a text element and append it rather than setting 'innerHTML' to a string: for example:
textElement = document.createTextNode('hello');
You can set an element's innerHTML to a much wider variety of tags and text
it is better to build up a string in a local variable and then assign it to a DOM element. Don't code something like this:
element.innerHTML += 'value: ';
element.innerHTML += i;
element.innerHTML += ', ';
element.innerHTML += j;
remember that neatly indenting your HTML adds text elements which can get in the way when your are going through the document tree. You might like to squash up the HTML
input' HTML elements do not have to be in a '
form' element
with text
input HTML elements, you can avoid being asked whether you want to commit your changes by creating the elements dynamically
you have to change HTML '
input' elements font-sizes on the input elements themselves - they will not change with any of their container's font-sizes
on my browser, Linux KDE's Konqueror, the radio buttons and checkboxs do not change size at all
my browser, Konqueror, adds on a certain amount of space around text input boxes regardless of my CSS settings. Internet Explorer does not do this
I use decimal color values in '
rgb(red, green, blue)' format rather than hexadecimal ones.
I usually have to think about what hexadecimals values are. I have not had any problems doing this with Internet Explorer or Konqueror
you can of course do transparency yourself - just take a (weighted) average of the red, green and blue values separately.
Older browsers such as Internet Explorer 6 may not support an 'opacity' setting, particularly if set dynamically
getting information from the DOM may be slower than storing it in JavaScript variables.
For example, remembering whether or not an HTML element is shown, with its style display set to be '
I am not sure if adding your own properties to HTML elements is better or not than storing them in global variables
if you size HTML elements in '
ems' or percents it is easy to do shrink and expand animations by just changing the overall container's font-size. I seldom set sizes in pixels.
if you are changing the page dynamically, you can look at a containing block's '
innerHTML' to see what is happening
remember that the user can scroll through the page
When you position a HTML element absolutely, add the amount scrolled. I use the value of '
window.pageYOffset' and where this not defined (such as on Internet Explorer) I use the property '
JavaScript won't redraw the screen until the script finishes or you pause with
setTimeout() or
You need to pause, maybe for longer than 50 milliseconds, to let the browser handle your mouse clicks and refresh the screen.
I had to pause for more than half a second when repeatedly shrinking the page in an animation by changing the font-size of a top-level '
div' element.
You could try using the '
canvas' element, but I am not sure if Internet Explorer supports it
it is best not to try to stop the browser putting outlines around links, button and form input elements when they have the focus.
After all, it is an accessibility feature to show where you are when, for example, you are using keys rather than the mouse.
Anyway, when I tried I could not completely get rid of the outlines. For example, moving around with the tab key between elements in a form would cause the browser to start showing outlines
to set the '
for' property of a HTML '
label' in JavaScript, you set the '
htmlFor' property.
Otherwise JavaScript confuses this with the '
for' loop keyword.
My browser lets you use '
for' in the '
setAttribute()' function for this but Internet Explorer does not
in one case with Internet Explorer (v8.0), setting the style property '
display' to '
none' on a '
div' HTML element does not hide the '
To get round this, I remove the '
div' from its parent.
The parent had a '
relative' position. The '
div' was offset with '
top' and '
left' style settings. The '
div' was put behind its parent with a '
z-index' value
the '
onresize' event of the '
window' object fires more often than just when you resize the browser window
For example, the event fires when scrollbars appear when the page is too big
the '
window.onresize' event may not fire when you change the text size using the menus of the browser
I check every few seconds to see if the size of an element on the page has changed using '
I have read on the web that you can also use 'custom events' to do this
If a container is not set to '
float' when its items are set to '
float' then the container will not have much '
offsetWidth' or '
with a '
select' list and Internet Explorer 8, if you refresh the page, then the selected option is not the option with the '
selected' attribute, but is the last option selected before refreshing
So, I set the '
selected' attribute with JavaScript
put a comment after closing tags that are far away from the opening tags
For example: '
</div> <!-- page -->'
it is best to put the caption of an image ih the HTML and not in the image itself
If the caption is in the image then the file size of the image may be larger
the '
pubdate' attribute of the HTML5 '
time' element was removed from the specification
the W3C HTML validator has an option to show an HTML5 outliner
The validator can also show the hierarchy of headings
you cannot have backslashes in a '
file' URL
in JavaScript you set an HTML element's '
className' not '
class' to add the element to a CSS stylesheet class.
Also remember that you set the '
className' on the HTML element and not in the elements '
style' object
when you want to set many style attributes of an element at once I have read that it is quicker to put them in a class and add it to an element rather than individually setting the attributes on the element's style object.
Actually my browser does not redraw the screen each time a style attribute is changed.
You can, of course, use the built-in string function '
replace()' to remove the class later
it is best to hide elements by setting their
style.display = 'none' rather than just setting their
innerHTML = '' as Internet Explorer seems to sometimes still leave a space for them.
a CSS style attribute that is not set has a value of
'', an empty string. To get rid of one of your style settings, set it to
Properties of HTML elements like '
class' and '
title' have values of the empty string (
'') if not set
you need to float the container of floated HTML elements for it to actually visually contain them on the screen
Another way around this is to set the '
overflow' CSS attribute of the container to '
Another way around this is to add a '
<br>' tag as the last element in the container and maybe give the '
<br>' tag a style of '
clear: both'
floated HTML elements can be squashed up if you do not specify a width
if you have 3 '
div' HTML elements ('
a', '
b', and '
c') one after the other and all styled as '
float: left' then if '
b' has '
clear: left' then on my old Konqueror 4.3 browser they appear as:
b c
whilst on Internet Explorer (IE), they appear as:
a c
I can get IE to look like my browser by putting '
b' and '
c' in a new '
float'ed '
div' and moving the '
clear: left' onto it
you can position a HTML element absolutely in relation to its container if you set the container display style to be '
not all the symbols in the list of HTML entities are supported in everyone's browser
I found that the mathematical symbol of a cross in a circle does not work on a friend's Internet Explorer. The copyright symbol works fine though
light colors appear as white on some computers
I set '
accessKey' values on some links and input buttons so that a user can press keys rather than the mouse.
On Internet Explorer you press the 'Alt' key together with the access key to click a button. For a link this gives it the focus and you can press the 'Return' key to follow the link. On my browser you press the 'Ctrl' key followed by an access key.
Access keys can be letters or numbers.
I had to change some elements to be links so I could give them access keys. This means an outline can appear.
I have read that access keys are less popular now as the key combinations can conflict with shortcuts used by screen readers.
If you use letters for access keys then they will override the keyboard shortcuts used by Internet Explorer. For example, 'Alt + F' will no longer select the ' ' menu. On my browser you have to focus somewhere on the page before you can use an access key, so this is less of a problem.
I have read that there is an informal standard for common access keys.
On Internet Explorer you may need to show the access key combinations in labels, list them all, or somehow underline their letters in the labels. On my browser when you press the 'Ctrl' key it shows all available access keys.
I have to squash up the HTML when I give each letter of a word a different color.
If I put each letter in a separate '
span' tag, the browser seems to add spaces between the letters unless I put the '
span' tags right next to each other in the HTML on one line with no spacing. Unfortunately the HTML is then difficult to read
check your HTML and CSS regularly with the W3C validators.
Don't leave it until you are finished like I did!
I had a problem where the HTML,
'hello,\n world'
is rendered as
with no spaces ater the comma.
This happens in both Internet Explorer and my browser.
I fixed the problem by adding a space after the comma
specify the character set of your page with, for example:
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
rainbows look nice. I create them with lots of '
div' elements '
floated' together
you can put '
' (non-breaking space) between the words in a link to stop the link being split across lines
with a '
select' list and Internet Explorer 8, if you refresh the page, then the selected option is not the option with the '
selected' attribute, but is the last option selected before refreshing
So, I set the '
selected' attribute with JavaScript
if you 'minimise' your HTML and turn something like:
then the browser no longer shows a space between the input boxes
on Internet Explorer 6, some radio buttons, when hidden with '
display: none', cause other radio buttons below to be strangely laid out
I fix this by removing and re-creating the first radio buttons when needed
some old browsers do not seem to apply the '
width' and '
height' you set for '
td' elements
on Internet Explorer 8, the '
title' of HTML elements only shows for a few seconds
I made the '
title' too long and there was not enough time to read it
number 'spinners' only seem to check your input against the '
min', '
max' and '
step' values of the 'spinner' when you submit a form
the height of a '
td' element in a table does not always seem to be the height you set
at first, Firefox did not seem to support 'number' input fields and their spinboxes (as of January 2014)
a usability expert suggests '
title' attributes should not be more than 80 characters
Also titles on links should mention the name of the website, and say if the link will open in a new tab or window
some people think the '
id' and '
name' attributes of the '
form' HTML element should be the same
I use 'HTML Tidy' to find problems
I use an online version where you can copy and paste or upload the code.
'HTML Tidy' told me I had an unmatched '
div' tag and no '
summary' on tables used for layout
if you give a link a '
target' attribute then the link may open in a new tab or window
If you click such a link more than once then the link opens in the same tab or window
it really is much better to use a '
<p>' tag rather than a '
<br>' tag
I got a blank line maybe where my browser wrapped the line just before the '<br>' tag
put a header tag, such as '
<h2>', after the HTML5 '
<section>' tag
there are tools to find broken or 'dead' links
I use an online tool
I use an outliner to see the hierarchy of my HTML5 '
I sometimes put '<' and '>' characters in the content of my web page when I should use '<' and '>'
The browsers do not mind though
it seems you should use an '
id' attribute not the '
name' attribute to identify the target of the fragment of a link (e.g. '
some people say you should not open links in new tabs
They say users lose control, you cannot use the 'back' button, and that some users do not understand tabs.
Others say you should use new tabs for external links or for information that is not closely related.
Most people agree that you could use a new tab for help information when filling in a form.
You can use the '
target' attribute in HTML to open links in new tabs
you should use 'curly' quotes to enclose what people say
The HTML entities are '"' and '"'
Some say you should use numbers rather than names for the entities as old browsers may not know the names. The entities for 'curly' quotes are '"' and '"'.
The HTML entities were not translated when I created a text node. I had to set the '
innerHTML' of the HTML element. This trimmed off trailing spaces
remember to use the HTML entity for ellipsis ('…' rather than three dots
There are HTML entities for common fractions and dashes
I put the unicode value ('\u2026') in a JavaScript string to get an ellipsis in the '
value' attribute of a '
button' input field
an '
input' HTML element of type '
file' does not show the full path of a local file on Chrome and Firefox, for security reasons
Internet Explorer 11 does show the full path
curly opening and closing quotes are not curly on Windows7. They are straight, slanting in and out
- I tried an HTML minifier I found
But it missed out a '
</section>' tag when I ran the minifier on the these tips.
The minifier reduces the size of the HTML by about 25%. But squeezing consecutive whitespace to one space reduces the size by 20%. I used the Linux '
tr -s' command.
Shortening the CSS rule names reduced the size by another 5%. I used '
However, I learnt a lot about HTML from the related article
Internet Explorer uses the 'D' access key to go to the address bar
I use a lowercase 'i' for the label of an access key as an uppercase 'I' looks like the vertical bar '|'
on my old Konqueror browser, when you 'tab', you go to fields that are not displayed
To stop this, I set these field to '
with access keys on Chrome, 'Alt+E' and 'Alt+F' make the Chrome menu appear
I have to press 'Alt' and 'Shift' and 'E' (or 'F') to get the access key
there are symbols in Unicode for transport symbols and emoticons
The helicopter symbol is not available with Chrome on Windows7.
The symbols do not scale very well, if you increase the font size. You see steps at the edges not curves for larger sizes
I read in a good book that the Firefox browser evaluates CSS rules from right to left.
If you have, say, the rule:
'form a { color: blue; }'
Firefox checks every anchor to see whether it is in a form.
The book suggests it is faster to use HTML element id's and classes in CSS rules rather than HTML tag names. Maybe this applies to other browsers
do not put JavaScript '
//' comments in a stylesheet:
my browser, Konqueror v4.3 with KHTML, does not report an error but sometimes ignores some of the CSS that follows the '
//' comment.
I tend to put '
//' comments in the stylesheet when I am mainly writing JavaScript
Internet Explorer does not seem to recognise HTML element
id's that start with an underscore in CSS rules.
I think the HTML standard may disallow this too.
I use underscores when shortening names in my 'minimising' script to avoid generating names that are the same as existing names
you cannot have decimal places in the numbers you use to set the color with an '
rgb(redNum, greenNum, blueNum)' format.
For example, '
rgb(200.1, 0, 0)' is ignored
a good book I read suggested setting to zero by default all margins and padding with the following:
* {
padding: 0;
margin: 0;
This worked well for me
using a '
border-style' of '
outset' or '
ridge' is a quick way to get a sort of 'shadow'
Internet Explorer lets you use a '
font-size' as low as '
you can draw a circle or ellipse around a HTML element by using a '
border-radius' of about half the width or height of the element
I decided to underline a link after reading the book "Don't Make Me Think" about the usability of web sites
If you scroll down a greyed-out page created with the CSS '
width: 100%; height: 100%', then the grey scrolls up and away
None of the fixes I found on the web work for me with Internet Explorer 8
z-index' values seem to work best when the HTML elements are close together in the document tree
putting comments above the 'document type declaration' makes Internet Explorer go into 'quirks' mode
In 'quirks mode', Internet Explorer behaves as it did in very old versions. In 'quirks mode' the '
width' and '
height' of a HTML element includes the '
padding'. This is called the 'Internet Explorer box model bug'
One simple way around this bug is to put the spacing in the '
margin' not the '
setting '
box-sizing' to '
border-box' may fix some layout problems
Remember to include any padding in the width and height
the 'Georgia' font on Microsoft Windows® has numbers with different heights
you can only specify a '
clip' rectangle on a HTML element with its '
position' given as '
The clipping seems quick.
Internet Explorer before version 8 does not have commas between the sizes of the rectangle.
On my old Konqueror browser, if you have not clipped the enclosing area, then bits of the element outside the clipped rectangle are still shown
Internet Explorer 8 gives an error if you set the '
clip' property to an empty string with JavaScript. Setting '
clip' to its default of '
auto' does not seem to work in Internet Explorer 6, so I set the '
clip' to "
rect('auto', 'auto', 'auto', 'auto')"
I use the opacity in the 'rgba' colours where setting the '
opacity' of a '
div' did not affect its background color in newer browsers
buttons in newer browsers sometimes look better with extra padding around the words
The padding I add is:
|Side (em)
|Top/Bottom (em)
|Internet Explorer 7 and before
|Internet Explorer 9 and after
|Webkit on MS Windows and Apple Mac
|Firefox on MS Windows
|Opera (Presto renderer before Webkit)
Buttons on the Android browser do not seem to need any extra padding. The padding needed on browsers on Linux seems to vary
I believe that if the '
:hover' rules changes the layout of the page, then on a touch-screen you may have to tap again ('double-tap') so you can see the change in the layout before it disappears
you can make checkboxes and radio buttons bigger with the '
transform: scale(2,2)' CSS property
This works on Internet Explorer as far back as version 9.
This does not seem to work on Chrome on Windows 8.1.
The bigger checkboxes and radio buttons overwrite nearby elements of the page.
I find it difficult to know where scaled-up 'text' and 'select' boxes are put, so I increase the font size
I forgot to include '
-khtml-' in the vendor prefixes for CSS attributes
I read that Webkit recognizes '
-khtml-' as well as '
I read that it is best to have an obvious 'active' state (maybe a colour) on buttons and links
On a touch-screen it is not always clear if your press has had an effect
I had a bug which was hard to find when I forgot to close an open bracket
I am glad I used buttons rather than CSS menus as on touch-screens you may have to tap twice on the menus
there needs to be a a space after the comma separating two Microsoft visual filters
For example:
filter: progid:DXImageTransform.Microsoft.
Alpha(opacity=20), progid:DXImageTransform.Microsoft.
gradient(GradientType=0, startColorstr=#cccccc,
in one case, Internet Explorer 8 hangs when there is a gradient generated by a Microsoft visual filter
the last setting in the stylesheet takes precedence regardless of the order in which you specify rules in the HTML '
class' attribute
on an iPad or iPhone, buttons change from round to square if you give a '
the color gradient drawn with '
background: linear-gradient' seems to be generated very quickly
you can do '
text-shadow' in old versions of Internet Explorer with Microsoft's visual filters
But the '
Shadow' filter leaves marks on the edges of letters
on Internet Explorer 8, if you give cells in a table a gradient with a Microsoft visual filter, then the gradient overwrites the borders of the cells
To get round this, on the table I set the '
border-collapse' option to '
separate'. Now the 'border' is the spacing between cells, which shows through the background of the table
setting the width of an HTML element to '
100%' may stop the width of the element being taken from another element
box-shadow's are rotated when you rotate an HTML element with a CSS '
I change the direction of the shadows to face the right way
if you rotate the '
tbody' of a table then not all browsers show it correctly
you can change the centre of the roation with '
on the iPad, if I rotate the page below the bottom of the page then there are black rectanges at the bottom right of the screen and the animation stutters (as of May 2014)
you can turn off the red border around '
number' input fields which shows when the content is invalid by saying:
:invalid {
box-shadow: none;
For example, the red shows when a field has the '
required' attribute but has no value.
I got the red border on Firefox when '
required' was not set and the content was valid
if I have a '
span' in a '
div' and I give the '
span' a large '
border-bottom' or '
padding-bottom' then the '
span' overflows below the '
I use this for my tabbed settings to set the color at the bottom of the tab index to the background color of the tab contents
With Chrome on Windows, I have to set the '
border-bottom' to '
2px'. For other browsers '
1px' is enough
having a '
dotted' rather than '
solid' '
border-radius' for 90 balls noticeably slowed down the game
I have read that '
border-radius' is worse for performance than '
box-shadow' and '
rotate' transforms
lots of floated items may lead to more reflows of the page
if you rotate some text aroudn the 'y' axis with '
rotateY' then the text disappears
The text has no depth
a rotation around the 'z' axis with '
rotateZ' is just a rotation in 2 dimensions
Internet Explorer 9 seems to support rotations in 2 dimensions with '
rotateZ' but not rotations in 3 dimensions like '
to get several elements to share the same 'vanishing point', set the attribute '
perspective' on the parent element
you can repeat the name of a CSS rule in the '
class' attribute of an HTML element
This may simplify the JavaScript code
you can centre text vertically by putting it in the cell of a table
To centre horizontally, say '
text-align: center'.
The cell height is a little bigger than '
1em' on my old Konqueror browser even if I say '
line-height: 1' and '
cellspacing="0"' and '
you can draw a cube by: putting the sides in the same place with '
position: absolute', rotating the sides, and pushing the sides out half a width
Here is the code I adapted from an article on the web:
.cube {
perspective: 1000px;
transform-style: preserve-3d;
.face {
position: absolute;
font-size: 1000%;
line-height: 1;
td {
width: 1.5em;
height: 1.5em;
text-align: center;
border: 1px solid;
opacity: 0.5;
line-height: 1;
.front { transform: rotateY(0deg) translateZ(0.75em); }
.back { transform: rotateX(180deg) translateZ(0.75em); }
.right { transform: rotateY(90deg) translateZ(0.75em); }
.left { transform: rotateY(-90deg) translateZ(0.75em); }
.top { transform: rotateX(90deg) translateZ(0.75em); }
.bottom { transform: rotateX(-90deg) translateZ(0.75em); }
.cube { transform: translateZ(-0.75em); }
<table class="face front" cellspacing="0" cellpadding="0">
<tr> <td> f </td> </tr>
<table class="face back" cellspacing="0" cellpadding="0">
<tr> <td> b </td> </tr>
When I rotate the cube as a whole, I do the rotation on each side. I got strange results when I did the rotation on the parent element containing the sides. Maybe rotating each side means the transforms have the same origin
I use a large perspective (between
1750px and
3000px) for my cube
transform-style: preserve-3d' cascades 3D attributes like '
perspective' onto child elements, but not on Internet Internet Explorer 11
a '
rotateX' transform with a positive angle, rotates a cube vertically up and you see the front face, then the bottom, then the back and then the top
a '
rotateY' transform with a positive angle, rotates a cube horizontally, left-to-right, anti-clockwise, like in maths, and you see the front face, then the left, then the back and then the right
with IE11, you can just style the colors of an HTML progress bar and the bar looks very simple. With Firefox, you can just style the inner 'value' bar
I drew my own progress bar using CSS like '
width: 30%'
setting the '
transform' attribute to '
rotateX(90deg) rotateY(90deg)' gives different results to '
rotateY(90deg) rotateX(90deg)'
The second rotation acts on the results of the first rotation, like matrices in maths.
When I rotate a cube, I put the cube rotation first and the faces rotation second
I turn off '
perspective' by setting the attribute to zero as setting the attribute to the empty string (
'') has no effect
you can use '
backface-visibility: hidden' to draw a solid cube
This seems to do the 3D hidden line removal
if I try to draw and rotate a cube on an iPad then the cube just disappears
on an iPad mini, with a font size set to '
smaller' than the default, then I have to look closer to read the words
corners with a small '
border-radius' can look like steps
light background colours vary their darkness widely among the different computers I use
a wide caption may make a table wider - the caption may not wrap
I had a bug where a missing semi-colon in the CSS caused the browser to ignore a following setting of the '
background-color' to a '
rgb' value
a CSS rule referenced by the '
id' attribute of an HTML element, overrides a CSS rule referenced by the '
class' attribute of the same HTML element
a CSS rule later on the page overrides an earlier rule regardless of which order the rules are in within the '
class' attribute of an HTML element
a font size a little smaller than the default looks nice and is easy to read, except on tablets and phones
I have a table with a '
box-shadow' where the shadow is over the caption on Firefox but not Chrome or Internet Explorer 11
I cannot reproduce this with a simple example
I use a '
border-bottom' for underlining rather than '
text-decoration: underline' as the latter puts the line through the bottom of a letter 'g'
However, I have to add extra space below the line with '
line-height: 150%' to stop the border touching the letters on the next line
to center an image, say '
display: block', '
margin-left: auto' and '
margin-right: auto'
I used '
display: inline-block' to give a width to an anchor in a '
A size of '
90%' looks smaller and '
70%' looks smaller still on Chrome, Internet Explorer 11 and Firefox on Windows7
A stray '
*/' in my CSS caused my browser to ignore the next line of code
Giving an HTML element a '
position' of '
relative' may put the element above elements that come later in the HTML
Internet Explorer does not let you use '
box-shadow' with a table where '
border-collapse' is set to '
One solution is to set '
border-collapse' to '
separate', set '
border-spacing' to '
0', set '
border-right' and '
border-bottom' on all cells, '
border-left' on cells on the left edge of the table and '
border-top' on the top edge.
Also browsers may not let you put round corners on a table where '
border-collapse' is '
You might use the above solution and set '
border-radius' on the cells at the table corners with '
border-radius-top-left' and so on. But now any shadows on the table do not have round corners. Also the background of the table shows through at the corners.
A better solution is to set '
border-left' and '
border-top' on all cells in table table. Then turn off '
border-top' on the top row and turn off '
border-left' on the left-most columns. Add a border to the table. Then set the same '
border-radius' to the table, and the table cells at the corners of the table as before. You need to set the '
border-radius' of the table cells otherwise the cells obscure the round corners of the table
I found some good tips on the website of the World Wide Web Consortium
it seems you can turn off the '
filter' attribute on old versions of Internet Explorer by saying '
You can also say '
enabled=false' as a property of the gradient filter
the default font on browsers on Windows seems to be a 'serif' font. On my Konqueror browser on Linux the default font is a 'sans-serif' font
using percent sizes with '
text-shadow' does not seem to work, but using '
ems' does
there is a good, but old, web page about fonts common to all browsers and operating systems
There is a good, but old, discussion of common fonts in this article and comments
Chrome seems to run a CSS animation each time I hide and show the HTML element with the animation
Firefox seems to run the animation just the first time the HTML element is shown
Internet Explorer 11 seems not to show a CSS animation if the name of the animation is not set when the HTML element is made visible in the JavaScript code even if the screen is yet to be re-drawn
One way round this, is to set a default value for the 'animation-name' in the CSS and override this in the JavaScript code
it seems you cannot use '
text-shadow' with CSS animations on Internet Explorer 11
browsers seems to make table headers bold, by default
it seems that to get round corners on a table row, you have to set the '
border-radius' on the table cells
Chrome defines the CSS '
filter' attribute but I had to set '
This is on Windows7, May 2016
the '
blur' CSS filter is may favourite
A large '
drop-shadow' filter can be slow
if you use '
border-radius' with a 'text-area' then there may be gaps in the border around the corners of the scroll bar
the '
font-size' of a table may not be taken from the enclosing block
Say '
font-size: inherit' to fix this.
This may happen on old browsers or when in 'quirks' mode.
The default stylesheet of the browser may have a value for '
font-size' for tables which you need to override
if you change the border of buttons then you may lose the nice default look
This also applies to input fields, text-areas, select boxes and so on
it really is a good idea to specify a '
background' when you give a '
For example, my browser does not support '
the W3C CSS validator reports lots of errors where I use browser-specific prefixes and Internet Explorer's '
when animating '
box-shadow' on Internet Explorer 11, in the '
key-frame' you need to set values at '
0%' and '
100%' as well as '
Internet Explorer 11 adds extra space at the top of the page when the HTML5 '
header' tag has a '
display' of '
Maybe this happens on old versions of Internet Explorer.
I do not want to use JavaScript and unknown tags are '
I just do not use a '
header' tag after the '
body' tag
the cursive fonts '
Monotype Corsiva' and '
SnellRoundhand' have smaller lowercase letters than fonts of the same size
SnellRoundhand' is the default cursive font on iOS
with the '
Avantgarde' font, Chrome sometimes breaks a single line of text into two lines
This font is wider than normal
the '
fantasy' font on Firefox on Windows 7 seems to be just '
- 'cssfontstack.com' has lists of fonts that look like the same font family on Windows and Mac
the Windows cursive font '
Monotype Corsiva' looks smaller than other fonts of the same size
This also applies to other cursive fonts
on an iPad the default cursive font is a handwritten one. On Windows, with Chrome and Firefox, the default is '
Comic Sans MS'. The default with Internet Explorer is not very cursive
if you give an image a '
width' and '
height' then the brower will not reflow the page as the images are loaded
on an Apple Mac, if you set the '
background-color' of a button then the button loses its default look with round corners and the button becomes a rectangle
On an iPad this does not happen. But if you set a '
linear-gradient' on an iPad then the buttons loses their default rounded look
a CSS animation using '
box-shadow' slowed down the game on an iPad
I read that Safari on iOs uses hardware acceleration for '
transforms' but not '
cursive fonts are extra wide
They are even wider than 'Avant Garde' fonts
the 'Zapfino' cursive font has very tall letters
For example, the letter '
g' comes down a lot.
This font may be the only cursive font on iOS
with tabbed panels, one way to get the tabs to overlap the panels is to pull up the panels with '
margin-bottom: -1px' on the tabs
You can then set the color of the '
border-bottom' of the active tab to the color of the active panel.
If you '
float' the tabs then they come out above the panels
the color of the 'crosshair' cursor seems fixed on Chrome and Internet Explorer. The color can get 'lost' in a similar background color
Firefox seems to choose a color that contrasts with the background color
it is hard to immediately restart a CSS animation using '
I clear the animation details from the HTML element, pause for a millisecond using '
setTimeout', and then set the animation details again
you can use the '
uuencode -m' command on Linux to convert an image to 'base64' format, for use with a '
data' URL
I remove the headers and newlines
I put one '
div' element inside another to draw a star with two triangles. It is simpler to dynamically create the stars this way than if you use '
:before' or '
I put the outer '
div' in another '
div' with '
position' of '
absolute' to avoid content flowing round the '
relative' outer '
my CSS animations 'stutter' when a game is being played
They pause every few seconds, for a fraction of a second, then jump to a later part of the animation.
I use '3D' transforms to get the animation to run on the GPU.
An animation of an old lady walking looks more natural with a 'stutter' than a bouncing ball.
I do not get a 'stutter' when the animatons run by themselves
the '
clip-path' attribute in CSS lets you create outlines of images with the '
polygon' shape
The 'clippy' tool lets you trace out an image
you play sound on the latest browsers by using the '
audio' and '
source' tags that are new with version 5 of the HTML standard
you can have sound on Internet Explorer version 8 and earlier by using the '
bgsound' tag.
When you give a value to the '
src' attribute of this tag the sound begins to play (asynchronously). Any sound currently playing stops.
I store how long each sound takes within the game. This data is quite large.
I create a small version of the game which does not have the lengths of the sound
to play sound files held in a sub-directory you give a path with '
/' separators not the '
\' separators usually used by Microsoft® Windows
the free 'SoX' (Sound eXchange) tool is good:
if you build the tool yourself you can convert sounds to the 'MP3' format by getting the 'LAME' (LAME Ain't an MP3 Encoder) and 'MAD' (MPEG audio decoder library) libraries.
I think this works around the patent.
There is a '
lame' program that converts files in 'wave' format to 'MP3'
I had to get the 'Ogg Vorbis' libraries too
to play sound files held in a sub-directory you give a path with '
/' separators not the '
\' separators usually used by Microsoft® Windows
I used the 'pitch' effect to get a female voice from mine, and I used the 'echo' effect to make it sound like being in a bingo hall
I shortened a few sounds by using a sound wave editor to reduce the silence between words and to cut out parts of the same pattern of sound
I sometimes just cut out some peaks of sound like "t's"
I offer separate archives of just '
MP3' files for Internet Explorer and Safari, and also just 'Ogg' files for the Firefox, Opera and Chrome browsers
This reduces the size of the archives
I use the '
soxi' program that comes with 'SoX' to find out how long a sound takes to play
I hold the microphone just in front of my chin.
The sound is distorted if I hold the mic in front of my mouth
recording sounds takes a long time
The game has 6 different voices each saying the numbers from 1 to 90
I use the Linux '
paste' and '
cut' tools a lot when working with big lists of '
sox' or '
soxi' commands and their results
it sounds better if you record whole sentences rather than individual words
it is probably better to add sounds as you develop the code
Because I waited until the end, I had to split up some complex sentences into words and just play the sounds for each word
I put the sound files in directories named after the first letter of what is said
This is like the 'terminfo' files in Unix. I could have also created sub-directories named after the second letter of what is said
An even better way might be to calculate a hash value from the letters in a phrase. I have lots of phrases that start with 'because'
I shortened long names of sound files by taking the first letter of words at the end of the name of the file
(My sound files are named after the phrase they contain, with spaces converted to underscores)
how you handle saying '22?' versus '22' is a problem
I sometimes put my fingers above and in front of the microphone
This stops the distortion I get from holding the microphone close to my mouth.
I still hold the microphone in front of my chin
The sounds files for the game take up a lot of space: a quarter of a gigabyte
I have about 10,000 sound files
I should have used the 'normalise' function of my sound editor
It scales up the sound, making the loudest part the maximum.
But it won't work if I have a few large peaks of sound
It takes me about an hour to record 50 phrases
The '
unzip' program tells you if you are about to overwrite an existing file but the '
tar' program does not
my animation using JavaScript pauses a little before a sound is played
I have a problem where there are pauses between sounds that should immediately follow each other
I am not sure whether the problem is with my code or the browser.
Part of the problem may be that when I test the game the sounds are on a slow memory stick
interrupting someone talking by setting the '
src' attribute of the '
bgsound' HTML element to an empty string (
'') sounds abrupt and not natural
when I create a compressed archive of sound files, the size is not reduced much
MP3 and Ogg files are already compressed
only a few people download the sounds for my game
The files are large. Experts say people do not like sound on web pages
I forgot to plan for a sore throat, aircraft overhead and nearby drilling
using SoX's pitch and tempo effects makes the sound less clear
you do not seem to need to append an '
audio' HTML element to the body of the document when you create the '
audio' element dynamically with the '
createElement' function of JavaScript
I did try appending the '
audio' tag to the body but with Internet Explorer 11 on Windows 7 the sound stopped working after playing lots of sounds
to adjust the volume on Windows 7, select the 'Windows Media Center' from 'All programs' in the start menu, and then click on 'Music' and use the '+' and '-' buttons on the bottom right
if I use the '
audio' tag and lots of sounds then the game sometimes pauses for a few seconds with Internet Explorer 11 on Windows 7. Sometimes I do not hear any more sounds after the pause
So I use '
bgsound' tag for all versions of Internet Explorer
the sounds sometimes take time to start on an old computer running Windows 7. This makes the sounds overlap
on Windows, if there is a link that plays a sound file then to save the sound, right-click on the link and choose 'Save target as'
some sounds are missed out when using the '
bgsound' tag with Internet Explorer 11 on Windows7 and when using the '
audio' tag with Firefox on Windows7
This may be because I have the sounds on a memory stick which is slow
Chrome may look ahead with sounds whilst Firefox lags. This is from a comment on the web.
Using 'sprites' may be one solution, where one file contains many sounds and you 'seek' around. This can be tricky
I used the events that fire on an '
audio' element to debug the sound
These events fire for me in this order: '
play', '
waiting', '
loadstart', '
suspend', '
loadmetadata', '
loadeddata', '
canplay', '
playing', '
canplaythrough', '
For example, I had a bug where I could not hear anything but I could see the browser loading and playing sounds
I use the '
ended' event on the '
audio' element to start the next sound
I have a timer that starts the next sound if the current sound cannot be loaded
if a sound file does not exist then the '
audio' element seems to wait and does not fire an '
error' event
I tried stopping sounds by setting the '
muted' property of the '
audio' element to '
This seemed to fit in more than setting the '
src' attribute of the '
source' element to an empty string
However it seems the '
muted' property may be ignored on mobile platforms
An article on the Mozilla Developer Network says to
pause the sound and set the '
currentTime' property to zero. On Chrome, it seems you have to also set the '
src' to an empty string
to play my 'Ogg' sounds with Firefox, I have to include a 'vorbis' codec
I set the '
type' of the '
source' element to '
audio/ogg; codecs=vorbis'
Android may only play sounds one at a time
iOS may only play sounds from a 'user event'.
I read this on the web.
This refers to sounds played with the '
audio' tag
there is a separate manual page 'soxformat' for how SoX handles different audio formats
'mp3' files may be padded with silence at the start and end
You can find out more on the web
This may be due to overlapping frames.
For example, if I convert a sound file in 'Wave' format to 'Ogg' and 'MP3' then the 'MP3' file has a longer duration
on Firefox, it seems you cannot just set the '
currentTime' and then call '
play()' on an '
audio' element
Instead you may have to call '
load()' and have a callback on an event like '
loadedmetadata' which sets the '
currentTime' and calls '
sound files load quickly: a 2 megabyte 'Ogg' or 'MP3' file loads in under a second
The file is about 3 minutes of sound and is on a memory stick.
I think sound sprites are for loading sounds over the internet
I kept the original timings of individual sounds by combining sounds in 'Ogg' format and then converting the result to MP3
Firefox now supports sound in 'MP3' format. Firefox needs the operating system, such as Windows, to provide an MP3 decoder
Chrome supports MP3
On Firefox with 'Web Audio' and an '
audio' tag as a source, the sound file has to be next to the page or in a sub-directory below the page, if the sound file is a local file
I tried loading sounds into '
audio' tags at the start
This only seems to load the first frame of sound.
Internet Explorer still seems to miss out sounds.
I even tried playing all the sounds at the start and holding onto the '
audio' elements
I have to call the '
play' method on the '
audio' tag before putting the sound into 'Web Audio'
I stop the sound when using 'Web Audio' and the '
audio' tag by stopping the '
audio' tag by setting the '
src' attribute of the '
source' tag to
'' (the empty string)
'Web Audio' on Firefox does not support the '
stop' method on a '
source' created from an '
audio' tag. My Firefox does not support the '
start' method either
Chrome will not play sounds with 'Web Audio' and the '
audio' tag if the sound files are on your computer rather than a website
This may be a security feature as you can look inside sound files with 'Web Audio', and the '
audio' tag can load sounds from anywhere on your computer
people say you need to route the sound into 'Web Audio' when an event like '
play' fires on the '
audio' tag, but this does not seem necessary
My code looks like:
var audioElement = document.createElement('audio');
var oggSourceElement = document.createElement('source');
oggSourceElement.src = oggFilename;
oggSourceElement.type = 'audio/ogg; codecs=vorbis';
var mp3SourceElement = document.createElement('source');
mp3SourceElement.src = mp3Filename;
mp3SourceElement.type = 'audio/mpeg';
var myWindowAudioContext =
window.AudioContext || window.webkitAudioContext;
var audioContext = new myWindowAudioContext();
var audioSource =
my sounds play well if I use 'Web Audio' and load the sounds in with 'Ajax'
Internet Explorer does not support 'Web Audio'. You cannot use 'Ajax' with local files.
But sounds may take different times to load across the internet
Firefox plays sounds fine if you load in sounds with the '
audio' tag and route the sounds into 'Web Audio'. So Firefox can load in local sounds fine
the '
ended' event seems to fire when you '
stop' a source in 'Web Audio'
Firefox sometimes seems to add '
range' HTML headers when I load in MP3 sound files with 'Ajax'
The request status returned is '
206' for 'partial content'. Maybe Firefox just wants to load the first part of a sound file.
So I try to override this by specifying my own range header of '
to find out which type of sound file to load in with 'Ajax' with 'Web Audio', I load in a test sound file with an '
audio' tag with multiple '
source' children and look at the '
currentSrc' property of the '
audio' tag on the '
canplay' event with the '
muted' property set to '
the sounds play perfectly for Chrome and Firefox with 'Web Audio' and 'Ajax' (to load in the sounds)
Ajax only works for sounds on a website not stored locally
Firefox with 'Web Audio' would not decode an MP3 file of music from 'bensound.com'
I used my old 'SoX' utility to convert the file to 'Ogg' format and back. Firefox could then decode the new MP3 file
I found background music with a clear tune is best
A 'samba' was too subtle
Firefox gave an 'out of memory' error when decoding songs with 'Web Audio'
I use an '
Audio' HTML tag instead.
'Web Audio' is for short sounds
Chrome now only starts playing sound as part of a user interaction
Chrome suspends the playing of sound when I create an '
AudioContext' to decode the sound when loading the page. I call '
resume' on the '
AudioContext' when the user presses a button to start a game
You can play sounds later outside of a user interaction
I cannot put the music from 'bensound.com' on Sourceforge because the music has a 'no derivative works' license
Sourceforge wants its contents to have licenses that conform to the 'Open Source Definition' which says derived works must be allowed
'000webhost.com' is a good place to test the error handling of playing sounds as '000webhost.com' is a little unreliable
a 2 minute file of music takes 3 seconds to load and start playing using 'Web Audio' and 'Ajax'
The music takes 300 milliseconds to start playing using the '
audio' tag. Maybe the music starts playing before it is fully loaded
I understand that search engines now give little or no weight to the '
keywords' and '
description' '
meta' tags
I did not quite believe the experts who say this, but it is evident in the results of Google's web crawler
some web sites, which list scripts, programs and games for download, ask authors for the location of the related 'PAD' (Portable Application Description) file.
The PAD file is in XML format and contains a description of the program and says where the program is, what operating systems the program run on and what category the program is in. An example is the PAD file of this Bingo game.
The PAD file is useful even for websites that do not take PAD files, as the file holds in one place all the information you need to submit about your program.
The PAD website tells you what can go in each tag. For example, you have to use specific operating system names and categories classes. The PAD website can also validate your PAD file.
The '
Primary_Download_URL' tag wants the name of a installer, like those used on Microsoft® Windows. The file extension of the installer must come from a small list. I give the name of a zipped version of the HTML file of the game
After adding the game's PAD file to the online repository, I got a few emails from download sites saying how good the game was and asking me to add a link to their site. I am not sure how genuine these sites are
The official PAD repository and validator changed in 2013. They are now at 'appvisor.com'.
You now use a GUI to enter the details on the PAD file and validate them. The GUI took me a bit of getting used to. The GUI does not completely work with Internet Explorer 8. You can import an old PAD file.
The new validator found a few errors with my old PAD file. The PAD details are now checked by humans before they are added to the repository. They wanted me to put in a real postal address. A PAD file is generated which is now held on the 'appvisor' website. You still need to submit details of your PAD file to each download site.
Appvisor encourages you to pay a little to have your program regularly 'certified' and to pay them to 'promote' your program to download sites and web directories.
Appvisor says the standard size for a screenshot is 800 by 600 pixels
a bold announcement of an unusual feature attracted a lot of interest
I posted on 'freecode.com': "World record set for 15,000 bingo players". Over 120 people looked at the game's page on 'freecode.com'. 20 of the people then visited the game's own site. (The game simulates the 15,000 players)
I could not get an entry into any internet directories for free
I submitted an entry to the Open Directory Project but it did not appear. Maybe there are not enough volunteer reviewers.
the Bing search engine seems to take its entries from the 'README' file in the downloads page of your project on Sourceforge
I had put details of the last release in the 'README' file
putting too many keywords in the web page title may confuse the user, may not help the ranking of the page by search engines, and may look ugly
I had: 'Free British Bingo, play against the computer, JavaScript'. It is now: 'British Bingo'.
it is easy to forget that Google looks for high quality links to your site and places less importance on the content of your pages
it took about 2 months for my website to appear in the results of search engines despite considerable efforts
This is what some experts say, but I did not believe them
I did not find the 'webmaster' tools of Google and Bing useful
It was only just possible to prove I owned the my web site as it is within Sourceforge. I added an 'id' file generated by the search engines as an attachment to my home page.
I used a 'sitemap.xml' file to get the search engines to look at my 'tips' document but I cannot find the document in the search engine results.
Yahoo uses the Bing 'webmaster' tools. I think the Yahoo search engine may now be Bing
maybe create a good website
I have noticed that the reviews of Linux distributions on the 'distrowatch.com' website usually comment on the quality of the website of the distro.
I read a good book that suggested going beyond the merely functional and adding a bit of style to your website.
On Sourceforge you cannot use your own stylesheets, but you can use the '
style' attribute of HTML elements to add colour or set the
font size/style/font-weight and so on. You can also add your own HTML tables
click on links to your website, visit your entries in web directories and visit your articles and forum posts
It seems like cheating but it helps
here are some ideas for getting publicity:
I announce new versions:
on the project's Sourceforge blog, with a title of 'Release Notes'
by updating my 'PAD' entry on the appvisor.com website
I added 2 lists of tips to a JavaScript forum on the 'Sitepoint' website
I wrote an article of JavaScript tips for the 'ezinearticles.com' website. The Sitepoint website would not publish it
One or two people read it each week and half of them then visit the game's website
I submitted details of the game to sites that have free scripts to download
we emailed (or filled in contact forms for):
Linux distributions and Linux gaming distributions
old people's magazines and magazines related to the author's health problem. We found some of the magazines in the library. Most were local magazines
selected PC magazines and computer gaming magazines, trying to avoid sending more than one email to the same publisher
older women's magazines, men's gadget magazines and puzzle magazines, again trying to avoid mailing the same publisher twice
national newspapers
web sites which review bingo sites
web sites which appear when you google "free games"
these sites really have Flash games and games for mobile phones. They seem mainly aimed at young men
web sites that are listed when you google "bingo expert"
"social gaming" companies such as Zynga
bingo sites
one library I use blocks out bingo sites but another library does not
We found the magazines in bookshops and supermarkets
These emails generated almost no visits. The only good results were from a local support group and a national charity, both related to the author's health problem. They may have been a few visits from bingo sites. I think magazines must receive a lot of emails
I put some adverts on 'free ads' web sites. Some were rejected because they had a link to the game's website or because the game is free. I now say 'look for "british bingo" on sourceforge.com' rather than use a link
the Bing search engine seems to take its entries from the 'README' file in the downloads page of your project on Sourceforge
releasing often helps to draw attention to your project
people recommend you write a release note or press release in three parts:
a short summary of the changes. Perhaps less than 140 characters so it can be tweeted
a brief description of your project, as the release note will be read away from you website
a list of your changes, giving lots of detail
Try to write sentences. Be consistent in using either English or American English, for example 'colour' or 'color'
I start afresh when writing the release note each time and highlight different aspects of my game
I once forgot to include a link to my website and another time I forgot to say the game was free
the 'sitepoint' forum did not allow me to post a general announcement when I registered. But after six months and two posts it did. Over 350 people read my announcement
writing this list of tips gave me plenty of material for articles
I originally meant to write an article for the 'Linux Gazette', but it stopped
a graph of the frequency of downloads of the game shows regular peaks when a new release comes out, quickly falling after
It looks a bit like a heartbeat.
The challenge seems to be to get more downloads in the lean periods
it is easier to write the release notes as you make the changes
websites with 'free games' have mostly Flash and mobile games, which are perhaps targeted at young men
do not get upset if you get some unfair criticism of your work
Just ignore it. Dismiss them a 'troll's
you may have to be happy with a small number of active users
About 15 people download each release. A book I read said blogging was the same. I still find it very satisfying that someone plays the game
I wonder if when web directories say lots of people have looked at your entry that they really mean that a page with many entries including yours has been visited a lot
my website actually appeared on the first page of a Google search for "british bingo", but only when I had almost given up on marketing the game and had gone back to writing the code
at the start, I put details of the game on lots of download sites. I don't now.
Some of the download sites later had unsavoury ads or were blocked from the PC's in the library
I find it useful to keep a record of who I contact so I do not do it twice
I read that someone at Google ranks the online gambling websites manually as some sites are scams
Now, I only contact people if I come across someone who might be interested in the game when I am reading a newspaper or magazine, or when I am browing the web
Someone said my entry in the software directory of the Free Software Foundation was 'spam' and Sourceforge deleted my project
When Sourceforge restored my project, all the pages in the wiki were gone. I had not made backup copies
you can find out from Google which websites link to or mention your website by searching for '
info:' followed by your website address
I found an old report on 'appvisor.com' that lists about a thousand download sites
I tried to submit my game to them. Many of the sites were not working.
This did not lead to an increase in downloads of my game
I change the '
title' tag of the online version of my game to suit search engines
The '
title' tag of the version for download is:
British Bingo
Whereas the online version has:
Bingo: free 90-ball game in browser with sound - play by yourself
The first 65 characters may be the most important. You can use dividers such as '
:', '
-', '
>' and '
|'. Remember to include lots of keywords
I created XML Sitemap files for the directories of the online versions of my game
I wanted search engines to crawl pages they seemed to be missing. I could also suggest the frequency at which the pages changed.
Even now, google only has about half the entries in my Sitemap file in its index.
Bing had not looked at my Sitemap file, a week after I submitted it
I changed the anchor text of one link to help search engines
There were two links: one was '
play online', the other next door was '
also'. Now both are '
play online'. It seems anchor text is quite important to search engines
I found three good chapters in the old first edition of the book 'The Art of SEO' by Eric Enge and others
The good chapters are: 'Keyword Research', 'Developing an SEO-Friendly Website', and 'Creating Link-Worthy Content and Link Marketing'.
I borrowed the book from my local library. I saw a free copy of the second edition on the web
the 'Webmaster Tools' of google will not let me target my website at Britain because the '
.pn' domain used by 'freehostingeu.com' is for the Pitcairn Islands
the '
meta keywords' tag is not used much by search engines
the text in anchors for links is important for search engines
I added an entry for a favourite image to my '
sitemap.xml' file
But google did not add the image to its index
Bing does not seem to recognise 'structured data' in 'JSON-LD' format
So I use the Microdata format
adding 'structured data' in 'JSON-LD' format makes Internet Explorer ask if you want to run scripts
So I use the Microdata format for pages without JavaScript
you can use the '
site:' operator with google and Bing to see what is in their indexes for a web site
you can use the '
meta' tag with Microdata to add data that is not visible on the page
I added some graphs to the 'Flickr' photo-sharing website
Maybe someone will stumble upon the graphs and follow the links
I do not think google follows the links
I have some Microdata common to my web pages. But if I do not reference part of the Microdata with an '
itemref' then extra entities appear at the top level of the page
it seems you can repeat any property in Microdata
But this might confuse Google's search in some cases
adding Microdata takes a lot of time
adding Microdata is a bit like programming and so maybe gives programmers an advantage in 'search'' over marketing people who focus on getting links and advertising
When I added Microdata, I got six times as many visitors to my website as normal, but this soon dropped off. Maybe the increase in visitors was for another reason such as a good review
Google search has its own rules for Microdata
But where Google has extra rules then maybe this means Google is going to use that part of Microdata
In particular, I understand Google search may show a 'rich card' in its results for your '
Organization' entity
I used '
itemref' in Microdata to define the properties of a '
Person' once and include the properties many times for '
author', '
publisher', '
funder' and so on
you can give some text instead of an object in Microdata and you will get an object with the '
name' property set to the text
it seems a good idea to give as many properties in Microdata as you reasonably can
you can use subtypes of entities in Microdata to give more detail
I use the subtypes: '
WebApplication', '
WebPage', '
ScholarlyArticle', '
TechArticle' and '
Dataset'. These are subtypes of '
the '
mainEntityOfPage' property in Microdata says that the entity that has this property is the 'main entity' for the given page
There is detailed information about the related properties '
sameAs', '
about', and '
url' on the 'schema.org' website, but I found this difficult to follow
the 'schema.org' website says every webpage is implicitly a '
WebPage' entity in Microdata, but Google's structured-data testing tool does not show this
So I gave a top-level '
div' HTML element '
itemscope' with an '
itemtype' of '
WebPage'. This '
div' contained most of the page
there is a page showing the hiearchy of the types of entities in Microdata at: 'schema.org/docs/schemas.html'.
you can specify several referenced items in an '
itemref' in Microdata - separate each with a space
I find the 'JSON-LD' examples in the 'schema.org' website easier to understand than the Microdata examples
I am going to write some more blogs on Sourceforge
Google search showed an old blog when I searched for '
javascript tips beckwith'
a screenshot of my game on 'libregamewiki.org' comes quite high in google's rankings
Google ranks a link to my game from 'libregamewiki.org' higher than download sites that have taken the 'PAD' file
I have read that Google's search slightly prefers JSON-LD over Microdata
Google only adds 'rich cards' to its search results for a small number of entities such as '
The Microdata has to be top quality and you may have to wait af few weeks.
Google can use other Microdata to understand a page
if you want multiple values for a property with JSON-LD then you put the values in an array
With Microdata you repeat the property
I have read that Google search no longer minds if you add Microdata with '
meta' tags outside of the visible content
one way of describing a web page with Microdata is to have a '
WebPage' entity with a '
mainEntity' property describing the main topic of the page
So the Microdata for these tips in JSON-LD looks like:
"@context" : "https://schema.org",
"@type" : "WebPage",
"significantLink" : "http://www.sourceforge.net/p/britbingo",
"mainEntity" : {
"@type" : "TechArticle",
it really is a good idea to test regularly on Internet Explorer if you are developing on another browser. Also test any clever feature on IE before going ahead.
Where there is a difference, IE is surprisingly sometimes right according to the standards. IE has a debugger, so you can easily find any problems. IE also has a simple profiler which counts and times when functions are executed
I started off writing debug information at the bottom of the page. But after a while I did not look at it much and just added alerts showing the values of variables.
I realised too late that it is best to use a common function to write out debug trace information.
When there is a lot of debug information, the code I use becomes very slow in my browser. For example,
if (debug) { dbg.innerHTML += fname + '(): loop: ' +
numbersInOrderIndex + '<br/>'; }
Maybe this is because a fresh copy of the debug listing is made each time something is added and the browser reformats the whole listing each time. It might be better to create a new text node each time and append it to the debug area
I wish I had used a common function to show errors and used more user-friendly messages.
Unfortunately, I just coded in alerts with quite technical messages like:
alert(fname + '(): bad how: ' + howElementHidden);
it turned out to be a good idea to keep details of the players' boards in JavaScript data structures away from the boards' visual representation as HTML
Maybe this is a bit like the Model View Controller (MVC) idea for Graphical User Interfaces
there is lots of help on the web but it helps if you search for a specific JavaScript feature
I like the tutorials on the 'quirksmode' website
I find articles by Douglas Crockford are particularly good for indepth explanations
JavaScript really is not much like Java. JavaScript is rather like 'C' and does the usual 'C' things with constructs like:
while ((c = getchar()) != EOF) {}
Like 'C', JavaScript is a small language and it is easy to understand all of it, unlike 'C++'. JavaScript has some tricky features like prototypes just like 'C' has pointers
almost all my errors are typing mistakes
The first is a bit old and maybe not on the web anymore. I use them because I work offline without an Internet connection and they can be downloaded
you don't need a fancy editor or debugger.
I used '
vi' and relied on brief error messages saying which line the problem was on.
(In fact my browser, Konqueror, does have a debugger but I built my own Linux and I sometimes have a problem with threads which seems to make the debugger lock up)
I now check changes into RCS very frequently as I develop the game, partly in case I make a terrible mistake.
RCS is, of course, a free Unix source control system.
I have stored over 2000 revisions of the game so far!
I also find RCS very useful for lots of others things, such as the website pages, 'minimising' scripts, articles and the 'PAD' file
I find I can still make small changes to the game whilst I test it
I remembered that the point of testing is to find bugs, so I try not to be too disappointed when I find bugs
when testing it may be best to start up your windows and browser afresh and not have anything big running in the background
I had a bug where the game just stopped perhaps because there was not enough memory to start a new thread with the JavaScript '
setTimeout()' function
other applications run faster if I completely close down my browser
it is nice to write animations so that they can be combined
For example, the background might disappear as the foreground text expands
I managed to have a common loop to go through the steps of of each animation
animations that have transparent elements seem quite slower
put a version number somewhere on the web page so you know which version you are testing
I even change the version when I am in the middle of making changes
you can use browser screenshot tools if you cannot test your web pages on other browsers
There is the 'browsershots.org' web site
The 'saucelabs.com' site lets you interact with your web page. This site gives unlimited time to free projects
you can test pages of HTML in the Chrome browser and the latest Internet Explorer browsers by using Sourceforge and 'saucelabs.com'
Make your page an attachment to a Sourceforge page in your project's wiki. Click on the link for the attachment from 'saucelabs'. Then choose a browser from the 'Open with' box at the bottom of the screen
I actually use some of the documentation of the program myself
I often refer to the list of the main functions in the game.
I hardly ever read the detailed descriptions of the processing
the way the game can play itself continously was useful when finding bugs
after a while, I focused on developing the game, and see making releases as a sideline
I used a separate email address for the game that differs from my personal email address
I upload the last items first to the download page on Sourceforge
Sourceforge shows the most recent items first
To get the directories in the right order in the file download area of Sourceforge, I add small files (called 'IGNORE') to the directories
I backup my work by emailing the game to myself
This mean I have many versions saved.
I save the sound files in the file storage area of 'GMX' mail. There seems to be a limit to the size of email attachments of about 50 megabytes
I make notes on till receipts as I walk along or on the bus
I organise them in an old envelopes
I use Sourceforge rather than Google because Google seemed more for several people working on a project
Use HTML to format Sourceforge pages
I used Sourceforge's own formatting and then some of it stopped working
I don't stop developing when I do the final testing for a release
I branch the code. I find testing boring
when I started I released some versions that were not fully tested as 'unstable' releases. I do not now
it seems best to test each path through the code rather than just playing the game a lot
sometimes I think the game is ignoring my clicks on an HTML button when an alert box is shown
I found 2 websites that would host my game for free: '000webhost.com' and 'freehostingeu.com'
Then it was easy to test my game in different browsers using 'saucelabs.com' which is free to Open Source projects.
Several other websites offering free hosting did not seem to completely work.
Several other websites seem to force you to use their website templates or website creation tools.
000webhost.com ' had my game 'under review' for several weeks until I raised a ticket with their helpdesk.
'freehostingeu.com' was unavailable for a few days asking for a login
After a year, 000webhost.com now sometimes shows ads for its paid website hosting. These ads disappeared when I used the 'remove inactivity ads' option in the control panel
000webhost.com adds a call to a script at the bottom of uploaded HTML files. I think this script show the adverts. The script seems to give an error on Internet Explorer 8. The script defines '$' which clashed with mine
freehostingeu.com will not serve a page that contains 'bad' words
With 000webhost.com you can upload files as zip archives which are then automatically unzipped. 000webhost.com' does not seem to correctly handle my 'gzip' files
Internet Explorer 8 in my local library did not work with the new menus used by 'freehostingeu.com' at the end of 2013. The menus work fine now
I get round this by using a session at 'saucelabs.com'
I would add a comment at the top of each function if I was writing the game again
I would not comment the parameters of functions.
To understand the code when I amend the code, I look at the code and put in '
alerts'. I do not look at the documentation much
I find it best to review afterwards any code I write late at night or early in the morning
getting the shadows under the boards right was quite difficult
the log files produced when my browser crashed almost filled up my disk
no-one reported any bugs and no-one posted any messages to the forums I set up on Sourceforge
I find it easier not to set a date for a new release but instead concentrate on the steps needed to get there
when testing, I try to find bugs rather than just confirming the program works
testing seems a good time to start developing new features when there is no pressure
when I make a change, I usually look for a similar bit of code in the program to copy
I turn off the spam filter on my mail account so I can get confirmations when I register for services on websites
the way I do 'responsive design' is to develop and test on an old browser and then add features for new browsers
I have a saying: 'if it is easy then it is not worth doing'
the changes I make first are the ones I think people will notice most
on most Android devices, phones have the words '
android' and '
mobile' in the 'user agent string' sent by their browsers whereas tablets have '
android' but not '
you need to test on a real iPad as well as a simulator
I test the game on the iPads at the local Apple store
my 'minimising' scripts create a file 10% smaller than the Google Closure Compiler
But my scripts take 45 minutes to run. The Closure Compiler takes less than a minute
Internet Explorer 11 does not have '
MSIE' in its 'user agent' string.
It has '
Trident/7.0; rv 11.0' instead
I find that I do more if I think about it on the bus and then spend a couple of hours in the evening on it, rather than spending most of a Saturday or Sunday on it
you can click anywhere at the top of a 'select list' not just on the arrow on the right
only a few hosting providers seem to be free and show no ads
Some of the registration pages do not seem to work or are similar to others.
You may get a more reliable service if you show some ads
I work on a copy of the game with lots of
alerts which I remove when I make a release
Internet Explorer adds the word '
Touch' to the 'user agent' string on a touch-screen running Windows 8 or later
An example 'user agent' string is:
Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0; Touch) like Gecko
when testing with Internet Explorer on Windows 8 with the saucelabs cross-browser testing tool, the 'user agent' string does not contain the word '
Touch', maybe because it is running on Windows Server
one way to make web pages look nice on Internet Explorer 8 is to use gradients generated by Microsoft visual filters
I try to code the hard but better way rather than the easy but not so good way
I look through the code after it has been 'minimised' to see if I can make it smaller
This takes about an hour
if you have variables with similar names, then it makes the 'minimising' harder
For example,
var name;
var nameValue;
you can see what your page first looks like better with the saucelabs cross-browser testing tool if you reload the page after it is first shown
I find it best to only do testing for one hour at a time
to put an app on the Apple iOS App store you have to pay $99 a year to join Apple's developer program
I observe how people sitting in front of me on the bus use their tablets and phones
I test the game on Android (and other) tablets at my local PCWorld store
I also test on touch-screen Windows 8 computers there
my game looks better on a real Android tablet rather than than a simulator
On the simulator, the words of the introduction are put in a narrow column rather than using the full width of the page
you need to plan for the developers being ill
I fell ill just before a release
you can roughly simulate a tablet on a PC by reducing the font size in the browser (or 'zoom-out') and narrowing the window
I think there are always bugs with most programs
I use the '
bc' program on Linux to convert colors to hexadecimal
You say '
when I developed the game, I wrote scripts to shorten names in the code. Now I also just add to a list of substitutions
it is good to include a lot of detail in your release notes
This is what people recommend. It also reminds you what you have done
I find it useful to do lots of testing when I am developing rather than waiting until before I release a new version
when I 'google' for a technical problem, I look for the results from the 'stackoverflow' website and the 'Mozilla Developers Network' website
if you make up CSS rule names in JavaScript from a root part and an index part on the end, then this may cause problems when you 'minimise' the code
For example, if '
repeatFade1' and '
repeatFade2' are 'minimised' to different names like '
fhd434' and '
it may be best to code a break out of any infinite loop after too many iterations
I had a bug and I could not tell if the browser had hung repainting the screen or if my script was in an infinite loop
the saucelabs cross-browser testing tool makes light grey elements seem almost invisible
my Konqueror browser takes a long time to load a page if I have loaded the page a lot
My browser takes up most of the free memory on my old computer.
I have read that browsers leak memory
to take a screenshot on Windows XP, press 'Ctrl+PrintScreen' and then paste the screenshot into Windows Paint
the output of one of my '
sed' scripts, that I use in 'minimising' the game, was mixed up when the disk was nearly full
Tucows, the download site, took 3 months to review my game and then rejected my game, saying the file extension was wrong ('bbingo.html.zip')
Tucows really wants you to pay them (at least $60) to review your program
'freecode.com' have frozen their website (as of July 2014)
constantly changing elements of a page can be just as attractive as shadows or gradients
For example, in my game I highlight the numbers on the boards of players as the numbers are mentioned
when I produce new versions every month, a lot of my time is spent testing and minimising (one or two weeks)
the Free Software Foundation says that JavaScript code that is minimised is not Free unless the JavaScript says where the source code can be found
The Free Software Foundation suggests using a '
@source: url' documentation tag
the Free Software Foundation have a short version of the GNU General Public license (GNU GPL) suitable for JavaScript
Normally you have to include a copy of the GNU GPLwith your code
when maintaining code I find it best to treat the original code with respect
on 000webhost.com, zip files are corrupted when I upload them with the 'other', windows-like, file manager
one public library I use, blocks you from using the 'net76.net' domain provided by 000webhost.com
the early hours of the morning are a good time to program, as it is quiet
But it can be cold
releasing a new version is just another step in developing, with problems and bugs to overcome (maybe with the hosting websites)
'000webhost.com' removes my large (4 megabyte) HTML files after a day or two. 'byethost.com' does the same and will not serve them. 'freehostingeu.com' will not let me upload large HTML files
I read that Chrome on an iPad uses the Safari renderer
a game is more enjoyable if you can win
Playing bingo with a few players is better than playing with lots of players
if you use the GNU General Public license (GNU GPL) for a JavaScript library then it may mean that anyone using the library has to open source their code too
my 'secret weapon' when developing is taking a break and visiting a relative (who plays bingo)
changing the 'text size' or 'font size' on browsers does not change the size of buttons or input fields whereas using the 'zoom' option does
to get to the settings in Chrome, click on the icon in the top-right corner showing 3 small horizontal bars on top of each other
On Firefox, clicking on these bars shows a menu with an 'Options' entry
On Internet Explorer 11, clicking on the cog in the top-right corner shows a 'Tools' menu
I still make changes, if they take no more than an evening, when I test before releasing a new version
But sometimes I continue into the early morning
on an iPad, a swipe does not fire the '
onclick' event
copy and paste the words on the screen when you get an error or save a screenshot
double your estimates of how long things will take
I used to make small changes to the 'minimised' version. Now I think it is best to do the 'minimising' every time I make a change
re-writing code a different way is another way to fix or reveal bugs that are hard to find
my game very occasionally hangs on my old brower and has once hung on Internet Explorer 11
remember to play your game a lot if you are developing a game
remember to leave room for the image of the cursor if you are drawing a tip near the position of the mouse pointer
adding a light border to a region of light color makes the shape of the region stand out
I do the final testing half an hour at a time, with a longer break after an hour
you can get ideas for future developments when testing as well as finding bugs
when I am tired of testing, I get up and open the window or something, then come back and do some more testing
I try to test not too much and not too little
I release a new version after 2 or 3 days of testing without finding a bug
sometimes it is easier to make a small change than it is to think about the change
when I have done the final testing, I try to go live as quickly as possible
once when I tried to upload a new version to Sourceforge, I found that the developer tools were unavailable for a few days due to a storage problem
The upload option was unavailable for 2 weeks
reqularly quiting my editor ('vi') seems to save memory
my game looks best in Internet Explorer if I use a lot of shadows, color gradients and rounded corners
I get a few visitors to my Facebook page
I do not promote the page, so this is great
I use a 'minimalist' window manager, 'aewm', on Linux to save memory
I cannot upload an HTML file of just under a megabyte to 'byethost.com'
I cannot login securely as browsers on Windows7 do not trust the certificate
I try to do changes together that relate to the same part of the code
when I change code, I comment out the original code rather than removing the original code
I remove the commented-out code just before I make a release
'upload.com' seems a good download site
It is part of 'CNet'
changes often take an evening to code, but a week to test, improve and get right
sometimes '000webhost.com' is slow to respond, so I search for '000webhost' and go straight to the login page for members
the book 'Effective JavaScript' by David Herman is a good intermediate book
I borrowed it from a local library
I look in the catalogue at my local library for books and reserve books from other libraries in the area which are then transferred to my library
I change colors in 'rgb' format to hexadecimal format to shorten the code a little
I use this Perl code:
when doing the final testing, I find it is a good time to learn more about JavaScript
when doing the final testing, I find I can still make small improvements to the code and minimising (minifying) scripts
I browse my free websites once a week to stop the hosting providers thinking they are unused
I change some colors in my CSS which are given as six hexadecimal digits to three hexadecimal digits to shorten the code a little
For example, '
#ffffff' becomes '
This shorthand is in the CSS specification. However it seems Internet Explorer 3 for Macs supported stylesheets but not the shorthand. Internet Explorer 3 dates from the later 1990's and probably would not run the JavaScript used in my game
Some browsers do not support three digit hexadecimal colors as shorthand in HTML such as when specifying the '
bgcolor' of an element. This is because this shorthand is not in the HTML specification
Three digit hexadecimal colors may not be supported in the '
filter' style attributes of Internet Explorer
you can shorten your code by leaving off leading zeroes in decimals
For example, write '
.5' not '
But JSHint complains saying a dot could be confused with the dot between an object and a property
there are free copies of old technical books on the web in PDF format
They are not usually the latest editions.
I can find old O'Reilly books this way - sometimes new ones too.
I just search with 'google'
I got a piece of malware from one download site. It may be best just to follow direct links to PDF files
Smashing Magazine is a website and newsletter with articles about advanced topics in web development
Google Charts is a JavaScript API to create charts and graphs
I put the identification strings of the version control system (e.g. '
$Date$') in a string variable rather than in the comments as the comments are removed when the code is 'minimised'
you can put out a release in parts with maybe the essential code first and then the supporting documentation a day or two later
I find it is good to continue developing when testing the last change
Maybe I test better this way
'JavaScript: the Good Parts' by Douglas Crockford is a good book
It is short but old. There are free copies on the web.
the 'w' key on my old keyboard does not always work, so I use '
xmodmap' in 'X Windows' to use the '#' key for 'w' with:
xmodmap -e 'keysym numbersign = w W'
xmodmap -e 'keysym F1 = asciitilde'
xmodmap -e 'keysym F2 = numbersign'
'gnuplot' draws good 3D graphs
'Eloquent JavaScript' is a good book
I particularly liked the example projects
on '000webhost.com', I cannot login through the home page. Instead I search for '000webhost' and choose the 'members' or 'login' page from the results
'000webhost.com' does not seem to serve files with a '
.txt' extension
'000webhost.com' handles '
.csv' files all right
'000webhost.com' claims '99.9%' uptime but a comment on their forum says they may say downtime is planned maintenance
My website was not available for several days
it really is best to put images in a sub-directory on the server
'HTML Utopia: Designing Without Tables Using CSS' by Rachel Andrew and Dan Shafer is a good old book
I borrowed it from my local library but you might find it free online
I remember the version of the source used for a release by making a RCS mark with '
rcs -n'
if you are happy to make a release that is not quite perfect then you can make it a lot quicker
I tried not stopping developing whilst doing the final testing for a release. This worked quiet well
I did half an hour of testing at the end of the evening.
I developed some Microdata which did not affect the game
I created a 'beta' version before a release, but not many people downloaded it
one thing I learnt from using Microdata, is to give every web page a version
both Google search and Bing prefer my website at 'bbingo.eu5.net' (with 'freehostingeu.com') over the duplicate at 'bbingo.net76.net' (with '000webhost.com')
This is despite the fact that 'bbingo.eu5.net' is slow to respond.
I have duplicate websites in case one is not working
I test on iPads at my local Apple store
I go when it is busy, at weekends and bank-holidays. The staff do not pay much attention to me when it is busy
Internet Explorer only asks if you want to 'run scripts' if the page is on your computer
If the page is on the web then Internet Explorer does not ask
one day, I could not access my free website at '000webhost.com'. I had to change domains.
'000webhost.com' said I could use 'ftp' to download the files from the old domain and to upload files to the new domain. But 'ftp' is hard to use on the library computers I use for internet access. So I had to find the files on my computer at home and upload them. I could upload up to 20 files at a time when using the file dialog
I read a book about 'agile' projects. Am I 'agile'?
I focus on programming. I try to spend the least time on marketing, testing and releasing new versions
I sometimes program late into the night. 'Agile' projects try to work 35 hour weeks to stay fresh
I do not have automated testing. I test by playing my game a little every day. I get ideas for improvements
I do not 'refactor' code. I try to respect old code. There may be a reason for the way it works
I do not always work on the most important things. I can be more effective by working on related items. I can work on unimportant things that add depth. I can have some fun by working on things that interest me
I have a feature that I work on when I am waiting on something for the current change. 'Agile' programmers do one thing at a time
I write notes on pieces of waste card like the low-tech post-it notes and index cards that 'agile' developers use
I only spend a few hours a day programming. I do not spend the whole weekend programming. I have kept going for about seven years. This is like the sustainable 35 hour weeks that 'agile' teams aim for
I try to break developing into small steps that I can do in an evening. I try to leave the game in a working state overnight. 'Agile' developers do tasks that can be done in one day
I try to be polite and accomodating with Sourceforge and the free hosting sites that I use. They may be unavailable for a few days or block my content, but I try to remember that they are free. 'Agile' teams try to collaborate with external suppliers
sometimes I may start working on another feature before I finish the final testing of what I am currently working on. For example, I may want to do the final testing in the library where I can use Windows browsers and have internet access
The book is 'Agile Project Management for Dummies' by Mark C. Layton. I got the book from my local library
I do not look at my TODO list much
The list slowly grows in size. I do related things or rely on my memory. I include the TODO list with the source on Sourceforge
the 'YUI Compressor' is a 'safe' minifier that does not change your code much
It shortens local variable names.
It shortens my JavaScript by 22% compared to 27% for 'UglifyJS'.
This is over and above my own minimising and using 'JSMin'
the book '97 Things Every Programmer Should Know' is worth reading
You can read it for free online
I read 'Getting Real' by 37signals. Am I 'real'?
I changed my game to use curly quotes for speech. You would not notice the change. 37signals suggest being 'passionate' about your project
I tend to say 'we' when there is just me developing. But 37signals suggest being straight with your customers about your size
the W3C link checker points out links that have been 'redirected' and advises you to update the links
I had to change the free '
eu.pn' website domain I used at 'freehostingeu.com'
The Pitcairn Islands said the '
eu.pn' domain was harming their reputation.
I changed right away to '
mygamesonline.org'. I later changed to the shorter '
using a free hosting provider such as '000webhost.com' is not perfect
My game loads sounds in real time across the web. With 000webhost.com' there are sometimes delays or errors such as not finding a file or getting an incomplete file
you must not panic when using a free hosting provider
I got a strange screen from '000webhost.com' part of which said I had exceeded my limit and had to upgrade. So I rashly upgraded to a paid account. Luckily, my debit card was declined. In fact, '000webhost.com' was not working properly and I could continue with my free account
sometimes when I upload a file to '000webhost.com' there is a delay of over ten minutes before the file appears on the web server
I write notes on bits from cornflake boxes
But ink smudges on the glossy outside
you can refer to a webpage as a subdirectory on the web server if you put the page in the directory and call the page '
releasing a 'beta' version breaks a release into smaller steps, reducing stress and leaving something if I die
I will try an 'alpha' release.
Nobody downloaded my last 'beta' though
doing a release over several days lets you be more careful and fix mistakes
You can have a good look at your entry at the download website before uploading the entry
I do a bit of testing most days in the library. I develop at home
This is a bit like running automated tests overnight
Microsoft Excel is good at drawing pie charts. Gnuplot is better at 3D charts
Excel uses a constant scale for the 'depth' or 'z' axis: one stop for each row of data
it is a good idea to read through your posts twice before sending
Check URL's in a browser, write a draft first, and do not forget to publish the draft
email messages from download and listings websites seem to go to the 'spam' folder of my 'gmx' mail account
I sometimes run out of memory and swap space on my old computer running Linux
I use the following to add more swap space:
dd if=/dev/zero of=swap1 bs=1024 count=100k
mkswap swap1
swapon swap1
Do not forget to run '
swapoff' before shutting down Linux
I create 'sprites' from GIF's from 'animatedImages.org'
I separate the images using the 'layers' tool of 'GIMP'. I drag the images to new images. I use 'GIMP' to create a blank sprite. I use the '
combine' program from 'ImageMagick' to position the individual images on the sprite
on 'Flickr', you can update an image by replacing it
're-factoring' may be where you produce a quick prototype and then later go back and tidy up the code
doing some programming can take your mind off your worries
if you work on a game for 10 years in your spare time, maybe you get the same result as a small team working for 1 year full-time