Set character-set early in HTML
I set the 'character set' as soon as possible in my web pages
I had a comment before the line:
The browser would find this line and go back to the top of the page and go through the comment again
What I learnt writing a bingo game.
I set the 'character set' as soon as possible in my web pages
I had a comment before the line:
The browser would find this line and go back to the top of the page and go through the comment again
I started by using an online HTML minifier at:
toptal.com/developers/html-minifier
This minifier squashes up spaces and removes unnecessary quotes around attribute names. However, this minifier gives an error with my 'tips' page which is quite long with lots of HTML elements.
The online minifier ranked highest by Google removes whitespace that is significant and thus changes the layout of my page. This minifier is at:
One way other minifiers give smaller output is by changing HTML entities to single UTF-8 characters. These characters appeared as weird characters until I saved the minified HTML with 'Notepad' with 'Save as' with the 'encoding' as 'UTF-8'.
I then tried the minifier at:
I noticed that this minifier also leaves out closing '</p>
' tags for paragraphs. This causes my 15-year old browser to incorrectly show spacing between lines. However, this works fine on modern browsers. It seems closing tags are not needed for many tags, but screen readers may get confused and Google may rank the page less highly.
I found that this minifier gives an error with my long 'tips' page saying the HTML is not valid. But the 'w3.org' HTML validator does not find any errors on my 'tips' page. So I changed to using the minifier at:
This minifier gives a similar reduction in size as the minifier at '10015.io'.
Using an online HTML minifier adds another step to minifying a web page. I have to go to a public library to use an online minifier as I do not have Internet access at home. My Linux system is also a bit old to run a minifier at home
Adding an 'inert
' attribute to the document body does not seem to speed up animations
The 'inert
' attributes stops any interaction from the user.
I thought animations started from 'view transitions' looked faster. I noticed these transitions stop all user interaction.
In fact, adding 'inert
' does not seem to make much difference.
My old page transitions using regular CSS animations look jerky on old computers. Maybe it is the complex HTML that slows them down
I realised you can do a reflection along the 'x' axix with a 'transform
' of 'scale(-1,1)
'
I was going to rotate the element 180 degrees around the 'z' axis. This might involve more complex 'sine' and 'cosine' functions
I sometimes change ':before' and ':after' pseudo elements to 'div' elements so I can reference them by 'id' in JavaScript
For example, I am adapting a CSS icon for 'Github' that uses ':before' and ':after'.
I usually add an inner 'div' container element which has a 'position' of 'relative' and a 'width' and 'height' of '100%'. I put the ':before' and ':after' elements inside this container with a position of 'absolute'.
But if the 'Github' icon is very small then the ':before' and ':after' elements are too far down. So instead, I set a parent element of the ':before' and ':after' elments to have a 'position' of relative'. The icon uses 'em' sizes and I reduce the size by setting the 'font-size'
I have been changing the text label of links to have words rather than 'bare' URL's
It seems screen-readers 'say' each character in the URL.
I have a lot of links to 'openclipart.org' on my 'credits' page. The text labels of the links were all bare URL's. But these bare URL's describe the 'SVG'. I will have to add more words to the text label of the links to make each description unique. In fact, content on 'openclipart.org' is in the 'public domain' and does not need attribution.
Also I found out that the symbols for links to Facebook, X, LinkedIn and so on on the first page of my game are too small for some disabilities. Instead I could have used words like 'Facebook'.
Also a long link might be better than the big fat links I use for mobiles
I have started using the 'CSSO' CSS minifier
It only reduces the size of my game by 2%. I already used shell and Perl scripts to remove comments and remove some spaces. 'CSSO' additionally removes spaces around '{' and '}' and removes semi-colons after the last property in a rule. Sometimes 'CSSO' combines similar rules and combines properties into a 'shorthand' rule.
CSS makes up about 20% of my game. (JavaScripts makes up about 65%). This is after my game is minimised.
The size of the CSS is halved when minimised. The minified JavaScript is about 15% of the original size. JavaScript variable names can be shortened but CSS property names cannot be easily shortened. I remove some vendor-prefixed properties.
'CSSO' wrongly changes a small stylesheet to nothing. The stylesheet is:
#navigationSettings {
display: block;
}
I had to hide some empty CSS rules from 'CSSO' as it removes them. These rules have properties set in JavaScript.
The online 'playground' of the rival minifier 'cssnano' does not seem to work on the old browsers in my local libraries
I use the Linux 'fold' to look through minimised code
I say: 'fold -s -w120'fold -s -w120
I have been adapting an animation of fish circling as in a bowl with bubbles rising in the middle
The original is by Yusuke Nakaya. See:
'codepen.io/YusukeNakaya/pen/WNopRwX'
The fish are made of CSS triangles:
.pfshFish-body .pfshScale {
width: 0;
height: 0;
border-width: 0 0 3.125em 6.25em;
@keyframes fishColor {
0% {
border-color: transparent transparent #6C99C6 transparent;
The triangles are reflected around the 'x' and 'y' axes to make one side of the body of the fish:
.pfshFish-body .pfshScale.-pfshTop.-pfshFront {
transform: scale(1, 1) skewX(4.5deg) rotateY(-11deg) rotateX(23deg)
translate(0.09375em, 0.15625em);
}
.pfshFish-body .pfshScale.-pfshTop.-pfshBack {
transform: scale(-1, 1) skewX(4.5deg) rotateY(-11deg) rotateX(23deg)
translate(0.09375em, 0.15625em);
}
.pfshFish-body .pfshScale.-pfshBottom.-pfshFront {
transform: scale(1, -1) skewX(4.5deg) rotateY(-11deg) rotateX(23deg)
translate(0.09375em, 0.15625em);
}
.pfshFish-body .pfshScale.-pfshBottom.-pfshBack {
transform: scale(-1, -1) skewX(4.5deg) rotateY(-11deg) rotateX(23deg)
translate(0.09375em, 0.15625em);
}
The 'scale(-1, -1)
' does the reflection.
In the above, the triangles are rotated a little around the 'y' axis to make the body fatter in the middle.
The triangles are also reflected around the 'z' axis to make the other side of the body of the fish:
.pfshFish-body > .pfshHalf.pfshRight {
transform: scaleZ(-1) translateZ(-1px);
}
There is an animation that explains CSS triangles at:
'css-tricks.com/animation-css-triangles-work/'
CSS triangles are also use for the tail:
.pfshFish-tail > .pfshScale {
width: 0;
height: 0;
border-width: 0 0 2.5em 1.875em;
}
@keyframes fishColor {
0% {
border-color: transparent transparent #6C99C6 transparent;
.pfshFish-tail > .pfshScale.-pfshTop {
transform: scale(-1, 1);
}
.pfshFish-tail > .pfshScale.-pfshBottom {
transform: scale(-1, -1);
}
The bubbles are made with a large border radius
.blowing-bubbles .bubble:nth-child(1) {
border-top: 1px solid #AFD2F7;
border-radius: 100%;
I colored the triangles to see how the animation works. See this at:
'codepen.io/Bert-Beckwith/pen/YPXRMJz'
My final version is at:
'codepen.io/Bert-Beckwith/pen/dPoMaZv'
I use JavaScript to do the random bits rather than use a CSS pre-processor as I may want to run the animation several times with different sizes and colors
Flickr said I had violated their terms of service by having non-photographic content
Another user had reported this.
I had not been using my Flickr account much so I experimented by adding images with captions containing tips and news. The images were drawings from 'openclipart.org'. I also made a gallery of screenshots of my game.
I removed these images. I left some graphs showing probability distributions of getting a 'line' or 'house' in bingo.
I had no more trouble for a few months.
But now, I cannot login. Flickr says my username is not valid. If I use a link to my images, then I get a a '410' HTTP code meaning the content was intentionally removed.
Yahoo! acquired Flickr in 2005. Yahoo! let you store lots of images, and even videos.
In 2018, Yahoo! (now owned by Verizon) sold Flickr to SmugMug. Now Flickr tries to be a community of photographers.
I still have all the same images on Pinterest together with the captions Pinterest only allows short caption, so I have to truncate my tips
Over half of my game is CSS
This is after the game is minified.
Only a third of my game is Javascript when minified.It is hard to shorten the names of properties in the CSS rules. I also have lots of icons made using CSS.
I would like to convert several individual CSS properties to 'shorthand' properties like 'animation'. Some of the CSS minifiers do something like this. But, I have empty CSS rules within which I set styles using JavaScript. The minifiers would remove these empty rules, by default. I also rely on some CSS rules being at the start and in a particular order so I can change the styles easily with JavaScript. Because of this, I only use the CSS minifiers on parts of my CSS. This can be a bit hard to manage.
I decided to remove most CSS properties with vendor prefixes when 'minimising' my game. I use a 'sed' script to do this.
The CSS minifiers do not shorten id and class names. In my other web pages, I used to have a list of names that I would shorten using 'sed'. This included CSS id's and class names. I stopped doing this when I started splitting up the JavaScript into lots of separate files. The JavaScript uses some of these CSS names. I would now have to run 'sed' on all the files. Luckily, my game is all one HTML page. For my game, I run both 'sed' scripts and a CSS minifier. Overall, my game is shrunk from about 14 megabyte to 2.5 megabytes. This reduction is not quite enough, as some free web hosting servies have a 2 megabtye limit on page size.
Manually running CSS, HTML and JavaScript minifiers takes time. I have to run online minifiers through the computers in my local public libraries. I do not have internet access at home. Using the onine minifiers makes it harded to 'move fast and break things' like Facebook's motto.
I created a video demonstration of my game using the gaming part of Windows10
I press the Windows key and 'G' to start and stop the recording.
I put the video on 'youtube.com'
I have been using Chrome's 'view transitions'
I set the 'view-transition-name' property in CSS classes and add (or remove) these CSS classes from the 'document.documentElement' root HTML element.
I can do this when the 'view transition' ends using a promise:
transition =
document.startViewTransition(play);
transition.finished.then(finishViewTransition);
I use a 'do nothing' 'view transition' to animate showing a dialog box without animating the whole page:
::view-transition-old(doNothing),
::view-transition-new(doNothing) {
animation: none;
}
.vtDoNothing {
view-transition-name: doNothing;
}
#confirmBox {
view-transition-name: confirmBoxTable;
}
...
document.documentElement.className += 'vtDoNothing';
I vary the animation in a 'view transition' by creating a 'style' element in JavaScript, then setting the 'innerHTML', and finally adding this 'style' element to the 'head' element of the page.
I use an 'animation delay' to make the 'new' animation follow the 'old' animation rather than crossing. For example:
::view-transition-old(endGame) {
animation: vtFadeOut .5s linear both,
vtZoomIn .5s linear both,
vtSpiralIn .5s linear both;
}
::view-transition-new(endGame) {
animation: vtFadeIn .5s .5s linear both,
vtZoomOut .5s .5s linear both,
vtSpiralOut .5s .5s linear both;
}
I keep the 'view transitions' short because the user cannot interact with the page while a 'view transition' is running. However the page can be changing while the 'view transition' animations are running. I use 'linear' animations so the page does not seem to freeze at the end of the 'view transition'.
The animations in a 'view transition' only happen when the browser has calculated the final state of the page. These calculations happen in the background and are not visible to the user. Before I used the new 'view transitions' API, I would animate away the old page state, then there would be a delay (maybe a blank screen) while the browser calculated the new page state, before I could animate in the new page state. However, in this old way, the user could interact with the page during the animations. If the user wanted to, I could stop the animation and move on. My 'old' page animations seem slow and jerky compared with the new 'view transitions'.
I also turn on a cross-fade when following links between my pages by adding to their stylesheets:
@view-transition {
navigation: auto;
}
I can very quickly add page animations to my game with the new 'view transitions' API. It is easy to use the default 'cross-fade' and, although subtle, it looks very good. I use this when changing tabs in my 'settings' page.
I have been reading a good picture book, 'How the brain works', published by Dorling Kindersley
I realised it will be a long time before Artificial Intelligence (AI) replicates our amazing brains with just numbers.
Our brains have evolved over millions of years and are specifically adapted for humans.
Science does not fully understand how our brains work.
Our feeling of consciousness is partly an illusion.
I suppose AI will be a different kind of intelligence to ours
I found this picture book in my local library
I add short names for frequently used built-in functions, when 'minifying' my game
I use 'sed' to append code like this to the start of my game:
Array.prototype.p=Array.prototype.push
Math.f=Math.floor
document.ce=document.createElement
Node.prototype.ac = Node.prototype.appendChild
var w=window;w.st=w.setTimeout;
I then change the code like this:
sed -e 's/\.push(/.p(/g'
But, I have not found a way of shortening the property 'Node.nextSibling
'
Modifying the DOM may not work in old versions of Internet Explorer.
I get annonyed when I see repeated code when I look through my game's code after I have 'minified' it
I ran UglifyJS twice and got a small further reduction in size.
I now set the 'passes' option of 'UglifyJS' to '3'. This further reduces the size of the JavaScript in my game by 0.5%.
I do not get much reduction in size when I run the 'CSSO' minifier twice or run the HTML minifier at 'jsonformatter.org' twice.
The 'terser' JavaScript minifier is much faster than 'UglifyJS' but produces slightly bigger results with the default options
I use Douglas Crockford's 'JSMin' minifier a lot
I modified it to keep newlines so I can look through the results. You can find it at:
'github.com/Bert-Beckwith/myjsmin'
'jsmin.c' is a small C program that removes JavaScript comments and excess whitespace.
I often comment out old code rather than remove the code, so I use 'JSMin' to look at what is left. Afterwards I say ':g/^$/d' in 'vim' to remove blank lines. I really should just remove the old code and learn to use my source control system better.
I also use 'JSMin' to minify my game, partly so that the input to 'UglifyJS' is smaller. I use an online version of 'UglifyJS' as my Linux system at home is a bit too old to run it. 'JSMin' is small and fast - I can run it in the background whilst playing my game
breaking coding down into small steps can make coding boring
People sometimes say you should break down programming into small steps so as to 'keep it simple'.
I have got into the habit of coding in very small steps because I am often tired in the evenings when I am coding.
I spent several weeks adding an option to the settings page of my game. Previously I might have done the whole thing in one evening.
However, I work on around 7 or 8 improvements to my game at any one time. I use a very old browser at home where I have no connection to the Internet, so I need to visit my local library to test on modern browsers. Also my game takes several minutes to load on my 25-year old Pentium computer.
my game looked strange when I tested it on mobile phones run by 'appetize.io'
There was a thick border around the boards of players. And the game seemed to hang when I pressed a button.
I thought maybe Chrome was adding an outline when an 'input' element got the focus. So I tried setting 'outline: 0
'. This did not fix the problem.
However, when I tested my game on mobile phones at 'browserstack.com' then everything looked fine.
I realised that maybe there was a problem at 'appetize.io'.
However, 'browserstack.com' only gives you one free minute per device. Whereas 'appetize.io' gives you 30 free minutes a month. 'appetize.io' worked fine for tablets.
This was a few months ago. Now my game looks fine on mobiles run by 'appetize.io'
I had a bug when minimising a page containing '<pre>' tags
I was removing whitespace with a shell script saying:
tr '\n' ' ' | tr -s '[:space:]'
But this removes indentation and newlines from inside the '<pre>' tags, which I put around code examples.
Removing whitespace with 'tr
' like this makes some of my pages considerably smaller.
I was using lots of '&nbsp;' entities and '<p>' tags but replaced these with '<pre>' tags as these seemed more correct. The minimising worked fine with the old code.
I now exclude content inside '<pre>' tags when removing excess whitespace, by saying:
sed -e'/<pre>/,/<\/pre>/!s:[ ][ ]*: :g'
Having a '<pre>' and '</pre>' tag on one line confuses the above 'sed
' script, so I first uppercased these tag, by saying:
sed -e's:<pre>\(.*\)</pre>:<PRE>\1</PRE>:'
I have not yet found an easy way to remove newlines as well as spaces outside of '<pre>' tags.
I am now trying out online HTML minifiers
I have been adding screenshots to the manifests of my webpages that are Progressive Web Apps (PWA)
Chrome suggests doing this in the 'Application' panel of the 'developer tools'
However Chrome only shows these screenshots as small 'thumbnail' images when you go to install the PWA.
It seems each set of screenshots shown needs to have the same 'aspect ratio'
I have been removing obvious 'abbr
' tags from my 'tips' page
I had a lot of fun looking up abbreviations but apparently it is bad style as it interrupts the flow of the reader. This can be especially bad for screen readers.
For example, I was showing the abbreviation for 'PC' and '3d'.
I also now only mention an abbreviation once the first time it is appears in a tip rather than repeating the abbreviation in the same tip. I still repeat abbreviations in different tips as someone might be reading just one tip.
I am now removing unnecessary links for websites mentioned in the tips.
When I started writing the tips, I thought the idea of HTML, being 'hyper-text', was to have lots of links. So I added a link for every website, book and organistion that I mentioned. But over time, the number of links grew to be over 500.
Again, the links, being blue and underline, interrupt the flow of the reader.
I thought the page would be more inviting with lots of diferent colours, font styles and font families. For example, as well as underlined blue links, I used italic for technical terms and a 'mono' font for code examples. But again this apparently is bad style.
Also my 'tips' page might rank higher in Google's search with fewer links and abbreviations. The page is very long with over 1000 tips across over 30,000 lines of text. Google's search might also not like all the 'span
' elements that are used to set different font styles and font families.
I remove one link each day and check the result. My 'tips' page on my website gradually improves as I upload a new version with a new tip about once a week
I have been adding 'smooth scrolling' to my pages which have internal links
I add this to my CSS:
:root { scroll-behavior: smooth; }
The browser now shows moving through the page to get to the link.
This even works on Firefox and on the old Chrome for Windows7.
Sometimes the page scrolls very quickly when I come 'back' to a page where I had gone to a link.
I turn 'smooth scrolling' off when the user has asked for 'reduced motion'.
I learnt about this from reading the book: 'Responsive Web Design with HTML and CSS' by Ben Frain. I found the book in a branch of my local library. I find different books in the different branches
I get page 'layout shifts' when I use 'Google Fonts'
If I say 'font-display: optional
' to get round this then I do not see the Google fonts at all, as they do not load in time.
I tried to reduce the size of the font file by specifying a font weight and by specifyng the letters in the alphabet as the 'text' to match. But the font file still takes too long to load.
I also tried putting Google's intermediate '@font-face' rules directly in my CSS. But the font file still loads too slowly.
I also tried downloading the font file onto my website. But the web server is a bit slow and again I do not see the Google fonts. My hosting provider is 'Hostinger'.
I did not try adjusting the size of the system fonts to match the Google Fonts to remove the 'layout shifts'. This seems a bit complicated and may not work on all browsers.
I am going to try loading fonts into my game using the JavaScript API. My game takes a few seconds to load anyway and probably already has a few 'layout shifts'
I managed to get 'blogarama.com' to index my blog
I get 50 posts free. I only put my best posts on 'blogarama'. 'blogarama' did not mind when I waited 4 months before adding the next post.
'blogarama' thought I had put a reciprocal link in my blog when I had not.
However, I cannot find any of my posts on 'blogarama'. There are a lot of ads.
Many directories of RSS feeds seem to have closed in recent years. However, it seems it is still worthwhile having an RSS feed
I always put a '#
' before a 'rm -rf
' before clearing out old backups
I think a bit and then remove the '#
' and then run the command.
I once ran '/bin/rm -rf
' as the user 'root
' and deleted lots of files I wanted. I even deleted the '/etc/passwd
' file and got the famous 'you do not exist
' error.
I work as the user 'root
' because my 'X Windows' system needs this. This is because I upgraded my Linux system myself 'from scratch' and did it slightly wrong.
I get a smiley '(:0)
' next to my 'root
' user's 'pseudo-terminal' when I run 'who
' to show who is logged on
warnings from Chrome's Lighthouse turned out to be bugs from using an old version of Chrome used for Windows7
Lighthouse said: 'heading elements are not in a sequentially-descending order
'.
I can get round this by using the 'Lighthouse' option at 'webpagetest.org'. Or I can go to a neighbouring libary that runs Windows10 and the latest Chrome
I adapted a 'codepen' icon made with CSS made of rectangles made with 'clip-path
', with the sides rotated to form a cube.
Some of the sides are moved to the front with 'translateZ
'.
I colored the sides to see how it works:
'codepen.io/Bert-Beckwith/pen/jENyyaK'
This is a different way of making a cube. Another way is to rotate 'div
' elements.
Maybe there is a bug with Chrome: sometimes the sides of the cube disappear if I change the background color of their container. The sides reappear if I click the icon. I tried reflowing the cube, adding 'z-index
' and adding '!important
' but these did not fix the bug.
It is best to use SVG's for icons but I learn about CSS and my old browser does not show SVG's in HTML pages
I changed from using 'cp -a
' to 'cp -pR
' when making a backup of the directories I use most.
The 'cp -a
' command gave an error because a symbolic link could not be created on the FAT file system of the memory-stick that was the destination of the copy.
So I removed the '-d
' (no dereference) part of the '-a
' option and now 'cp
' copies all the files that the symbolic link references.
On second thoughts, maybe 'cp -a
' is better because it means I do not get duplicate files
For about 2 months, images were sometimes not loaded into my pages when served by my hosting provider 'Hostinger'
Sometimes Chrome could not load a page at first but then found it.
Sometimes I also got errors transferring files with 'FTP'. I could not do a backup with 'FTP' because of these errors.
Maybe I should not complain as I chose a very good value 4-year deal when I moved my website from the free '000webhost' to Hostinger. Inflation since has made the deal seem even better.
So I get 'Hostinger' to generate a backup every week and download it. It is one big 'gzipped' 'tar' file. I request the backup in the middle of the week as Hostinger says the backup takes a few hours to prepare. I download the backup at the end of the week. The download takes only a few minutes. I checked this download file. However, Hostinger says there were some problems with their backups.
I tried using the web-based 'file manager' provided by 'Hostinger'. But I sometimes got network errors when I used this 'file manager' on the old Windows7 computers at my local public library. So I went back to using 'FTP'. But the 'FTP' in the 'File Explorer' of Windows7 says passwords are sent in 'plain text'.
I can now transfer files and do a backup with 'FTP' without errors. but the backup is too slow taking over an hour. I could not seem to stop the slow backup and I ended up with errors on the extended 'FAT' file system on the memory stick where I store my backups. When I got Windows to 'fix' the file system, the recovery came to the end but did not finish. Still the file system ended up fixed.
I have read good things about the hosting provider 'fastcomet.com' and they have a cheap multi-year deal
I cannot install a Progressive Web App (PWA) with Firefox on Windows
It seems Firefox on the desktop removed support for installing PWA's. Maybe this feature was broken and Mozilla did not want to spend time on it.
There is an unofficial 'extension' to Firefox that lets you run Firefox with a PWA.
In February 2024, Apple said it would not support PWA's in the Ruropean Union. Apple changed its mind perhaps after developers complained. Maybe this was part of a dispute between Apple and the European regulators
My JavaScript game is too big for 'freehostingeu.com'
There seems to be a limit of 2 megabytes.
I use 'freehostingeu.com' as a sort of backup website
My game is about 4 megabytes. I am manually 'minimising' it at the moment with shell and Perl scripts in addition to 'UglifyJS'. But I will not be able to get it to be under 2 megabtyes.
I did split the JavaScript in my game into two for the 'InfinityFree' hosting site a year or two ago. This site has a lower limit of 1 megabtyes.
I should have developed my game as lots of separate JavaScript and CSS files. But having one 'monolithic' file made things a lot easier to start with.
I cannot see the source of my game in Chrome with the 'View source' option on the old Windows7 computers in my library
My game is about 12 megabytes.
To get round this, I note down the line number of the error in Chrome and then look at the source in Firefox which loads in my big game successfully
There probably is a better way to view a file with line numbers in Windows. The line numbers in Word wrap around to line '1' after line '65534'
I remove excess whitespace in strings used to create dynamic CSS
My minimiser, 'UglifyJS', does not remove the excess whitespace. It would be quite difficult. So, I edit the source file by hand in 'vi' saying:
s:'[ ][ ]*:' :g
This turns:
' @keyframes ppbWingRight' + birdNumber + ' { ' +
' 0% { ' +
' transform: rotate3d(0,1,0,' + wingAngle + 'deg); ' +
' } ' +
' 100% { ' +
' transform: rotate3d(0,1,0,-' + wingAngle + 'deg); ' +
' } ' +
' } ' +
into:
' @keyframes ppbWingRight' + birdNumber + ' { ' +
' 0% { ' +
' transform: rotate3d(0,1,0,' + wingAngle + 'deg); ' +
' } ' +
' 100% { ' +
' transform: rotate3d(0,1,0,-' + wingAngle + 'deg); ' +
' } ' +
' } ' +
I create a 'style
' tag, set the 'innerHTML
' to the string, and attach the 'style
' tag to the 'head
' element.
I often start with some 'static' CSS that I found on 'codepen.io', often written by Yusuke Nakaya. Most times, the 'pen' uses a CSS pre-processor. I instead do the random bits in JavaScript. This is so the animation can run several times, and be different each time.
I do my own 'minimising' as well as running 'UglifyJS'. I shorten object properties and CSS id's and classes. I also replace constants in the same way as the C pre-processor does. I end up looking through the resulting code and it is then that I see the spaces in the dynamic CSS.
the download sites 'download.com' and 'softpedia.com' did not update their entries for my game after I released a new version
I filled in entries on their online forms for the new release. These two download sites had been best for my game in the past.
Also, the 'appvisor.com' website closed in 2024. This website had the official PAD repository and validator. 'PAD' stood for 'Portable Application Description' and was an XML file with information about your program.
However, I updated the entry for my game at 'libregamewiki.org' and the change was approved within a few days. The 'libregamewiki.org' website comes quite high up in Google's search rankings. But another change I made to my entry on 'libregamewiki' is still waiting to be approved.
Also I created an entry for my game on 'github.com'. I was even able to add an update for an improvement. I pasted the new code into the online editor. I pressed '.
' to get to the editor. I cannot really use 'Git' or the repositories on SourceForge because I do not have Internet access at home and the computers at the library use Windows and make it hard for you to install programs.
It seems the government regulators are trying to open up Apple's and Google's app stores. So maybe download sites will make a comeback. But I am not sure that trying to make money out of free software works that well. 'appvisor' charged for promoting your program and the download sites show adverts. It seems advertisers have switched from banner adverts on websites to targeted ads on social media.
I generate some interest myself in my game by putting tips on Facebook, LinkedIn, Pinterest, Flickr, 'blogspot.com', Sourceforge and two RSS feeds. Also, Google's search finds obscure names in my page of first names. My pages of idioms and bingo probabilities also have some visitors. I also put my animations on 'codepen'
I have been adapting an RSS icon made with CSS
The RSS icon came from:
'codepen.io/dazulu/pen/nwppvr'
There are 4 circles layered on top of each other, using 'z-index
' values. The circles are made with 'div
's and 'border-radius: 50%
'. The circles are of increasing size.
The circles are centered by setting a 'left
' and 'bottom
' to minus half the div's width and height. The circles have 'position:absolute
' within the overall icon container's 'position:relative
'.
The second and fourth circles have a white background, whereas the first and third have the orange color.
Only the top-right corner of the circles is shown by putting the 4 circles in a container 'div
' and giving the 'div
' an 'overflow: hidden
'.
Finally a small white circle is placed on top at the center of the above 4 circles.
My RSS icon is at:
'codepen.io/Bert-Beckwith/pen/YzobrmX'
This also shows the icon without 'overflow: hidden
' to show how it is made up
Chrome behaved strangely when I put a 'div
' inside an anchor ('a
') tag
Chrome put the 'div
' after the anchor tag rather than inside it.
I fixed this by changing the 'div
' tags to 'span
' tags and set the 'span
' tags to 'display: inline-block
'.
However, it seems the HTML5 specification says that you can put an anchor tag around most tags.
There are discussions about this on 'stackoverflow.com'.
My 'div
' contains other 'divs
'. The anchor tag is inside some complex HTML - a simpler example worked fine.
I am using an old version of Chrome: the last version on Windows7 from the start of 2024.
(My local library has not upgraded from Windows7 yet. The library has instead installed a more recent version of Firefox. Sadly some websites like 'Outlook' and 'Pinterest' do not completely work with the old version of Chrome)
The 'divs
' are for an RSS icon made in CSS from:
'codepen.io/dazulu/pen/nwppvr'
I put the RSS icon alongside a few other website symbols for Facebook, X and so on.
It would be best to use an SVG, but my very old Konqueror browser at home does not show SVG's in an HTML page. Also I can learn more about CSS.
I now need to use 'currentTarget
' on a 'click
' event on the anchor tag because if I click on a child 'div
' and the event bubbles up to the anchor then the 'target
' property is the child not the parent. I want the 'href
' property on the parent so I can open the link in a new tab
I had to change a '#
' to '%23
' in an SVG in a 'data
' URL of a 'background-image
' property in CSS
I had to do this when changing RGB colors to hexadecimal when 'minimising' my page using a bit of Perl:
s/rgb\(\s*(\d+),\s*(\d+),\s*(\d+)\)/sprintf("%s23%02x%02x%02x","%",$1,$2,$3)/eg;
(My old version of Perl does not allow '%%
' in the 'sprintf
' in the substitution)
All the other 'special' characters are encoded in the SVG in the 'data
' URL.
The 'background-image
' property looks like:
url("data:image/svg+xml;charset=utf8,%3Csvg%20viewBox%3D%220%200%20168%...
There are online tools to do the encoding.
A PNG image would need full 'base64' encoding to go in a 'url
' but an SVG does not
I now put code examples inside a '<pre><code>' block
I was using '&nbsp;' to indent lines.
I set the '<code>' to 'display:block
' so I can indent it with 'margin-left
'.
I start the example code immediately after the '<code>' tag to avoid an extra newline.
I put everything in a 'div
' with contenteditable="true"
and spellcheck="false
" to allow 'copy and pasting' and to remove any red 'spell-check' wavy line.
I give the 'div
' 'max-width:100%
' and 'overflow:auto
' to stop scrollbars appearing in the browser's outer window
I changed some of my icons to have transparent backgrounds. These were the icons mentioned in the 'manifest' files of my Progressive Web Apps (PWA)
I had given the icons white backgrounds to make them clearer as recommended by the PWA tutorial on Google's 'web.dev' website. But these looked strange next to other icons on a Windows desktop.
I made all my web pages PWA's by adding a 'manifest' file and starting a 'do-nothing' service worker. Chrome warns that loading these service workers slows things down
if I want to see changes I have made to my website in Chrome, then sometimes I have to click 'Disable cache' in the 'Network' tab of the 'Developer tools'
I noticed this when changing the icon images in 'Web App' 'manifest' files.
This may also have happened when I changed script files that I load in by creating a 'script
' tag and setting the 'src
'
I forgot which version of my JavaScript game I 'minimised' to produce the latest version.
Luckily I had put an RCS 'identification marker' in an HTML comment at the start of the code.
I had used the 'Revision
' marker.
RCS is the free source control system that came with my old Linux system
I speed up my JavaScript animations of the color of each letter in lines of text by:
IntersectionObserver
' to only run the animations when the text is visibletransition
' for the color changesscript
' elements in JavaScript and set their 'src
'. I use 'load
' events to create dependencies between the scriptsI color the letters by adding 'spans
' around each letter and then getting references to each 'span
'. I add a CSS class to each 'span
' and add a stylesheet with the color 'transition
' using JavaScript. The result looks like a rainbow passing through the letters.
'codepen.io/Bert-Beckwith/pen/eYobEKq'
Unfortunately, coloring each letter with JavaScript is very slow. And all the 'spans
' and 'transitions
' make things worse.
But I did not speed up the coloring of letters of text in my JavaScript game. I do not notice the performance problems when playing my game.
A better way might be to have one 'keyframe
' for the rainbow colors and different negative 'animation-delays
' for each letter. The 'animation-delays
' could be set with 'nth-child
'. There is some sample code for this at:
'codepen.io/Bert-Beckwith/pen/ZENYmmo'
The constant coloring of the letters still makes this slow. I would have to create the CSS in JavaScript to allow for animations of a random duration.
Yusuke Nakaya makes a firework animation by moving up together lots of small pieces and then sending them off in random directions.
Here is the CSS, which uses a pre-processor:
@keyframes spark#{$i} {
0% {
transform: translateY(random(150) + 500px);
}
50% {
transform: translateY(0);
}
100% {
transform: rotateZ($deg) translateX(random(200) + 100px);
}
}
The animation is at: 'codepen.io/YusukeNakaya/pen/zYvWGwb'
I have adapted this to use JavaScript to do the random bits rather than a CSS pre-processor.
I like the CSS animations by Yusuke Nakaya at 'codepen.io/YusukeNakaya'
I have changed two to use JavasScript for the random bits rather than a CSS pre-processor. They are the 'Paper Birds' and 'Birds' at: 'codepen.io/Bert-Beckwith'.
I use these as background animations for my game.
I learn about CSS as I change them
I used '!important
' in CSS for the first time
Only to discover that you are not meant to use it because it is difficult to override.
I have a problem where an element has a 'transition
' on both 'color
' and 'transform
' but these attributes are set in different places and may or may not be present.
I set the transitions by creating dynamic stylesheets with JavaScript so the latest 'transition
' overrides the earlier.
I tried using 'id
' and 'class
' CSS selectors so the earlier 'id
' overrides the later 'class
' selector but I cannot do this easily in all places because I am changing old code.
So I set: 'transition: color 3s, transform 0.5s !important
' to override where I later set 'transition: transform 0.5s
'
Taking a reference to a function of a class object sometimes loses the context
If I say:
var g = obj.f;
g();
Then the 'this' for 'g' is 'window' not 'obj'.
To get round this, sometimes I say:
g.call(obj);
With a timeout, sometimes I say:
var that = this;
function callg()
{
that.g();
}
setTimeout(callg, 1000);
I have been converting 'modules' to objects made with 'prototypes' and 'new'. By a 'module' I mean a self-executing anonymous function (a closure) returning references to inner functions
I made an SVG darker using an SVG filter
I added the filter to the top-level 'defs
' tag:
<defs id="defs4">
<filter id="my-dark-filter"
color-interpolation-filters="sRGB">
<feColorMatrix type="matrix"
values="1 0 0 0 -0.5
0 1 0 0 -0.5
0 0 1 0 -0.5
0 0 0 1 0"/>
</filter>
The values in the fifth column in the matrix vary from 1 for all-white to -1 for all-black.
I then called the filter from the top-level 'g
' tag:
<g filter="url(#my-dark-filter)" id="layer1">
I got the idea from 'stackoverflow.com'
The SVG came from 'openclipart.org'
my free website at 'freehostingeu.com' was down for several weeks
Other websites at their 'eu5.net' domain were down too.
'freehosteu.com' say the domain was suspended by the registry because the domain was abused.
You have to hold your nerve with free websites.
I used 'freehostingeu.com' as a backup to the free '000webhost.com'.
'freehostingeu.com' blocks pages with 'bad' words but sometimes these are innocent. One example was the 'itAu
' in 'webkitAudioContext
'.
'freehostingeu.com' used to offer the 'eu.pn' domain of the Pitcairn Islands. But the Islands said it was harming their reputation.
I was very happy with '000webhost.com' and stayed for ten years before upgrading to the cheapest paid plan with their parent 'Hostinger'. I chose a starting 4 year plan which now seems very cheap.
Hackers got 13 million passwords from '000webhost' in 2015. It was suggested that the passwords were stored in plain text and not encrypted. However, '000webhost' is free and shows no ads so I cannot complain
I use 'appetize.io' to test my game on simulated tablets and mobile phones
The trial version of 'appetize.io' gives me 30 minutes a month with a 3 minute limit on each session. However, I have just gone over my monthly limit and nothing happened.
I use the 'standalone' option where I can get to a simulated browser and run my game.
I came across 'appetize.io' while looking for a way to run mobile apps in a browser. But the app uses the Microsoft Authenticator app and this means I would have to setup the shared keys each time
I decided to delay my 'no-op' PWA service worker rathen than remove it
Chrome give a console warning if the service worker fetch listener of a Progressive Web App (PWA) does nothing. Chrome wants you to remove these 'no-op' (no operation) service workers to avoid the time taken to start the listeners.
But Chrome only recognises the PWA if it has a service worker. Chrome puts an icon in the top right to let you install the PWA.
I delay starting my service worker with a 'setTimeout
' of 3 seconds on the page 'load' event. You do not notice the delay in the PWA icon appearing.
I also delay all my animations. This also means that Google's search, Chrome's 'Lighthouse' and Webaim's 'Wave' accessibility checker do not see the bad color contrast choices of my animations.
I have switched from using JSHint to ESLint to find mistakes in my code
ESLint points out where a variable is assigned a value but the variable is not used. For parameters to functions, I try to remember to also change where the function is called. Sometimes these changes cascade up through parent function calls.
ESLint can process the 10 megabytes of JavaScript in my game. ESLint can do this on an old Windows7 computer with not much memory.
I use the online ESLint at 'eslint.org/play/'.
I read about ESLint in an article in 'Smashing' magazine.
I added a 'style
' tag inside my 'noscript
' tag to hide the 'loading' animations when JavaScript is disabled
I got the idea from an answer on 'stackoverflow':
I read a good book on AI: 'Smart until it's dumb' by Emmanuel Maggiori
The author shares his stories of working on AI in business and academic research.
The author says the power of AI is often exaggerated and the author predicts a mild AI winter.
The author's biggest fear is that AI will be used for safety-critical tasks like self-driving cars where machine-learning can make silly mistakes.
I borrowed the book from a public library
Chrome will not let me use 'calc
' in 'translate
', like:
translate3d(0,calc(-100vh-10em),0)
But Chrome allows the equivalent:
transform: translate3d(0,-100vh,0) translate3d(0,-10em,0)
There is an answer about this on 'stackoverflow.com' at:
I am using an old version of Chrome on Windows7 dating from the start of 2023
I make my checkboxes and radio buttons rotate when they are clicked
If the checkbox is clicked ('active') then the checkbox is immediately rotated 180 degrees. When the click is over, then the checkbox slowly rotates back to its original position.
input[type="checkbox"] {
transition: transform 1s;
display: inline-block;
}
input[type="checkbox"]:active {
transform: rotate3d(0,0,1,180deg);
transition: 0s;
}
This is on 'codepen' at:
Google's search set a 'full' page to be 'canonical' rather than the 'cut-down' version I had made for mobiles
I fixed this by putting the full content back in the mobile version.
Maybe Google's search wants to index some of the phrases in this page of 'idioms'. I know Google indexes some of the names in my 'names' page.
The mobile version still does not have some features of the 'full' page like: being able to search the phrases, having an index, having animations, and showing carousels of images. Most of these extra features are only shown with JavaScript after a delay after the page loads.
Google recommends not having a separate page for mobiles. I could use 'accordians' to show the extra content
there is a good CSS switch that looks like a light switch at:
'codepen.io/marcusconnor/pen/QJNvMa'
This switch uses 'em
' units so it is easy to scale.
The 'on' side is at the left which is the reverse of most switches. I removed the words and colored the sides red and green. I start off with the 'input
' element being 'checked
' and reverse the sense of the action in the JavaScript of the handler for a click. I found it too difficult to change the CSS and HTML to swap the left and right sides.
One trick with all pure-CSS switches is that clicking the label sets the related 'input
' element. So you hide the 'input
' field and style the label with maybe 'span
' elements inside the label and the 'spans
' can have a 'display
' value of 'inline-block
'.
Another trick is to use the ':checked
' state on the 'input
' element to change the style of the adjacent 'label
' with a CSS selector like 'input:checked + div
'.
The 'input
' element can be put inside the 'label
' element.
I sometimes change the code in 'codepen' to help me understand the code. I set colors and background colors
a leading zero can mean an integer is in octal in JavaScript
I learnt this when 'ESLint' warned about a time (in milliseconds) I had written as '0960
'
I moved my 'noscript
' tag from within the 'head
' tag to inside the 'body
' tag
The W3C HTML validator pointed out that my 'noscript
' tag contained 'div
' tags that do not belong inside a 'head
' tag.
The 'noscript
' tag worked the same way in the 'body
' tag
the online SVG optimizer, 'svgomg', shortens id
's to the same letters which conflict if the SVG's are inlined
I solved this by turning off the 'Clean up IDs
' option.
The W3C HTML validator points out the conflicts.
The Node.js tool, 'svgo', that is used has a prefix option or plugin to solve this problem.
The SVG's at 'openclipart.org' by regular contributors are not shrunk that much by the optimizer. One SVG got bigger after being optimized. Another SVG was dramatically smaller after being optimized
scaling down the size of a button on the 'active
' state means the JavaScript action does not fire on the outer parts of the button
I am animating my buttons on the 'hover
' and 'active
' states. I use 'scale3d
' and 'rotate3d
' as I am already setting the background color. I have 'input
' elements with a 'type
' of 'button
' which have no content so I cannot have ':before
' or ':after
' elements. I set a zero transition time for the 'active
' state and a longer transition time on the button element. Therefore the button is immediately transformed and then more slowly springs back into its original shape.
My problem is that when I click on the button, it is immediately scaled down, so on the outer parts of the button the click is no longer inside the button, and so the JavaScript action does not fire.
My soluation is to instead use rotations on the 'x' and 'y' axis of 180 degrees
if I dynamically create an 'input
' tag with JavaScript then I seem to have to dynamically create the 'label
' tag too
If the 'label
' tag is in the static HTML without the 'input
' tag then the W3C HTML validator says the 'for
' attribute of the 'label
' tag points to an 'input
' tag that does not exist.
I dynamically create the 'input
' tag to avoid the browser asking me to confirm that I want to leave the page when I have entered something in the 'input
' tag. The 'input
' tag is not part of a form that is submitted.
Also I have to dynamically create an 'img
' tag with JavaScript when I set the 'src
' attribute with JavaScript.
If the 'img
' tag is in the static HTML without a 'src
' tag then the W3C HTML validator says there is an error.
I dynamically set the 'src
' attribute because I am showing a carousel of images with JavaScript
I am worried that Google's search will see my page a bit like how the validator does. I add the 'input
' tag after a delay after the page loads. I do this to speed up the page load
the 'W3C' HTML validator has an 'outline' option
This option showed a bug where the 'h1
' tag was inside an 'h2
' tag. I was using the 'h2
' tag to give a name to an HTML5 'section
'.
This bug was not shown by the HTML5 outliner I use. This is the old one written by Marc Hoyois
I found a pure-CSS switch that does not use the 'for
' attribute of the label to set the 'input
' element
This switch has the 'input
' element as the background for the whole switch and uses 'pointer-events: none
' on the label to pass clicks through to the 'input
' element.
This switch is at:
I found some characters that were not UTF8 in my webpages using Perl.
I typed:
perl -ne 'print if /[^[:ascii:]]/' cr.html
The 'W3C' HTML validator noticed the invalid characters. The validator would not work when there were invalid characters.
The invalid characters were accents and the 'a
' and 'e
' combined in 'Julius Caesar
'. The invalid characters were in quotes I took from 'wikiquote.org'.
Several suggested checks for invalid characters did not work for me because my version of Linux is 10 years old.
I found the successful command at 'linuxhandbook.com'. This looks a good website for learning about Linux. This site seems a bit like the old 'O'Reilly' books such as 'Unix Power Tools'.
URL fragments (or 'hashes') on a page would not work until I fixed some invalid HTML.
I used the 'W3C validator'.
I had 'p
', 'code
' and 'article
' tags without ending tags. And ending tags without starting tags.
I had 'p
' tags around 'ul
' tags and 'p
' tags around 'p
' tags.
the 'border-radius
' property in CSS can have 8 values: four horizontal radius values, a slash and then four vertical values
The 'youtube' icon at 'css.gg' uses this to have corners with longer vertical parts.
You can also make odd-looking curved shapes.
I almost understand how to draw triangles in CSS after looking at the arrow heads in icons on 'css.gg' such as 'youtube' where it is in the ':before
' element
adding more metadata for my images did not improve how the images appear in Google's search
I added more JSON-LD with ImageObject
's for the main images in my pages.
I added license information to existing JSON-LD.
I added image information to my 'sitemap
' file.
I gave my images long descriptive file names.
I type 'site:bbingo.xyz
' in Google Images to see how my images appear in Google's search.
Google's Search guide recommended I add the extra metadata
the author of the icons at 'css.gg' has an interesting way of drawing lines
He creates a background of just one color using a linear-gradient. He then clips the background using the 'position/bg-size' syntax.
Here is an example of a red vertical line at the top of a box and a blue horizontal line at the bottom:
.gg-arrows-merge-alt-v {
width: 12px;
height: 22px;
background:
linear-gradient(
to left,red 10px,
transparent 0)
no-repeat center top/2px 8px,
linear-gradient(
to left,blue 10px,
transparent 0)
no-repeat center 20px/10px 2px
}
I think this method is used because the icons at 'css.gg' are made using just a 'div
' and its ':after
' and ':before
' elements
I almost used '-webkit-tap-highlight-color
' to remove the blue highlight when you tap an item on a mobile with Chrome
My item had an odd shape.
But it seems you also need to set 'outline: none
' on recent versions of Chrome. But this causes an accessibility problem.
So I just gave my item a regular shape and kept the blue highlight
you can make a 'funnel' shape in CSS with 'perspective
' and 'rotateY
'
The 'volume' and 'camera' icons at 'css.gg' use this
I search the icons at 'css.gg' using Google's search
For example, I search for 'button icon cas.gg
'. But after a while Google puts up a check to see if you are a human and not a bot.
There seem to be more icons at 'css.gg' than those listed in the categories.
Sometimes I have to align the icons by adding a 'top
' or 'left
' property to the parent element which is positioned 'relative
'.
Sometimes I have to add a 'top:0
' or 'left:0
' property to the ':before
' or ':after
' elements when I add the icons to a real webpage.
There is no 'cog' or 'gear' icon as this is difficult to do with the 3 elements used: the parent, the ':before
' and the ':after
'. I found a cog icon in an answer on 'stackoverflow.com'.
I converted the icons to 'em' units but a few icons do not scale completely perfectly. It is probably best to use inline SVG's, but I am learing a lot about CSS using the icons at 'css.gg'.
I change the 'display
' property from 'block
' to 'inline-block
' because I mainly put the icons next to text. I also change 'rotate
' to 'rotate3d
' out of habit because I have done a lot of CSS animations that run on the GPU
my account at 'freeshostingeu.com' was removed because I did not log in for a year
When I next logged in, my account was reinstated, but I got errors when using the file manager.
So I just created another account using another of my email addresses.
I visit all my pages at least once a week, but I must remember to log in too
I convert the CSS icons at 'css.gg' to units of 'ems
' so they scale well
I assume one 'em
' is 16px
.
'css.gg' uses a 'scale
' transform, but I have found this produces 'blocked steps' for the curves when scaled up.
'css.gg' removes unnecessary semi-colons at the end of a list of CSS properties for a CSS rule. But, I always get bugs when I add another property at the end of a list and forget to add a semi-colon at the end of the previous property.
It may be better to use nline SVG icons, but I learn about CSS when I modify the icons at 'css.gg' and I do not know much about modifying SVG's. There is probably less code if I use the icons from 'css.gg' rather than SVG's. I do not want to include a big online icon library.
I convert the icons at 'css.gg' from '2px
'-wide lines to '1px
'. I am using icons like illustrations and I do not want them to be too bold.
There is a little confusion about the license for the icons at 'css.gg', but the website says it it an MIT license
I have been enjoying adding a custom 404 error page to my website
Google's Search guide recommends a custom 404 page. I made a page with links to the valid pages.
I used CSS rotations and scaling.
The HTML editor of my hosting provider, Hostinger, does not allow 'meta
' tags. I used a CSS media query to adapt the page for mobiles as I could not use the 'viewport
' meta tag. This editor works best if you add a bit of code at a time rather than trying to paste in a whole page
I was puzzled by some CSS with a very large 'border-radius
'
But a 'border-radius
' of more than half the width of a square is treated as a 'border-radius
' width of a half the width, which makes a circle.
There might be a CSS rule with a large 'border-radius
' that applies to many square elements of various sizes
I can pause a CSS animation by creating a 'style
' element with a 'keyframe
' of the same name that does nothing
If the new 'keyframe
' does something different then both Chrome and Firefox immediately change the animation
I am putting each tip on my tips page in an 'article
' tag
The 'article
' HTML5 tag is for self-contained content.
I add an 'h3
' heading below the 'article
' tag with a title for the tip. Unfortunately, I am going to have to make up titles for about 1000 old tips. I hide the heading with 'display:none
' so only HTML5 outliners see it.
I have started reading Google's guide to how to improve a website's ranking in its search results. The guide is at:
I want to find out why my tips page does not appear in Google's index. This is somewhat ironic
to get a random value, say from 17 plus or minus 3, I can say:
20 - Math.random() * 6
I was saying:
d = Math.random() * 3;
if (Math.random() < 0.5) {
d *= -1;
}
v = 17 + d;
I had to rename my 'sitemap' file to get around Google's search saying it could not fetch it
I renamed 'sitemap.xml
' to 'sitemap2.xml
'
if I set the colors of scrollbars using properties like 'webkit-scrollbar
' then my single-item 'select
' is not colored and the 'select
' behaves strangely
If I make it a 'multiple
' 'select
' then the colors and behaviour are fine.
I fixed this by excluding 'selects
' with CSS selectors like:
:not(select)::-webkit-scrollbar
I got a surprise when I pressed the back button and my page set the checkboxes to their previous values
I could turn this off by saying 'autocomplete="off"
' on the checkboxes. Instead, when the page loads, I look at the 'checked
' values and run the relevant actions.
Firefox also 'autofills' the checkboxes when I refresh the page.
There is a discussion of this at:
This is also discussed on 'stackoverflow.com'
I realised that I can see the compiled HTML and CSS on 'codepen.io' where examples use preprocessors
There are options in the menus I get from the 'down arrow' icon in the top right corner of the HTML and CSS editors
I had my first go at 'visually hidden text'
This is content that is meant for screen readers but which is not visible on the screen.
I had an icon as the label for a search term 'input
' field. The 'Wave' accessibility testing tool pointed out that the label had no text.
One solution is add some text to the label but give the text a '1px
' size with 'overflow: hidden
' and 'clip
' it.
This is discussed at:
'webaim.org/techniques/css/invisiblecontent'
and, of course, on 'stackoverflow.com'
I have had a bug twice where content will not overflow outside its container. I forget that I had set 'contain: content
' in the CSS
'contain
' in CSS isolates a part of the HTML allowing the browser to speed up the rendering partly by stopping content overflowing into other areas. .
I was changing the color of each letter of the text with Javascript. I wanted to separate this from the large main content of the page which did not change. So I added 'contain
'. It made a small difference
if I use a near-black background for 'dark mode' then I can have more colorful foreground colors
Otherwise, if text is to be clear then I need almost white foreground colors for dark-but-colorful backgrounds.
Things can get a bit scrappy when I am changing lots of colors for 'dark mode' when I am changing old code I do not quite remember.
I think it will take all year to change my game to offer a 'dark mode' - truly a labour of love
the example code on the 'w3schools.com' website is copyrighted with no open-source license
I used their code for a CSS switch. I had to start somewhere.
I am going to change to use code from 'codepen.io' which has more interesting CSS switches anyway. 'codepen.io' uses an MIT license. I might try to vary the switches shown using various designs
I am doing my search icon using CSS from the 'css.gg' website
There are lots of nice CSS icons at 'css.gg'.
An SVG icon might be simpler but my old browser does not show SVG images in HTML
the scroll-bar lags behind my mouse movements if I use the '-webkit-scrollbar
' properties
This happens when I have many JavaScript animations and a long page.
This happens even with the latest version of Chrome on Windows 10
The '-webkit-scrollbar
' properties let you color the scroll-bar or use patterns.
I am going to show a custom scroll-bar after about a minutes on pages where the lag is small
I enjoy looking at the animations by Yusuke Nakaya on 'codepen' at 'codepen.io/YusukeNakaya'
I look for animations that can run on the GPU during my game. These are CSS animations that use 'transform
' and 'opacity
'.
I put a few animations together that I find on 'codepen'. I try to make them more random and make them fit on different screen sizes. I learn about the animations as I make changes.
The animations on 'codepen' have a MIT license
I now turn on my animations if there is a wide screen and not a 'coarse' pointer'. I used to check the 'user agent string' for 'Mobi
', 'Android
' or 'iPad
' etc
A 'coarse' pointer is a finger on a mobile or tablet.
I also check for 'prefers-reduced-motion
' and 'prefers-contrast
'.
I also check 'userAgentData.mobile
' on Chrome.
I am going to check the screen size using a media query as well.
My media query for mobiles in my CSS is now:
@media (max-width: 699px), (pointer: coarse)
The comma in the media query above means 'or'. In the above, I am trying to include mobiles or tablets with wide screens
implementing 'dark mode' with 'invert
' on the 'html
' tag does not seem to work on the old Firefox used in my local libraries
This version of Firefox does not invert the background. This Firefox just inverts the elements you add. The Firefox developers feel they are following the specification.
Using 'invert
' when there is an 'overlay' scrollbar on Chrome sometimes makes the scrollbar disappear. I am using the last version of Chrome on Windows7. I understand 'overlay' scrollbars have been removed from the latest versions of Chrome. Of course, a dark scrollbar on a black background does not make sense. So I would need to use 'color-scheme
' to change the color of the scrollbar. But 'invert
' does not work well with 'color-scheme
'. I could not set the colour of this 'overlay' scrollbar with properties like '-webkit-scrollbar-thumb
'.
So I am going to have to implement 'dark mode' by setting the colours one by one.
In my game I darken background colours by reducing the 'red', 'green' and 'blue' values by a half. I lighten text colours by increasing the 'red', 'green' and 'blue' values by a half of '255' minus the value.
In my game I am going to offer the choice of implementing 'dark mode' by changing all the colours one-by-one or by using 'invert'. I will put in a warning that 'invert
' may not work on Firefox. I use 'hue-rotate(180deg)
' with 'invert
'. This keeps the colours more or less the same. but I also 'invert
' some element again to retain their true colours.
The public libraries in a neighbouring town do not have Firefox installed at all and just offer Edge and Chrome on Windows 10
I enjoy looking through the example code at 'w3schools.com/howto'
For example, I was looking for an SVG for a 'hamburger' menu icon before I saw a 'howto' making a 'hamburger' icon with just CSS and HTML
I cannot tell if the user really wants a light color scheme or the default just applies
There is no longer a 'no-preference
' value.
There is a good article at 'web.dev/articles/prefers-color-scheme/'. I wish I had read it first.
You can use transitions on filters such as 'invert
'. They look very nice and do not seem to slow things down.
I am going to try inverting the colors on my web pages at intervals. This may be annoying. But I can experiment because very few people look at my pages
release late and less often
I did not release a new version of my game last year but recently the number of downloads on SourceForge has gone up ten times.
Maybe this is because Google's search now finds a third-party link to my list of first-names.
Or maybe because I now post my tech tips on SourceForge, Facebook, LinkedIn and blogspot.com.
Or perhaps because I have made my tips, probabilities and idioms pages more mobile friendly
red text on a white background does not have enough contrast
In other words, red text has a contrast ratio of less than 4.5:1.
I coloured red the first letter of paragraphs.
I now use a darker red: 'rgb(235,0,0)
'.
I check the contrast of colours with the 'Wave' tool from 'webaim.org'
having over 30 IntersectionObserver
's on one of my pages does not slow the page down
I show a carousel of images next to each section when the section is visible.
Before I added observers, all the carousels were running all the time. All these animations was slowing the page downa a little.
It was simpler for me to code each observer to observe just one target element
for my quick 'dark mode' I say 'hue-rotate(180deg)
' as well as 'invert(100%)
'
Inverting colors makes the strongest of the red, green and blue channels the weakest, changing the color or 'hue'. If you rotate the color wheel by 180 degrees, you get back to something near the original color or 'hue'.
I tried reversing the order of 'invert
' and 'hue-rotate
' when I invert images again. But the order did not seem to make any difference. If I invert images again then I do not seem to get back to the exact original colors.
I tried reducing the brightness after inverting the colors but this reduced the contrast of the text.
For my game, I have started on a custom 'dark mode', changing all the colors rather than using a quick 'invert
' filter. If I make the colors lighter or darker rather than inverting then I can keep much closer to the original color scheme. But this is going to take me a long time. So I am also working on a 'dark mode' with an overall 'invert
' but also borrowing some of my custom colors and inverting them again so they show through
I added a check on 'navigator.userAgentData.mobile
' as well as searching for 'Mobi
' in 'navigator.userAgent
'
But I did not need to, as the high-level browser information will still be in the 'userAgent
' string when Chrome reduces the information in the the 'userAgent
' string.
All the information in the old 'userAgent
' string can be used to uniquely identify you so Chrome is reducing the information.
Firefox does not support 'userAgentData
'.
Still, 'userAgentData
' offers another way of testing for mobiles on Chrome. I do not want to run animations on a mobile even if the mobile has a wide screen and supports the animations. You are really meant to use 'feature detection' and 'responsive design'
it is easy to delete the wrong files on my website when using the FTP in Windows 'File Explorer'
But it is also easy to make backups of my website with FTP.
I selected a few files to delete but I still had my 'images
' directory selected so I deleted lots of my images by mistake. I am going to delete just one file at a time in future when using FTP.
It takes one and a half hours to backup my one gigabyte website using FTP. My cheap hosting plan with 'Hostinger' does make weekly backups but I cannot access the server where the backups are from the computers in my library - a DNS problems maybe.
I can now easily switch to another cheap introductory offer with another hosting provider now I have my own backups
I find the text is clearer if I set the text to be bold when I setup 'dark mode'
I say: '* { font-weight: bold; }
'
But the bigger text sometimes overlaps items that follow.
I have just finished reading the very good CSS tutorial on Google's 'web.dev' at: web.dev/learn/css/
It brought me up-to-date and gave me lots of ideas
I have been trying to make some SVG's have transparent backgrounds
I could just remove a white 'rect
' in a small number of cases.
More often, I had to remove a white 'path
' going from the outside edges to around the figure.
Sometimes this 'path
' is off-white like '#fefefe
'.
However, sometimes a white background is needed to show through inside the figure, like for the whites of eyes.
Sometimes a white background is needed as a black figure will not show up against a black background, like for a black cat.
I found it is a good idea to comment out parts of the SVG with XML comments ('<!--
', '-->
') rather than remove the parts, in case I make a mistake.
I have a black background when the user wants 'dark mode'. I invert the 'html
' tag and then invert again the SVG images to get back to the original colors. I use the CSS 'invert
' filter.
The SVG's are of animals and are from 'openclipart.org'
I am creating 'cut-down' copies of my web pages which perform better, are more accessible, and which put mobiles first
These 'cut-down' pages have much less content. The tips page just shows the latest tips, for example.
I remove all the JavaScript animations and CSS animations from the 'cut-down' pages.
I change some colors to have more contrast in the 'cut-down' pages.
I remove any index and any search boxes from the 'cut-down' pages. I will add them back when I have learnt how to do 'slide-in' options for mobiles.
I add a link in the 'cut-down' page to the original page.
I rename the original page and make the 'cut-down' page take on the orignal name of the original page. Now all external links, like Google's search, point to the 'cut-down' page.
However, my most popular page is an old-fashioned page with lots of animations, badly contrasting colours and badly spaced-out elements. The page is best viewed on a desktop computer
when I would rather read the paper, I tell myself I will just do some programming for an hour
But often I end up spending several hours programming.
I sometimes end up readng the paper while waiting for my browser to load my game, which takes a few minutes on my 20-year-old computer.
I try not to do too much programming all at one time, so I don't get bored with it. I try to a little at a time, but aim to carry on doing it for many years
I thought a CSS animation with a duration of 3 milliseconds was too quick. But maybe I was wrong
I thought our eyes could see changes at up to about 60 frames per second, meaning a minimum animation duration of about 16.666 milliseconds. On the computers I use, Chrome uses a frame rate of 60 per second.
But there are monitors with refresh rates of 144Hz and 240Hz, which Chrome supports.
Also our brain can improve on what our eyes see. And some people can see the flicker in lights. And our peripheral vision is better at seeing motion.
The animation was of a flame flickering
I find I do not need to fully understand how a fix to a program works
Sometimes it's a bit like magic.
I have to start somewhere and I understand more as I work on that part of the program.
I find many bugs as I develop new features rather than through testing
it really is best to set colours in CSS and not JavaScript
Then I found it is easy to change to a high-contrast colour palette by just creating a stylesheet to override the normal colours.
The idea is you change colours by addng a CSS class rather than setting the 'color
' property of an HTML element.
But sometimes I calculate colours in a range between two colours or calculate the effect of overlaying one semi-transparent colour onto another. Here, I think it would be too long-winded to put the colours in CSS rules. But this means I have to re-colour all the parts of the boards in my game when I change to a high-contrast palette.
One good thing I had done was to have lots of options on a settings screen to change aspects of my game. So when I change to a high-contrast paletter all I have to do mostly is to run the code that runs when an option is changed. By contrast, some people say you should show the user just a few options.
Another good thing about adding a high-contrast palette was that it got me back into lots of old code.
I dynamically create stylesheets a lot, a bit like this:
var stylesheet = document.createElement('style');
var mHeadElement = document.getElementsByTagName('head')[0];
mHeadElement.appendChild(stylesheet);
And it is similarly easy to remove these stylesheet afterwards
my cheap hosting plan with Hostinger does not offer SFTP (SSH File Transfer Protocol)
My cheap plan costs about one dollar a month for four years. To get SFTP I have to upgrade to a $10 a month plan which is currently on offer at $3 a month.
I am using FTP because the computers in the libraries where I use the internet cannot reach the server with Hostinger's new file browser.
I understand FTP sends passwords and data as plain text, unencrypted, which is not secure
there are some good quotes from Steve Jobs at 'wikiquote.org'.
Here are some:
I make a random quote the 'title
' attribute of an image. The quotes at 'wikiquote.org' are in the public domain.
There are also some inspiring quotes from Nelson Mandela
I have been working on over seven tasks at the same time for the last few months whilst developing my computer game
By contrast, 'Agile' developers like to work on one task at a time.
Each day I make a list of what I will do on each task the next day as I go through the tasks. I try not to think about all the tasks all at once as it can get a bit confusing.
However I liked working on one task for a few days when I stayed at home recently when I had Covid.
I have tried lots of different ways of working over the years. During the summer of the pandemic I even tried working through the night but I did not sleep well afterwards due to the daytime noises. I recommend you just pick whichever way of working suits you at the current time
I try to change a 'generic' node in the 'accessibility tree' to a 'section
' or 'figure
' element
A 'generic' node is usually a 'div
' element. I add an 'h2
' header element after a 'section
' to describe the 'section
' element. I hide the 'h2
' element by setting 'display: none
'. I add a 'figcaption
' after a 'figure
'.
I try to replace the 'generic' 'div
' element with a 'section
' or 'figure
' element but sometimes my 10 year-old browser gets confused so I just put the 'section
' or 'figure
' around the 'div
'.
The 'accessiblity true' is an extended version of the DOM tree meant for screen readers.
I also hope that if I add more HTML5 tags then Google's search bot will like my pages a bit more. But I really need third-party links to my pages to get in the search rankings.
Getting to the 'accessibility tree' is a bit complicated in Chrome. Go to the 'developer tools' then choose 'Accessiblity' from the 'Elements' tab, then click 'Enable full-page accessibility tree', then click 'Reload DevTools', and then click the icon of a person with outstretched arms
I had a first go at a 'Content Security Policy' (CSP)
I added HTTP headers to the '.htaccess
' file on my website:
Header add Content-Security-Policy "default-src
'unsafe-inline' https://bbingo.xyz data:;"
Header add Access-Control-Allow-Origin "*"
I really need to put my styles and scripts in separate files. Allowing inline styles and scripts is unsafe, so I have to say 'unsafe-inline
'. A workaround would be to put hashes of the scripts in the CSP headers. I say 'data:
' as I have some SVG's encoded inline in a data URL.
Content Security Policies are meant to stop cross-site scripting attacks and work by telling the browser to only use resources from specific locations.
My tips page is attached to my pages on Sourceforge so I need to allow access to the favicon and manifest which are on my website at 'bbingo.xyz'. So I include the second header
I have been adding 'prefers-reduced-motion
' and 'prefers-contrast
' media queries to my webpages
The accessibility course on 'web.dev' says I should have my animations off by default and let the user turn on the animations if desired.
Chrome lets you emulate these media settings. The computers at my library do not let you set these media settings in Windows.
'web.dev' says these two accessibility media queries are the two best supported by browers
the 'main
' HTML tag comes between the site 'header
' and 'footer
' tags
There can be a page 'header
' and a page 'footer
' within a 'main
' tag.
There can also be 'header
's and 'footer
's wihin 'article
' and 'section
' tags.
I wrongly put my site 'header
' and 'footer
' tags within my 'main
' tag and Chrome did not mark the 'header
' and 'footer
' as 'landmark' tags in the accessibility tree
I changed the 'lang
' attribute of my 'html
' tags to be 'en-GB
' rather just 'en
' to help screen-readers
I also removed 'text-align: justify
' as the uneven spacing can make the text harder to read
I am using the online HTML5 outliner by Marc Hoyois at: 'hoyois.github.io/html5outliner/'
I used to use the outliner at: 'gsnedders.html5.org/outliner/'. This got confused by HTML5 tags like 'header
' and 'nav
'. This outliner seemed to break and stop working
I have been adding more semantic HTML5 elements to my webpages
I have added 'header
', 'section'
, 'main
' and 'nav
' elements.
The 'accessiblity' course on 'web.dev' says to add semantic elements before adding ARIA attribues.
I do use an ARIA label to distinguish two identical links. One link is big for small screens. The other link is small for big screens
if I upload files to my website then they do not always immediately appear when I look at my webpages in a browser
My hosting provider is 'Hostinger'
I have been reading 'Cryptocurrencies all-in-one for dummies' by Kiana Danial et al
The book put me off buying some bitcoin. It seems so difficult to keep your 'private keys' secure.
I learnt a lot about keeping online investing secure
I borrowed the book from my public library
I have been using 'accent-color
' in CSS to set the background color of checkboxes and radio buttons
I found one quirk.
I have a set of checkboxes with a CSS animation taking the 'accent-colors
' through a rainbow. The background colors start off all in sync. But if I check and un-check some boxes then the colors get out of sync. It is as though un-checking a box restarts the animation afresh
I enjoyed reading the course about HTML forms on Google's 'web.dev'
The course was an easy read and brought me up-to-date.
The course has lots of links to related articles
I have been using the 'Wave' accessibility testing tool from WebAIM'
This tool is more thorough than 'Lighthouse'.
So far 'Wave' has told me about:
h2
' headers between 'h1
' and 'h3
' headers'Wave' is a project at Utah State University which is supported by big tech companies and the U.S. government
I learnt a lot about how to design the HTML and CSS of a blog from starting a blog on 'blogger.com'
My own page of tips is one long list and has too many HTML elements which makes the browser slow to lay my page out.
'blogger.com' shows a paragraph for each post and shows the whole of the post when you select it.
No-one reads my new blog except me. My blog is at: 'onecenttips.blogspot.com'
the 'caret-color
' CSS property changes the color of the flashing bar which shows the point at which text will be inserted
The 'caret-color
' property applies to 'input
', 'textarea
', and text with the 'contenteditable
' HTML attribute set.
If the 'caret-color
' is not set then the color is the color of the 'input' element.
It seems a good idea to set the 'caret-color
' on the ':focus
' CSS selector.
The 'caret-color
' can be animated with 'keyframes' in CSS.
This animation does not seem to affect the performance of my page. I was worried about the performance as changing the colour will not run on the GPU
my pictures of line graphs are smaller in 'PNG' format than Webp' format
'Lighthouse' said I could reduce the size of my images by converting them to a newer file format and so reduce the time it takes to download my web pages
creating a simple minimal Progressive Web App (PWA) helped me get started with this sometimes complex topic
Chrome also helps by showing lots of information about your PWA and letting you test the 'service workers'.
I learnt a lot from the course on PWA's on 'web.dev' but the course was a bit overwhelming.
After all, PWA's are quite ambitious. You add hints to a web page, borrow a little code, and magically the page turns into something that runs by itself on a mobile phone like a native app.
Now I don't need to learn two new languages to get my game to run nicely on Android phones and iPhones and iPads.
However, I had to upgrade my website to use SSL for PWA's to work.
I have now changed all my web pages so that they can run as PWA's
I added a 'div
' with 'overflow: auto, max-width: 100%
' around the sample code in my tips page to avoid a warning in 'Lighthouse' about the content not being sized correctly for the viewport on a mobile
If a line of code is longer than the width of the browser, this means a scrollbar appears below the code. This keeps the content within the width of the browser.
You can put the 'overflow
' CSS on the 'code
' or 'pre
' tags if these tags enclose all your sample code.
I also say 'contenteditable="true" spellcheck="false"
' on the 'div
' so the code can be easily selected and the browser does not underline in red what it thinks is misspelt
There is lots more to styling sample code like colour syntax highlighting, shadows, slight rotation, and different typefaces.
I use the 'IntersectionObserver
' to only show my slow JavaScript animations when they are visible
These 'observers' are simple to use
I use the 'scope
' property in my 'manifest' so I can have many 'Progressive Web Apps' from one website
It seems the 'start_url
' needs to end in a slash. Luckily, my pages are called 'index.html' and are in their own subdirectory.
Here is an example:
"scope": "/techtips/",
"start_url": "/techtips/",
My 'manifest' is in the top directory of my website.
I got the idea from a post on 'stackoverflow
you can set the 'theme-color
' on a desktop if you create a 'Progressive Web App' (PWA)
It is reasonably straightforward to create a minimal PWA. I had to change my website to use SSL.
You set the 'theme-color
' in an HTML 'meta
' tag. This colors the title bar on mobiles and tablets.
You can create a 'shortcut' to a 'standalone' copy of your PWA outside of your desktop browser
Firefox says the SSL 'issuer certificate' for my website has expired
I think I need to upgrade Firefox to refresh its database of SSL certificates. But I use Firefox in my local library.
My hosting provider uses the free SSL certificates from "Let's Encrypt"
I like to add a random negative 'animation-delay
' to my CSS animations to vary where the animation starts in the 'keyframe
'
adding loading="lazy"
and decoding="async"
to images in a web page cut the time to load the page by a third
The page has about fifty 800 x 600 images.
Adding decoding="async"
makes the page 'flicker' as the text is shown before the image.
I thought about adding loading="lazy"
to all my images and letting the browser decide which to show. But this is wrong as the 'above the fold' images will delay the 'first content paint'
it is best to use use self-referential 'canonical' tags
These are 'canonical' tags on pages that point to themselves.
This makes it clear to Google's search crawler which page you want to have indexed. For example, deciding between 'www' and 'non-www' URL's.
The 'canonical' tag for my tips page is:
<link rel="canonical" href="https://bbingo.xyz/techtips/" />
I had wrongly just put 'canonical' tags on versions of my pages that were not 'canonical'
it is best to have 'width
' and 'height
' attributes on 'img
' tags even if they are 'responsive' and can change their size to fit the layout
I wrongly removed the 'width
' and 'height
' from my 'img
' tags when I made them 'responsive' by adding 'max-width: 100%
' and 'height: auto
' in my CSS.
The browser can calculate the size needed for the image early on from the ratio of the 'width
' and 'height
' in the HTML before the image is downloaded
It seems quite complicated when I read about this
I learnt a lot reading about 'Responsive Design' on Google's 'web.dev' website
increasing the contrast of a blue colour made it grey
I am checking the contrast of my colours with the 'Accessibility' section of the 'Lighthouse' tool in the Chrome 'Developer Tools'.
I click on the element in the 'Lighthouse' report, go to the 'Styles' pane, click on the color box of the active rule at the top, change the color picker to 'HSL' by clicking on the control on the right, lower the 'lightness' using the arrow key, and then changing back to 'RGB' for my old browser
adding 'contain: content
' in CSS reduces the time to recalculate my stylesheet by a quarter
Using 'contain: strict
' makes the content disappear as I have not specified a height.
Adding 'contains
' tries to stop CSS changes within that branch of the DOM tree affecting other parts of the tree, and vice-versa.
I am changing the color of the text in the header of my 'tips' page, with a transition. This takes a long time. Maybe the browser is looking through the large body
use an empty string (""
) for the 'alt
' attribute of a cosmetic 'img
' tag
This means screen readers will ignore cosmetic 'img
' tags.
I wrongly gave the penguin illustration on my 'tips' page an 'alt
' attribute of 'Penguin
' but the illustration is only loosely connected to the page content.
If you use an empty string as the 'alt
' attribute then if the image cannot be loaded then you won't get a missing image icon on the page. At least not on Chrome or Firefox, but you still see the missing image icon on Internet Explorer 11
Edge may give another view of performance to Chrome
Chrome tried out a summary of performance missing off some of the detail.
But I could have looked at Edge which showed lots of detail about performance, the old way
Firefox shows another view of the performance of a webpage
Firefox shows clearly which functions use the most CPU
compressing all my pages had the sixth biggest impact when speeding up my web pages
I had not realized the importance of having a small initial size for a webpage to speed up page load times. The 'ighthouse' tool showed this.
I simply run my JavaScript through 'JSMin' to remove comments and unnecessary whitespace. I compiled 'JSMin' from source - it is a very small C program.
I will probably run my JavaScript through 'UglifyJS' when I stop making changes to my webpages. I have to go to my library to use the online ''UglifyJS'' so it is a bigger job.
I shorten 'id' and 'class' names in CSS using 'sed
':
tee scsstmp.html |
sed -n -e '/style type=/,/<\/style>/s@[ ]*[.#]\([a-zA-Z][a-zA-Z0-9_]
[a-zA-Z0-9_][a-zA-Z0-9_][a-zA-Z0-9_]
[a-zA-Z0-9_][a-zA-Z0-9_][a-zA-Z0-9_] [a-zA-Z0-9_]
[a-zA-Z0-9_]*[a-zA-Z0-9_]\) [ ]*[{,:][^.#]*@:\1:@gp' |
sed -e 's/::/:\n:/g' | sort -r | uniq | nl -v150 -n rz -w 3 |
sed -n -e 's/^ *\([0-9][0-9]*\)\t:\([a-zA-Z][a-zA-Z0-9_]*\):/s;\2;Z\1;g/p' >scsstmp.lst
sed -f scsstmp.lst scsstmp.html
This shell script uses 'sed
' to create a file of subsitutions and then runs them against the webpage.
Finally, I squash up all whitespace with a line cf shell script:
tr '\n' ' ' <jtjsm.html | tr -s '[:space:]' >jtmm.html
I also removed old unused code to further reduce the page size
running animations that are not at the top of the page less frequently had the fifth biggest impact when speeding up my web pages
My animations are where I change the colour of the text and where I show a slideshow of images. These animations mainly use the CPU not the GPU, so have quite an effect on performance.
I also only re-create the 'keyframes
' each time the animations run for the animations at the top of the page. I re-create the 'keyframes
' to fine-tune the fading in and out in the slideshows
breaking functions into steps and pausing between the steps had the fourth biggest impact when speeding up my web pages
This lets the browser respond to the user's clicks and other user interactions.
This also keeps the frame-rate high so screen changes seem smooth.
This also shortens the 'long-running tasks' shown in the 'performance' tab of the 'developer tools' in Chrome.
I also stagger the start of the slideshows so that the web server does not send the pictures back all at the same time. One page has about 20 slideshows
delaying things so that the page loads faster had the third biggest impact when speeding up my web pages
The background gradients and the SVG pictures both fade in, so you do not notice that they now start after the page loads.
On page load, I now only color the text which you first see at the top of the page. The rest of the text below is coloured after a delay.
I just use 'setTimeout
' to delay things
not doing animations on a phone or tablet had the second biggest impact when speeding up my web pages
Also on a phone or tablet, I do not colour the page background with changing 'radial gradients' and do not have slideshows of SVG pictures of animals fading in and out.
I check for phone and tablets by looking at the page width and the 'user agent string'.
I have now speeded up my pages in other ways to almost run these animations fine on a mobile or tablet
reducing the number of HTML elements had the biggest impact when speeding up my web pages
I had a 'span
' around every letter to pass rainbow colors through the text. Now 'below the fold' it is only each line that has a different color.
I have about 1000 tips on my tips page. I have lots of links, lots of 'abbr
' elements and lots of 'spans
' to highlight phrases. I will have to split my tips page into lots of separate pages, one for each section.
It is as though when I change the colors, the browser checks through all the HTML elements to see if they are affected
'closures' may take up memory and sometimes slow things down
I split up a function and moved most of its functionality out of the page load, but then the page load seemed to take longer.
I used 'setTimeout
's calling 'inner functions' (or 'closures') within the original function.
The original function had large arrays of colours that I suppose had to be copied into the 'closures'.
I made these large arrays global variables so now the 'closures' need only 'capture' a reference to the arrays
I was wrongly testing for a tablet by searching for 'tablet
' in the 'user agent string'
I got the idea from a post on 'stackoverflow'.
But Internet Explorer 11 on Windows7 on a desktop has 'Tablet PC
' in the 'user agent string'.
I have gone back to my old regular expression for a tablet:
/android|ipad|playbook|silk|kindle|nook|bntv|xoom/i
I first test for a mobile with: /Mobi/i
'freehostingeu.com', the free webhosting site, gave the error '403: forbidden web page' because the page had the forbidden sting 'itAu'
'freehostingeu.com' has automatic content filtering.
The string was in the code 'webkitAudioContext
'.
'itAu' is a bank in Brazil and a unit of the FBI.
Other forbidden words have been: 'zynga.com', 'PROXY', 'porn'
Firefox may not support all the latest media queries
Firefox sometimes says 'hover
' and 'any-pointer: fine
' are 'false
' on a desktop PC with a mouse running Windows 7.
I was trying to test for a 'powerful computer'. Anyway, a tablet with a stylus would have a 'fine
' pointer. And, of course, the latest versions of Windows support 'touch'.
I am going back to testing for 'mobi
' in the 'user agent string'
all uppercase Windows filenames are converted to lowercase by my very old Linux system
I download files from 'openclipart.org' using the Windows computers at my library and upload them to my web hosting platform. But I make a list in my web page on my old Linux system whose 'vfat' file system driver converts all uppercase names to lowercase. So now the web page cannot find the lowercase files on the web server
using 'openclipart.org' reminded me that you do not have to be a Linux kernel developer to contribute to 'free software', 'open-source' software or 'creative-commons' media
A small number of artists have contributed lots of clip-art for free which is very good
the experience of the 'pixabay' website reminded me why I am nervous about putting my game into the 'public domain'
People were creating mirrors of 'pixabay' as the contents were in the 'public domain'.
Anyway, I cannont make my game totally 'public domain' as some of the animations are derived from those with an MIT license
I changed how I check for a 'powerful computer' in JavaScript to use a 'media query'
I check for a wide screen and a 'fine' pointer like a mouse:
var windowMatchMedia = window.matchMedia;
if (windowMatchMedia) {
var mediaQuery =
windowMatchMedia(
'screen and (min-width: 700px) and (any-pointer: fine)');
if (mediaQuery.matches) {
return true;
}
}
At first, I wrongly put brackets around the whole 'media query'.
I used to check the 'window.innerWidth
' and look for the string 'mobi
' in the 'user agent string'.
I find it best when timing page loads to start Chrome afresh and in 'incognito' mode and write down the results.
I got confusing results when I left browser tabs open with previous results.
I exaggerate the results by throttling the CPU six times and disabling the cache
I once got the famous error message "you don't exist
" after I deleted '/etc/passwd
' by mistake
surprisingly, I am always the user 'root
' on my Linux system
This is because I need to be 'root
' to run my 'X Windows' system which I built from source. Something went wrong with the permissions.
I once started deleting my system by typing 'rm -rf /
' by mistake. But I stopped it and recovered the files from a backup. Otherwise, I have been OK using 'root
'
it may be a good idea to give (self-executing) anonymous functions a name to help with debugging and performance tuning
Also, I code very simply and use lots of intermediate variables that are not really needed. This lets me easily add 'alerts
' to show the values of the variables. This is how I debug on my 10-year old browser. My browser crashes when I use the debugger. Of course, code runs a little quicker if you do not use intermediate variables.
I wanted to check for a powerful desktop computer
My code passes a rainbow through the letters of the text and runs badly when I mimick a mobile by throttling the CPU in Chrome's 'developer tools'. There are hundreds of 'spans
' around the letters and each letter has a CSS transition.
Just checking the page width works surprisingly well. I check if 'window.innerWidth
' is greater than 700. The page width of an old computer in the library is just above 700 with the 'developer tools' pane showing. Both the 'Lighthouse' tool and Google's mobile testing tool are fine with this.
I then exclude mobile phones by simply searching for 'Mobi
' (case doesn't matter) in the 'userAgent
' string. The Mozilla documentation suggests this. I do use the large regular expression from 'detectmobilebrowser.com' in my game. But this has not been updated since 2014, so I don't use it here. However, there must be a reason why commercial websites check the 'userAgent
' against large databases of mobile 'userAgent
' strings.
I could almost exclude tablets by just also checking for the word 'android
' (case doesn't matter). But I noticed that Kindles do not have 'android
' or 'mobile
' in their 'userAgent
' strings. So I use an old catch-all test for tablets:
/tablet|android|ipad|playbook|silk|kindle|nook|bntv|xoom/i
Of course you are really meant to check some feature of the brower or perhaps time something.
There is a long post at 'stackoverflow' about detecting mobiles.
It is true what Google says about not having too many HTML elements on a page
I had a page with over 20,000 elements which took 4 seconds to load when I reduced the CPU by 4 times using the Chrome 'developer tools', to be like a mobile phone.
The page takes 2.5 seconds to load when I remove the 20,000 elements. Also, there are now less 'long-running tasks' where I change the color of text at intervals after the page has loaded. I suppose there are now less elements to check if the color change applies to them.
I can 'format' my 64 gigabyte memory stick by running 'format /FS:FAT32 E:
' from Windows7's 'powershell'. But it will take over 2 hours
Windows7 will not let me use 'fat32' if I right-click on the drive icon. I need to use 'fat32' so my very old Linux system can recognise the format of my memory stick.
I cannot run other quicker formatting programs as the computers in my libraries stop this.
I have file-system errors on my memory stick that Windows cannot fix
sometimes with my old browser I need a short delay before I can 'focus
' on an HTML element
I use 'setTimeout(f, 100)
'.
The delay is needed after I have made the element visible with JavaScript. I suppose the browser wants to render the element before it sets the 'focus
' to the element.
Chrome and Firefox do not need the delay.
Adding a short delay fixes all sorts of problems
I had to 'format' my memory stick to get rid of the file-system errors
Windows could not fix all the file-system errors.
Quick 'formatting' my memory stick took a few seconds. I had spent several hours removing files and fixing most of the errors
Chrome struggles to render CSS 'transitions' of the colors of lots of HTML elements
I pass a rainbow of colors through the letters of the words on a page. I put 'span
' elements around each letter and change the color of each letter about every 3 seconds. These 'spans
' have a CSS class which has a CSS 'transition
' so the colors change smoothly.
But I see lots of red warnings in the 'performance' tab of Chrome's 'developer tools'. The color 'transitions' mean there are constant 'long running tasks' of over 100 milliseconds where a third of the time is scripting and two-thirds rendering the CSS.
I am going to fix this by having the 'transition' CSS rule on only a few sentences in the introduction
I read a good old book about blogging: 'The Million Dollar Blog' by Natasha Courtenay-Smith
I got it from my local library.
(I read that the man behind 'Silk Road' was caught in a library)
I am going to have to delete most of the files on my memory stick which has file system errors so that Windows can fix the errors in under an hour
I got the errors when, after copying lots of files, I typed 'sync
', which seemed to hang, so I killed (-9
) the sync. I should have waited for the 'sync
' to finish
I deleted a 'postgres' directory when I should have renamed it and waited a few weeks to see if I needed it
Part of my browser was linked to a 'postgres' library which I deleted. My browser is now missing a panel.
I wanted to free up some space.
'postgres' is a free database but I have not used it for a while
there are some top quality SVG's of flowers by Juan Pablo Enrici at: 'openclipart.org/artist/jpenrici
'
The SVG's are free and in the public domain
I am going to keep open the 'console' part of the 'developer tools' window in Chrome in future as I missed an error in a page
One of the libraries I go to has wide screens so there is space for the 'developer tools' and a narrowed main window
I decided to put the initial 'focus' on my 'start game' button so I can just press 'Return' to start a game
I used 'element.focus()
'. I did not use the HTML 'autofocus
' as later I am goind to change the 'focus' to other HTML elements.
It seems that setting the 'focus' can be bad for 'accessibility' as the 'focus' jumps around and may even scroll the page
I lost the 'redirect' from my old free website at '000webhost.com' pointing to my new paid website at 'Hostinger'
'000webhost.com' had deleted my account and old website. I switched about 9 months ago. I had not used my old account since switching. Maybe I should have logged in regularly to '000webhost.com'.
I get the message 'The authors have deleted this site' when I try and access my old website.
Messages in the '000webhost.com' forum say '000webhost.com' may delete accounts where you have not logged in to the 'control panel' for 3 months or even 7 days.
'000webhost.com' say they send a warning email, but this may be treated as spam and not show up. I did not see an email from '000webhost.com' in my 'gmail' account.
I had a website with '000webhost.com' for abount 7 years. I would recommend '000webhost.com' as long as you are ready to put up with the many ups and down.
The cheap four-year deal I took at 'Hostinger' seems increasinly good value if we both last 4 years
some of the SVG's from 'openclipart.org' look better in a smaller size
Some of these SVG's look a bit crude in a larger size
I am going to run 'ls -R
' on my backups and look for errors
Before, I was just checking two key files and missed some errors.
My memory stick with the backups has file-system errors where I turned off the power in the middle of a backup.
I make backups with 'cp -a
' to preserve timestamps on the files.
I also run 'ls -R /mnt/sd/bingo49 | grep error
' to find any errors
I noticed how nice it is that SVG's keep their 'aspect-ratio' and stay centred when they are resized
My SVG was in a 'div
' which had its width given as a percentage and its height given in 'ems
'. The 'div
' goes into some strange shapes when I resize the browser window, but the SVG still looks fine.
This contrasts with bitmap images which may be stretched and distorted to fit their container.
You can even specify how exactly you want the 'aspect-ratio' of SVG's to be preserved
I forgot about the 'load
' and 'error
' events when setting the 'src
' of an 'img
' tag with JavaScript
I was fading in the image before it had been loaded.
I also forgot to set the 'error
' event to 'null
' in the error handler. The page went into a loop and Chrome crashed.
I also found I had to reset the 'error
' event in the handler for the 'load
' event
I decided to add pictures of animals to some of my pages
This is like the covers of old 'O'Reilly' books.
This helps brighten up dry subjects like my lists of changes and credits.
I get the pictures from 'openclipart.org'.
I go through a list of pictures, fading them in and out.
There is a good quick up-to-date introduction to SVG at:
There is a much more detailed tutorial at:
A little of this is out of date and I found it hard going.
I read a thought-provoking book: 'Surveillance Valley' by Yasha Levine
The author says the internet started with the ARPANET, used by the U.S. military. The author says this was used for counter-insurgency work in Vietnam. The author says ARPANET was used to share data on protests in the U.S.
The author says Edward Snowden leaked details of the PRISM project showing that companies such as Google and Facebook worked with the U.S. government to give the government direct access to all the very detailed information these companies hold about you.
The author says the 'Tor' project is mainly funded by the U.S. government to encourage regime change in hostile countries. The author says Tor has holes in it. The author says the U.S. government can get around Tor and Signal by hacking your mobile phone.
The author says Tor and Signal give people a false sense of security and so prevents the regulation of Google and Facebook's data collection.
I got the book from my local library
It is good to have a dream even if it does not come true
Ten years ago, when I started writing my game, I hoped it might lead to some work.
My aim was to learn the language and have something to show for it.
I do not think it will lead to any work. My concentration and eyesight are poor.
But it is good to have a hobby. It takes your mind off your worries.
But I have become very shy spending so much time on my computer.
I support browsers until they are no longer used in the libraries I go to
Until a frew years before Covid, my local libraries had Internet Explorer 6 running on Windows XP.
Now, just after Covid, most of my local libraries have Internet Explorer 11 running on Windows 7.
One branch of my local libraries has just got new computers with the Edge browser.
My libraries also have Chrome and sometimes Firefox.
Web pages load slowly and animations are not smooth on the old library computers.
I have a library card for a neighbouring area where I used to work, so I use their computer too
'JSMin' cuts off the end of my regular expression: /bbingo\.xyz\/.*[^\/].*\//i
JSMin thinks there is a comment, //
, at the end. But Chrome just sees the regular expression.
I changed it to: /bbingo\.xyz\/.*[^\/].*[\/]/i
The regular expression ohecks if the file is in a sub-directory of my website 'bbingo.xyz
'. It looks for 2 slashes with something that is not a slash in-between. I check 'window.location
' against this regular expression.
An address of 'bbingo.xyz/t
' gets changed to 'bbingo.xyz/t/
' somehow.
JSMin is a simple 'minifier', removing comments and spaces
I think I have finally found a way to nicely animate a flag to make it look as if it is blowing in the wind
I can use SVG SMIL animations and the 'feTurbulence
' and 'feDisplacementMap
' filters.
I got the idea from an answer to a question on Stack Overflow.
I don't think this will run on the GPU though
I am going to create sub-directories in my 'images
' directory on the web-server
I should have done this sooner.
For example, I will have a sub-directory 'birds
' for SVG's of birds.
There are too many files in the 'images
' directory which might slow access to the files.
I might also have different files with the same name. I am collecting lots of SVG files from other websites and some just have a long number as a name like '1442343646.svg
'.
I created sub-directories for my sound files using the first letter of the filename. But there are still too many files in some of these sub-directories. I got this idea from the layout of Linux 'terminfo' files.
the number of downloads of my game from 'Sourceforge' varies more than it used to
Sometimes I panic when there are no downloads in a week. But then the downloads get into double figures which is very good for me
Sometimes I forget that there are other downloads from other sites such as 'download.com'
sometimes I think my game might be more popular if it ran nicely on mobiles as well as the desktop
Sometimes I think of 'xearth' a beautiful animated background of the sun shining on the Earth. It runs on 'X Windows' which is less popular these days.
I was hoping that the screen sizes on mobiles would one day be large enough to run the tablet version of my game
find a method of developing that suits you and your circumstances
During the covid lockdowns, I programmed for several hours during the night, attempting big tasks. Now, I code a little at a time, maybe for 20 minutes at a time and just an hour in total in an evening
I have seen the trend for 'agile' development come and go. Object-orientated development was popular, now less so
when writing code, you keep it simple and get something working quickly. Graphic design and art takes much longer
I am probably going to spend a year working on an animation. I have spent several months working on a coloured background for my game
another way to add a tip to an inline SVG is put the SVG in a 'div
' element and put the tip on the 'div
'
if I want a tip on an inline SVG then I have to add a 'title
' tag to the SVG
I make sure the 'title
' tag is the first child of the SVG. This is to work with old versions of SVG.
I dynamically add the 'title
' tag to the SVG:
var titleElement = document.createElementNS(
'http://www.w3.org/2000/svg',
'title');
titleElement.innerHTML = freedomSaying;
internalIndexImage.insertBefore(
titleElement, internalIndexImage.firstChild);
It seems I have to use 'createElementNS
'
the tags are formatted nicely by some drawing programs that generate SVG
The end of the tag is on a separate line making it easier to add and remove attributes:
<svg
id="svg2"
version="1.1"
>
I may try this for my HTML tags
maybe there is a limit to the magic of the GPU (perhaps the memory of the PC and GPU)
A JavaScript animation of the color of text (using 'setTimeout
') stuttered when I had 2 CSS animations of the opacity of the background of the whole page and the opacity of an image taking up about a quarter of the page.
The 2 CSS animations should run on the GPU but the JavaScript text animation will not run on the GPU.
I change the opacity to just fade in and out different 'radial gradients' on the background of the page and to fade in and out the different images.
This was on a modest PC in my local public library.
I improved things by changing the animation of the image to just change the opacity briefly at the start and end of the animation rather than all the way through the animation
I am going to use small 10 gigabyte memory sticks for backups
I takes too long to check and fix the file system on my 64 gigabyte memoery stick
it really is best to check if you can restore from your backups, like people say
I was clearing out old backups on a memory stick and found I could not delete some because the file system was corrupt
I read a good book: 'Facebook The Inside Story' by Steven Levy
I found it in the business section of my local public library.
It is a bit biased as it was written with the cooperation of Facebook
Facebook wrote its mobile app in native code after first trying HTML5
I like the 'easeOutBack' easing function on 'easings.net'
I use this easing function on an animation of a spider. The spider comes down the screen, slowly stops and then bounces back up a it
if I 'move fast and break things' then I worry when things go wrong
This is one of Facebook's mottoes.
Other Facebook slogans have been:
'wikiquote.org' has some good quotes with a Creative Commons license
'brainyquote.com' has better quotes but they are only free to use for personal use
I fade in and out the coloured backgrounds of my pages because the lightness of the colours is different on the computers I use
This means the coloured background is not too dark for too long.
I vary the 'opacity
' in a CSS animation. The backgrounds are radial gradients. The lightness is different on the computers in the two libraries that I go to
I have started using 'hsl' (hue, staturation and lightness) colours a little
Here is a color wheel:
background: conic-gradient(
hsl(360, 100%, 50%),
hsl(315, 100%, 50%),
hsl(270, 100%, 50%),
hsl(225, 100%, 50%),
hsl(180, 100%, 50%),
hsl(135, 100%, 50%),
hsl(90, 100%, 50%),
hsl(45, 100%, 50%),
hsl(0, 100%, 50%)
);
I wrongly changed 2D 'transforms' to 3D ones in a CSS animation to get them to run on the GPU
It seems 'transforms' and 'opacity
' in a CSS animation always run on the GPU.
Forcing JavaScript animations onto the GPU may slow them down as the CPU has to build a picture and send it to the GPU using lots of memory
I thought I would have some fun colouring and animating the text and background of my web pages as not many people look at them
I am also going to animate the 'title
' of the pages as they do not appear high up in the rankings of search engines anyway.
I am also going to add some SVG pictures that I like
I wrongly assumed my game would always have a white background
I had lightened colours by reducing the opacity in 'rgba
' colours. I had made the shape of the thorns of a rose by overlaying white blocks.
I now have a background made of light coloured 'radial gradients'
there are 'conic-gradient
's in CSS
They are like 'radial gradients', but the colours change as you go round the centre point.
There is a lot more to 'radial gradients' than I realised, like 'farthest-corner
' and 'steps'
I added 'viewBox
' properties to a few SVG's that did not scale nicely
I set the dimensions of 'viewBox'
from the 'width
' and 'height
' properties.
The SVG's were the 'src
' of an 'img
' tag. I wanted to preserve the 'aspect ratio'
I used 'calc
' in CSS for the first time:
left: calc(50% + 10px)
and:
left: calc(100% - 0.2em)
I used the easing functions at 'easings.net' again
I read a good book about Artificial Intelligence (AI) going wrong
The book is 'You look like a thing and I love you' by Janelle Shane.
The book made me realise you can try out 'machine learning' for yourself these days. I am going to put my list of names into an AI and see what new names the AI comes up with
you can animate the title in the browser tab (or window title) by setting 'document.title
'
I first tried setting the 'innerHTML
' of the 'title
' tab, but this does not work in Chrome.
I put a smiley in the page title and slowly change it. If I change the title quickly then the browser tab (or window title) changes in length which is a bit distracting.
I have read it is bad form to animate the page title.
I got the the list of smileys from the Linux 'smiley
' program
I simulate 100,000 games of bingo to find out the average number of balls to get a 'line' or 'house' for a given number of players. But only about 1000 games are needed
I read a good book about Cambridge Analytica using data from Facebook to target ads at specific groups of people and help elect Donald Trump and promote Brexit
The book is 'Mindf*ck' by Christopher Wylie, the whistleblower.
You probably would not use Facebook after reading this book, at least with your real name
I added an SVG landscape as background to the first page of my game
I first looked at the SVG's at 'freesvg.org'. But the SVG's come from 'openclipart.org' so I looked there as well. The 'freesvg.org' website was created when 'penclipart.org' was under attack and unavailable. The 'openclipart.org' website is sometimes slow to load its images on the old computers in my library.
Some of the SVG's on 'openclipart.org' are based on images at 'pixabay.com' which seems a good website for free images, videos and music.
I added 'preserveAspectRatio="none"
' to the 'svg
' tag to make the SVG's fill up the whole screen. In the CSS, I had 'width: 100%; height: 100%
'.
I said 'preserveAspectRatio="xMidYMax meet"
to scale an SVG keeping to the 'aspect ratio' and placing the SVG at the bottom of the screen.
I removed the 'inkscape
' and 'sodipodi
' tages to reduce the size of the SVG's I included inline in my game. I also include larger SVG's as external files using the 'src
' attribute of the 'img
' tag
it is a good idea to call 'preventDefault
' at the 'start' of a 'click
' event handler on a link, rather than at the 'end'
I had an error in my event handler that caused the handler to stop before it got to my call to 'preventDefault
' at the end of my handler. So the default action occured which meant the browser followed the link which loaded another page.
I also put a 'try catch
' construct around my event handler's code, just to be sure no error pops out
my paid hosting provider 'Hostinger' is not perfect
Sometimes my pages don't load first time and I have to reload.
But the service is not down for days like their free hosting '000webhost.com'
my paid hosting provider 'Hostinger' lets me look at the 'access logs' from their webserver
I was surprised to find someone actually playing my online game. I thought nobody played it apart from me
Chrome lets you change the 'title
' tip of an HTML element whilst the tip is shown
I change the 'title
' from JavaScript.
Chrome fades out the old value for the 'title
' and fades in the new value, taking about a second. So if I update the title every second, the title seems to flash.
Firefox and Internet Explorer 11 do not show the change to the 'title
'
I am going to update the 'title
' on a progress bar with the current value which changes about every 3 seconds
I set 'pointer-events: none
' in CSS to let mouse clicks pass through an HTML element
For example, I am working on an animation of a ladybird. The ladybird sits on a 'stage' that completely covers the screen. This is partly so I can say 'overflow: hidden
' in the CSS so I do not get scrollbars when the ladybird flies off the screen. But the ladybird is in front of the rest of the page. The 'stage' would stop me clicking on items behind the 'stage'. So I put 'pointer-events: none
' on the 'stage' and now mouse events pass through to elements behind the 'stage'
The value for 'pointer-events
' is inherited by child elements.
I say 'pointer-events: auto
' on the ladybird so that its 'title
' tip is shown when the mouse is over it
Chrome crashed when I tried to change the colors of 25000 'spans
'
Chrome gave me the 'aw snap' message.
I had put 'span
' elements around all the text on a page, so I could pass a rainbow through the letters. I only changed the colors every 3 seonds.
However, Chrome was still responsive with all the 'spans
', letting me scroll through the page. Whereas, with Firefox, the scrolling was sluggish. Even without changing the colors, the scrolling stuttered on Firefox.
I decided to just color the text in the first few sections at the top of the page
my very old Konqueror browser does not create a 'text node' when there are spaces and a newline between a 'table
' tag and its 'caption
' tag
Chrome, Firefox do create a 'text node'.
I squashed up the HTML by removing the spaces and newlines.
I was trying to navigate the nodes using 'firstChild
' and 'nextSibling
'.
The same thing seems to happen between 'thead
' and 'tr
' tags
there were no downloads of my game on Sourceforge one week
But Chrome said the SSL certificate of 'Sourceforge' was invalid. You needed to choose the 'advanced' option on Chrome to download my game
all plain text in a sequence is put into one 'text node' in HTML even if it is across several lines
I put a few files on a memory stick so I could put live the next version of my game at short notice
I tried to only think about when I would go live when I was testing my game
I was worried about another lockdown closing the libraries where I access the internet
I did not fix most bugs that I found when testing a release
Instead I just added them to a list.
I wanted to make the release as soon as possible.
I will have more time later to better fix the bugs. I did fix a few easy bugs, but I did not include the changes in the release.
Some of the books I have read say that users want to see quick improvements even if there are some bugs left in
I read a thought-provoking book about how companies on the internet collect data about you
The book is 'The Trust Manifesto' by Damian Bradfield, co-founder of 'WeTransfer'. I borrowed it from my local library.
He says you do not need to be a bad company to be successful on the internet. It made me think about why people write Free Software
I find background music with a bit of a beat and insistent tone is best
Some of the classical music is too gentle and does not show up against the sound of the caller reading out the numbers.
Some of the free classical music from the 'musopen.org' website varies a lot in volume
a good book suggests writing passwords down in a notebook kept at home
But the book says it is better to use a 'password manager'.
The idea is to avoid reusing simple passwords that are easy to remember.
The books suggests using a simple transformation such as changing lowercase to uppercase and vice-versa.
The book suggests keeping the notebook in a locked drawer.
I write down my passwords on a piece of card I keep in my bag which I take with me everywhere. I have left it by mistake in the library and nothing happened.
The book is 'Confident Cyber Security' by Jessica Barker
my very old Konqueror browser puts tag names in uppercase when I look at the 'innerHTML
'
Chrome, Firefox and Internet Explorer leave them in lowercase
I bought the domain name of my website for one pound from 'NameCheap.com' but it costs ten pounds a year to renew
I got a 'Bad Request
', '400
' error when using Ajax on my hosting provider, 'Hostinger'. This was because I had a range header of '0-
'
I had added the range header to try to stop Firefox getting partial content.
I did not get the error from their free hosting service, '000webhost.com'. Maybe the free and paid hosting use different web servers. 'Hostinger' uses the 'LiteSpeed' web server whereas '000webhost.com' probably use Apache
I use 'ftp' in the file manager on Windows7
I type 'ftp://
' in the address bar.
It says the passwords are sent as plain text.
The file managers of my hosting provider 'Hostinger' do not always work, so I use 'ftp'
I bought the domain name of my website from 'NameCheap.com' because they provide better privacy. The contact details on the 'whois' record are their registars and not mine
You can find out the name, address, phone number and email of the owner of a website by looking at the 'whois' record.
I tried to buy the domain name from my hosting provider, 'Hostinger', but the registrar rejected my contact details as I had made them up. Hostinger offer to keep your contact details private, but the details can still slip out. Hostinger charge for this.
I 'pointed' my domain name on 'NameCheap.com>' to my hosting provider, 'Hostinger', by setting the 'domain name servers' in NameCheap's records to be the 'domain name servers' of 'Hostinger'. I then let 'Hostinger' know and they adjusted their records too. The changes then propagated across the internet. I did try to 'transfer' my domain name but this is the wrong thing. I also tried to set a 'personal name server' but this is wrong too.
NameCheap.com are keen for you to use two-factor authentification to access you account, like an online bank.
Hostinger's starter hosting plan is a little cheaper than NameCheap.com's. I paid for four years hosting to get the best price. After all, I have used their free hosting, '000webhost.com', for ten years.
Hostinger copied all my files (200 megabytes) from their free hosting service, '000webhost.com'. I asked their helpdesk to do it. It would have taken me months to do this myself. The helpdesk also re-directed my website on '000webhost.com' to my website on Hostinger
if I put curly quotes in HTML, like '&#8220;line&#8221;'
, then the 'innerHTML
' shows a single quote character for each curly quote
But Chrome and Firefox leave a '&nbsp;'
in the 'innerHTML
' as it is in the HTML. These browsers show the corresponding Unicode character '&#160;'
as '&nbsp;'
in the 'innerHTML
'. My very old Konqueror shows both types of '&nbsp;'
as just a space in the 'innerHTML
'
my free hosting provider '000webhost.com' said my account was blocked due to a third-party complaint
My website said it was sleeping.
I emailed the moderator. I did not send the identity documents they wanted.
After a few days the account was OK again.
The moderator said I had exceeded the 300 megabyte limit on disk space. I had not. But I have 'MP3' and zip files which the moderator said are not allowed.
I cannot see any mention of 'MP3' and 'zip' files in the terms of service of '000webhost.com'. There is a clause where you agree not to infringe the rights of other people.
I think I will upgrade to a paid plan. If people play the online game with sound then the bandwidth limit can be exceeded. The sound is played from lots of small files. Maybe I lost my nerve as my account on '000webhost' works fine now
if a game is to be successful then it has to be one of the best in the world, which is quite hard to do
I try not to hurry
During the lockdown I had lots of time.
I have the rest of my life to make changes to my game
sometimes I 'kill
' my old browser when I am finished
My browser can take a few minutes to exit after playing my game which is about 10 megabytes in size. Maybe Linux is swapping out memory. I only have 128 megabytes memory on my 20 year old computer.
I have to remove files from my browser in '/tmp
' afterwards
I failed the LinkedIn JavaScript quiz, even after 10 years of coding in JavaScript
I was not able to get a badge because I do not use new features of JavaScript like 'map
', 'export
' and 'static
'.
My browser is over 10 years old and my computer is over 20 years old.
Still, my experience shows you do not need to use the new features of JavaScript.
There are answers to the quiz on the web. But the answers did not seem completely up-to-date
I got lots of errors when I put the output of the 'UglifyJS' minifier through the 'JSHint' code analyser
There were lots of missing semicolons. I suppose the output of 'UglifyJS' does not follow the style rules of 'JSHint'.
I was able to get a list of undefined variables from 'JSHint' by adding more 'relax' options and inreasing the maximum number of warnings. I usually mean the undefined (global) variables to be faster local variables.
The source code of my game (about 10 megabytes) is now too large for the online JSHint', even if I first put the source code through 'JSMin' to squash up white space.
Missing semicolons can stop the output of 'UglifyJS' from running. 'UglifyJS' removes all newlines which may mark the end of statements. So I wrote a program to remove most newlines from the source code. This shows up missing semicolons when the game is run. Normally 'JSHint' would point out the missing semicolons
you can pass anything as a parameter to the function 'clearTimeout
'
This is useful if you are not sure if you have already cleared a timeout - you can just call 'clearTimeout
' on the timeout anyway
I used to use very long names for variable and functions but the code was difficult to read, especially when the lines were wrapped in my editor
For example:
if (this.showingWarningAboutMissingoutPlayersWhenTooManyHouseOrL
ines) {
this.selectorForTextColorOfWarningAboutMissingoutPlayersWhen
TooManyHouseOrLines.setRandomStart();
if (animatetextColor) {
this.addTextColorToWarningAboutMissingoutPlayersWhenTooM
anyHouseOrLines.setColor();
}
}
Now I use shorter names, like people recommend. For example:
_.addTextColorsToWarnPressIBoxContBut =
This would have been:
_.addTextColorsToWarningToPressInformationBoxContinueButton =
Of course, the shorter names are less descriptive
I changed most of the black text in my game to color
I thought it is a game and should be fun so I use color.
I try to have the text always changing color. I try to use CSS transitions. It is hard to use transitions if the text also has a 'hover
' color where you want an immediate change in color. So sometimes I just use my own detailed rainbows rather than using a transition.
Sometimes you see the transition on the first change from black to a color. So I have a small delay before adding the stylesheet with the transition, using a 'setTimeout
'.
I use simple 'setTimeout
's to loop and keep changing the colors.
Sometimes I color each letter in the text differently. I dynamically add HTML 'spans
' around each letter.
Even my old browser is quick to change colors. I suppose browsers do not need to reflow the layout. I use closures to hold onto the HTML elements and colors to keep things quick
I tried programming at night during the summer
I wrote some amazing code but I found it difficult to sleep in the morning because of noise from the neighbours, workmen and dustmen
you can use percentages in 'rgb
' colours, even fractions
For example: 'rgb(100%,50.5%,100%)
'
I have been reading some PDF's of old books I found free on the web:
'CSS The Definitive Guide' by Eric A. Meyer
Surprisingly readable despite going into great detail
'CSS Cookbook' by Christopher Schmitt
This gave me lots of ideas and includes a U.S. flag made with CSS
'The CSS3 Anthology' by Rachel Andrew
An introduction to CSS. Fond memories for me as this is where I started
'Smashing CSS3' by Eric Meyer
A more advanced guide to CSS, surprisingly up-to-date
'Best of Nine Smashing Years' from Smashing magazine
A variety of articles. I liked the one on the psychology of web design
'Maintainable JavaScript' by Nicholas C. Zakas
Some interesting parts despite being meant for large projects
'Programming the Mobile Web' by Maximiliano Firtman
I wish I had read this before developing a version of my game for tablets
I used Google search. Watch out for traps: maybe just click on PDF's not links or buttons. Of course, you are really meant to buy the books
I use the SVG attribute 'overflow: visible
' in the CSS to animate parts of an SVG to be outside the SVG container using the CSS 'translate
' transform
CSS animations using 'vw
' and 'vh
' units adapt if you resize the browser. The animations run on the GPU. But the animations take a bit longer to finish after being resized
I could not restart a CSS animation on Firefox
The HTML was fixed.
One solution is to have 2 identical 'keyframe
s' and change the animation name to alternate between the 'keyframe
s'.
Another solution is to 'clone' the HTML and remove the original HTML.
Setting the element's 'offsetWidth
' to itself did not work
with Internet Explorer, if you select a link with an 'access key' and the link has 'text-decoration
' set to none, then sometimes no outline appears on the link
The outline reminds you to press 'Enter' to activate the link
Internet Explorer sometimes freezes for a few seconds on Windows7 when playing a series of short sounds held on a slow memory stick using the 'audio
' tag
It seems Internet Explorer can freeze when using 'add-ons'.
The 'audio
' tag is meant to run asynchronously
I had to use 'createElementNS
' to create an SVG and 'use
' element in JavaScript
Setting attributes of the 'style
' property of the SVG element had no effect. So I put the SVG in a 'div
' and set the 'style
' of the 'div
'
a 'long press' on a link on an iPad brings up a menu with more details and a preview. You can disable this in CSS with: '-webkit-touch-callout: none
'
I had some 'dummy' links with a 'click
' event handler to override the default action. But the 'long press' menu lets you go to the default action. The 'dummy' links were for 'access keys'
Chrome will not run a transform such as 'translate3d
' on the GPU if there is a 'percent' size
You can see this by running a long loop after starting the animation. This test does not work on Firefox which freezes everything.
Chrome will however run transforms on the GPU when sizes are in 'em
', 'vh
', 'vw
', 'vmin
' and 'vmax
' units
Internet Explorer does not support CSS transforms on SVG elements like 'path
' and 'polygon
'
To get the SVG transform to run again on Firefox, I had to 'clone' the SVG. I forgot to attach events
if you know someone's email password, you may be able to reset their Facebook, Twitter, LinkedIn etc passwords
sometimes the text wraps badly at the end of the line when the text is in a 'div
' with a 'crossmark' in a 'div
' floating on the right of the text 'div
'
If I change the 'div
' for the text to a 'span
' then the text wraps correctly. I then put the text and 'crossmark' in a 'div
' so other HTML elements flow around correctly
letters with accents in my text editor appear as question marks in Chrome
I think I should convert the letters to HTML 'entities'
if I have a width and height in CSS that is half the size of the 'viewbox
' of an inline SVG, then I have to double the size of a 'translate3d
' transform in CSS
Scaling SVG's can be complicated
sometimes I cannot access my hosting provider '000webhost.com' from Chrome, but I can with IE
Chrome says '000webhost.com' 'closed the connection'.
Once I get into '000webhost.com' with IE, then I can usually get in with Chrome
I sometimes use 'prompt
' for simple debugging, in addition to 'alert
' and setting the background colour
(The debugger with my old Konqueror browser freezes. I built it myself from scratch and the multi-threading went wrong)
in the summer, my flat gets the sun in late afternoon, so after work I go to the park and stay in the shade
It is probably good to have a break from programming
if I aim to do a little programming in the evening, then I usually end up doing a lot more
I tried developing in a 'prototyping' or 'agile' way, but I found lots of bugs when doing the final testing for the release
The code is a mess too
it is simpler to use the shorthand 'animation
' property in JavaScript rather than setting 'animation-duration
', 'animation-delay
' and so on
You could set constant animation properties in a stylesheet and dynamic properties in JavaScript. I find this too complicated
Google's search encourages you to put some JSON-LD of a simple 'Product
' in you web pages
The 'Product
' has a 'Review
', 'AggregateRating
' and some images. These may be displayed in the search results
if I make a prototype then I make a list of things to tidy up afterwards
I changed the description of my game on 'Sourceforge' to 'Relax with an eccentric game...'. But then nobody downloaded the game
So I changed the description back to the plain: 'Play a game of 90 ball bingo...'.
I had given up on appearing in google's rankings
I can code more complex programs if I code a bit, test it, and then take a break until the next day
to make a shadow of a complex shape, you can repeat the HTML of the shape, slightly offset, with a grey background
Bitcoin took a few years to become popular
One breakthrough came when they had a good new version and announced it on 'slashdot.org'. I read about it in the book 'Digital Gold' by Nathaniel Popper. I have waited ten years for my game to become popular.
The people who wrote the original code for the Mt Gox exchange and Silk Road website were gifted amateurs, not experienced programmers with degrees in computer science. So there is hope for me after all
The website 'download.com' comes near the top of the rankings on Google's search and Bing for games like mine
'download.com' claims over 400 downloads of my game. I only get a few downloads a week on 'Sourceforge'. 'download.com' have written their own descriptions of my game.
Google's search puts my entry on 'libregamewiki.org' near the top of its rankings
there is a bug with 'backface-visibility
' in a 'card flip' animation on Chrome. The back does not show where text is positioned 'absolute
' and the card is positioned 'relative
'
A work-around is to use 'opacity
' instead of 'backface-visibility
'. The 'keyframe
' for the front face is:
@keyframes cfAnRotateXby360ForChrome {
0% { opacity: 1; }
24.9% { opacity: 1; }
25.0% { opacity: 0; }
74.9% { opacity: 0; }
75.0% { opacity: 1; }
100% {
transform: rotateX(360deg) translate3d(0,0,0);
opacity: 1;
}
}
I had to set the 'easing
' function to 'linear
'
on Internet Explorer 11, an animation did not work when I added the 'keyframe
' after the element was shown
I solved this by showing the element after I add the 'keyframe
'
it seems iPads now pretend to be Macs
The 'user agent string' for an iPad says 'Macintosh
' not 'iPad
'.
I test for 'touch events' to see if the Mac is an iPad
I now release a new version in small steps over a few weeks. I update a few files each day and make an announcement when I have finished.
I use to do a release all at once, over several hours. But I got a bit stressed out and made mistakes
Chrome says there is not enough contrast in my headings of red text on an white background
I use the 'audit' feature of the 'developer tools'
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 'margin-top
'
it seems you cannot use font sizes less than the default to be mobile friendly, according to the 'audit' 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: 'translate3d(100%,0,0)
'
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 'start' menu
I had a bug, but Chrome carried on, creating duplicate 'input
' fields
I found the bug by looking at the console in the 'developer tools'
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 'stroke-dashoffset
'
I use the 'Text to Path' option in the 'Layer' menu. In the 'Path' tab on the 'Layer' dialog, I right click and choose 'Export Path'. I have an old copy of 'GIMP'
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) {
playPromise.then(null).catch(null);
}
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 'keyframes
'.
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];
headElement.appendChild(stylesheet);
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.
JavaScript uses garbage collection for objects. Apparently browsers use a 'mark and sweep' method rather 'reference counting' as counting has trouble handling circular references.
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 Array()
:
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 be 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: 'r();'
.
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 'superclass
' property of objects. Browsers seem to support it. It is like normal inheritance and much easier but goes against the spirit of JavaScript.
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();
r();
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 'undefined
'
So you can test if optional arguments are given by seeing if they are not 'undefined
' rather than checking 'arguments.length
'
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 };
myFunction(params);
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 setTimeout()
.
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 'event.srcElement
'
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 'alert()
'
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 +
y;
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 'undefined
'
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 'alert
'
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 '$a
'
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 '0
'
the online 'Google Closure Compiler' with the 'advanced' option gives lots of warnings when I add functions to the prototype of Array
, 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 'document.formName.radioGroupName[radioIndex]
'
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 online compiler is no longer available in 2025.
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 '!1
'
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 'for(;;)
'
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 '1E4
'
changes ['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 '[1,2,]
'
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 'Math.max
'
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 'setTimeout
'
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' 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!
You need a recent browser to run 'JSHint' on your computer rather than using the 'JSHint' website. 'JSHint' uses some recent JavaScript features like 'Object.create()
'.
'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
when my browser's JavaScript interpreter is out of memory, it cannot seem to start up the garbage collector to free memory that is no longer used
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
'assocArray.key'
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'] = [];
aa.push(3);
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;
alert(myClass.v);
myClass.f = function () { alert('hi'); }
myClass.f();
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 2
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 'undefined
'
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 'body
'.
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 ('
, ""
), 0
, null
, false
or 'undefined
'
you do not need to put brackets around the arguments to the 'typeof
' and 'instanceof
' operators.
It is really 'typeof v
' not 'typeof(v)
'
the 'const
' keyword does not work in all browsers.
I understand that it is not in the current JavaScript standard. It may have originated in the early Netscape browsers and may continue in current Mozilla-based browsers. It is not easy, and may be impossible, to make sure a variable does not change its value
I think saying 'for (var i = 0, j = 0; i < 3; i++) {}
' creates a variable ''j'
'.
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 'undefined
'
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
saying:
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
because:
undefined
', or give a value to JavaScript's 'undefined
' variableyou can use the first version with simple JavaScript variables that are not set
Also notice that:
null == undefined
is 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;
}
alert(x);
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
func(obj);
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:
array.concat(anotherArray)
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 'object
'
I thought it might be 'array
'
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
with Internet Explorer, if the page does not load because there are errors in the JavaScript, then you can find out more by double-clicking the warning icon in the left corner of the status bar of the browser
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 'push()
'
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 'String(something)
'
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 'toString()
'
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 'onclick
'
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 'Opera/9.8
'
The developers of Opera thought that 'Opera/10
' might be confused with 'Opera/1
'.
Opera 15 uses the 'Webkit' render. Previously Opera used its own 'Presto' renderer
if you shorten:
o.prototype.f = function() { }
var x
to:
o.prototype.f = function() { }var x
you get an error without a semicolon before the 'var
'
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() {}
this.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) {
crossrule=document.styleSheets[0].cssRules;
} else if (document.styleSheets[0].rules) {
crossrule=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:
(function(a,b)
{
if(
/(android|bb\d+|meego).+mobile
|avantgo|bada\/|blackberry| ... |phone)|xda|xiino/i
.test(a)
||
/1207|6310|6590| ... |your|zeto|zte\-/i
.test(a.substr(0,4))
) window.location=b
}
)
(navigator.userAgent||navigator.vendor||window.opera,
'http://detectmobilebrowser.com/mobile');
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 }
}
</style>
<script type="text/javascript">
testdiv = document.createElement('div'),
testdiv.id = 'touchTest';
document.body.appendChild(testdiv);
touchMediaRuleHasEffect = testdiv.offsetTop === 9;
document.body.removeChild(testdiv);
</script>
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 'setTimeout()
'
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 '&lt;' and '>' into '&gt;' as you do if you set 'innerHTML
'
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 'inherit
'
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 'getElementById
'
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
my browser crashes when the attribute of a CSS rule is changed from 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 'msTransform
'.
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 'border-top-right-radius
'
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 'k9
'
On Chrome and Firefox the 'valid
' property is 'false
'
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 into 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 'div
'
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 'slice
'.
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 browser, 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 'innerHTML
'
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 '&gt;
' 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 false
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 'undefined
'
function btmp()
{
return
3;
}
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 'window.g
'
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 'undefined
'
';;;
' 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) {
_privateMethod();
_privateArray.push(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) {
this.subscribers.push(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);
return;
}
}
},
publish: function(data) {
var i, len = this.subscribers.length;
for (i = 0; i < len; i++) {
this.subscribers[i](data);
}
}
};
var Observer = function (data) {
alert(data);
}
var observable = new Observable();
observable.subscribe(Observer);
observable.publish('hi');
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] = [];
this.topics[topic].push(listener);
},
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 on the web
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 'Resources' option of the 'Developer tools'
To get to the 'Developer tools' click on the three bars in the top right and choose 'More tools'
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 ||
window.mozIndexedDB;
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 + ': ' +
eventTargetError.message);
}
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;
createStore(db);
} 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 ||
window.mozIndexedDB;
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 + ': ' +
eventTargetError.message);
}
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 my 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 'Resources' option of the 'Developer tools' 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 'Array
'.
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 'atan
'
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 'file
'
You cannot read (or write) any file
it is hard to style an 'input
' field of type 'file
'
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 'D:
'
I could not hide an 'option
' tag in a 'select
' tag by setting 'display
' to 'none
'
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 'canvas
'
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 $4
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 'replace
'
'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 'innerHTML
'
you can write the character '\\u00A0
' as the shorter '\\xa0
'
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 'rotate3d
'.
You can say '1turn
' rather than '360deg
'
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');
element.appendChild(textElement);
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 'block
'.
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 'document.body.scrollTop
'
JavaScript won't redraw the screen until the script finishes or you pause with setTimeout()
or setInterval()
you cannot do really slick and fast animations with simple JavaScript and dynamic HTML without the browser becoming unresponsive or maybe missing out steps.
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 'div
'.
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 'setTimeout
'.
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 'offsetHeight
'
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 in 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 'auto
'.
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:
a
b c
whilst on Internet Explorer (IE), they appear as:
a c
b
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 'relative
'
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 'File' 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,
world'
is rendered as
'hello,world'
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 'float
ed' together
you can put '&nbsp;
' (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:
'<input>
<input>'
into:
'<input><input>'
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 'sections
'
I sometimes put '<' and '>' characters in the content of my web page when I should use '&lt;' and '&gt;'
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. '#section
')
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 '&ldquo;' and '&rdquo;'
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 '&#8220;' and '&#8221;'.
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 ('&hellip;' 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 'sed
'.
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 'disabled
'
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, 'Even Faster Web Sites' by Steve Souders, 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 '15%
'
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 'padding
'
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 'absolute
'
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:Browser Side ('em') Top/Bottom ('em') Internet Explorer 7 and before 0 0 Internet Explorer 9 and after 0.5 0.2 Webkit on MS Windows and Apple Mac 0.7 0.3 Firefox on MS Windows 0.4 0.2 Opera (Presto renderer before Webkit) 0.5 0.2 Other 0.3 0
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 'webkit
'
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,
endColorstr=#000000)
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 'linear-gradient
'
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
any box-shadow
's are rotated when you rotate an HTML element with a CSS 'transform
'
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 rotation with 'transform-origin
'
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 'div
'
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 around 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 'rotateY
'
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 'cellpadding="0"
'
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>
<table class="face back" cellspacing="0" cellpadding="0">
<tr> <td> b </td> </tr>
</table>
...
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 'span
'
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 'collapse
'
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 'collapse
'.
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 'filter:;
'
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 '-webkit-filter
'
This is on Windows7, May 2016
the 'blur
' CSS filter is my 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 'background-image
'
For example, my browser does not support 'linear-gradients
'
the W3C CSS 'validator' reports lots of errors where I use browser-specific prefixes and Internet Explorer's 'filters
'
when animating 'box-shadow
' on Internet Explorer 11, in the 'key-frame
' you need to set values at '0%
' and '100%
' as well as '50%
'
Internet Explorer 11 adds extra space at the top of the page when the HTML5 'header
' tag has a 'display
' of 'inline
'
Maybe this happens on old versions of Internet Explorer.
I do not want to use JavaScript and unknown tags are 'inline
'.
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 'sans-serif
'
'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 browser 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 'transitions
'
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 'keyframes
'
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 ':after
'
I put the outer 'div
' in another 'div
' with 'position
' of 'absolute
' to avoid content flowing round the 'relative
' outer 'div
'
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
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
', 'ended
'
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 'true
'
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 'play()
'
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';
audioElement.appendChild(oggSourceElement);
audioElement.appendChild(mp3SourceElement);
audioElement.play();
var myWindowAudioContext =
window.AudioContext || window.webkitAudioContext;
var audioContext = new myWindowAudioContext();
var audioSource =
audioContext.createMediaElementSource(
audioElement);
audioSource.connect(audioContext.destination);
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 '0-
'
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 'true
'
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 of 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
The Appvisor website closed in 2024
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
The Appvisor website closed in 2024
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 as '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 'CreativeWork
'
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 'Product
'
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" : "https://sourceforge.net/projects/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.org' 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
Several times, I thought they were bugs in the browser or the JavaScript interpreter, but they were typos
I use the free JavaScript guides: 'the FieldCommander JavaScript Reference Guide' and 'Danny Goodman's' 'JavaScript and Browser Objects Quick Reference'
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.
Your browser probably has a useful JavaScript debugger though.
(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. In 2025, 'saucelabs.com' only offered a free 28-day trial.
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. In 2025, 'saucelabs.com' only offered a free 28-day trial.
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 'alert
s'. 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 'saucelabs' cross-browser testing tool is very slow at displaying JavaScript alert boxes
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'
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 'mobile
'
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 alert
s 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 'obase=16
'
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
testing on Internet Explorer 8 picks up more JavaScript errors than my browser
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 Developer 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 'ghl756
'
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 GPL'with 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 browser 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:
s/rgb\(\s*(\d+),\s*(\d+),\s*(\d+)\)/sprintf("#%02x%02x%02x",$1,$2,$3)/eg;
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 '#fff
'.
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 '0.5
'
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 quite 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 'eu5.net
'
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 'index.html
'
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