patternjavascriptMinor
HTML5 / JavaScript Tic-Tac-Toe
Viewed 0 times
javascripttoetictachtml5
Problem
As an exercise, I decided to create a simple Tic-Tac-Toe game. It is Ruby on Rails based, but as for now I'm not using the server side for anything (I intend to build up on it in the future, though).
As I'm rather new with JavaScript, HTML5 and CSS, I'd like some feedback regarding what did I do wrong or what could be done better.
index.html.erb
tic_tac_toe.js
```
var tokenAttributeName = 'token';
var idAttributeName = 'id';
var circleTokenName = 'Circle';
var crossTokenName = 'Cross';
var noTokenName = 'None';
var circleColor = 'green';
var crossColor = 'red';
var fontColor = 'black';
var font = "bold 30px Helvetica";
var resetText = "Reset";
var hoverOnOpacity = 1.0;
var hoverOffOpacity = 0.75;
var highlightTime = 100;
var turn = circleTokenName;
var won = false;
$(document).ready(function() {
drawResetCanvas();
$('canvas#reset').click(function(e) {
location.reload();
});
$('canvas').hover(
function(e) {
var field = $(this);
field.animate({ opacity: hoverOnOpacity }, highlightTime);
},
function(e) {
var field = $(this);
field.animate({ opacity: hoverOffOpacity }, highlightTime);
});
$('canvas.field').click(function(e) {
var field = $(this);
var fieldId = field.attr(idAttributeName);
if (field.attr(tokenAttributeName) != noTokenName || won) {
return;
}
if (turn == circleTokenName) {
drawCircle(fieldId);
field.attr(tokenAttributeName, circleTokenName);
}
else {
drawCross(fieldId);
field.attr(tokenAttributeName, crossTokenName);
}
//field.animate({opacity: 1.0}, 0, function() { field.animate({opacity:0.75},2000)});
if (checkWin(turn)) {
alert(turn + ' won!');
won = true;
}
else if (checkDraw()) {
alert('Draw!');
};
turn = turn == circleTokenName ? crossTokenName : circleTokenName;
});
});
function checkWin(f
As I'm rather new with JavaScript, HTML5 and CSS, I'd like some feedback regarding what did I do wrong or what could be done better.
index.html.erb
tic_tac_toe.js
```
var tokenAttributeName = 'token';
var idAttributeName = 'id';
var circleTokenName = 'Circle';
var crossTokenName = 'Cross';
var noTokenName = 'None';
var circleColor = 'green';
var crossColor = 'red';
var fontColor = 'black';
var font = "bold 30px Helvetica";
var resetText = "Reset";
var hoverOnOpacity = 1.0;
var hoverOffOpacity = 0.75;
var highlightTime = 100;
var turn = circleTokenName;
var won = false;
$(document).ready(function() {
drawResetCanvas();
$('canvas#reset').click(function(e) {
location.reload();
});
$('canvas').hover(
function(e) {
var field = $(this);
field.animate({ opacity: hoverOnOpacity }, highlightTime);
},
function(e) {
var field = $(this);
field.animate({ opacity: hoverOffOpacity }, highlightTime);
});
$('canvas.field').click(function(e) {
var field = $(this);
var fieldId = field.attr(idAttributeName);
if (field.attr(tokenAttributeName) != noTokenName || won) {
return;
}
if (turn == circleTokenName) {
drawCircle(fieldId);
field.attr(tokenAttributeName, circleTokenName);
}
else {
drawCross(fieldId);
field.attr(tokenAttributeName, crossTokenName);
}
//field.animate({opacity: 1.0}, 0, function() { field.animate({opacity:0.75},2000)});
if (checkWin(turn)) {
alert(turn + ' won!');
won = true;
}
else if (checkDraw()) {
alert('Draw!');
};
turn = turn == circleTokenName ? crossTokenName : circleTokenName;
});
});
function checkWin(f
Solution
First, a (proper) HTML document looks like this:
Html, head, body, and title are strongly recommended, tho not required.
You seem to be using `
Yeah, I hate jQuery. Especially the animations. CSS transitions are supported wide enough that you should probably use that instead. It's smoother - the DOM isn't meant to be messed around with every 20ms (as is the case with jQuery animations).
So, pretty good job for recent unzoomed desktop browsers with users who can't notice jQuery's slowness. Now just make it vector and vanilla and not have a bunch of… things in the DOM (ids, "tokens" (invalid attribute)) which can be put in arrays.
Tic tac toe
Html, head, body, and title are strongly recommended, tho not required.
You seem to be using `
s a lot… why? Can't you just make them images?
Canvases are ugly and pixely, images are beautiful and potentially vector (or at least easier to make high-res (important for retina devices)). The only downside is you have to create the images… but I just did it for you (tweak to your liking):
Don't make a bajillion ids. Instead of $('canvas#f' + rowId + colId)`:document.getElementById('container').children[rowId].children[colId]Yeah, I hate jQuery. Especially the animations. CSS transitions are supported wide enough that you should probably use that instead. It's smoother - the DOM isn't meant to be messed around with every 20ms (as is the case with jQuery animations).
So, pretty good job for recent unzoomed desktop browsers with users who can't notice jQuery's slowness. Now just make it vector and vanilla and not have a bunch of… things in the DOM (ids, "tokens" (invalid attribute)) which can be put in arrays.
Code Snippets
<!DOCTYPE html>
<html>
<head>
<title>Tic tac toe</title>
</head>
<body>
<!-- Stuff -->
</body>
</html><div class="row">
<img class="field" />
<img class="field" />
<img class="field" />
</div>
<div class="row">
<img class="field" />
<img class="field" />
<img class="field" />
</div>
<div class="row">
<img class="field" />
<img class="field" />
<img class="field" />
</div><svg xmlns="http://www.w3.org/2000/svg" width="50" height="50" fill="#f00"> <!-- An X -->
<polygon points="0,4 4,0 50,46 46,50" />
<polygon points="50,4 4,50 0,46 46,0" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="50" height="50" stroke="#090" stroke-width="5" fill="none"> <!-- An O -->
<circle cx="25" cy="25" r="22" />
</svg>document.getElementById('container').children[rowId].children[colId]Context
StackExchange Code Review Q#48995, answer score: 7
Revisions (0)
No revisions yet.