The following students will meet me in my office this Friday. If you are going to be out of town just let me know so we can re-schedule.
- 11:15 Cormier
- 11:25 Denmark
- 11:35 Dillon
- 11:45 Gavel
- 11:55 Goss
The following students will meet me in my office this Friday. If you are going to be out of town just let me know so we can re-schedule.
Some really cool tips on using Chrome's developer tools are shown on this video:
I have just emailed the grades for HW 6. People seem to be having trouble with creating closures. Below is my solution to the this homework. Notice how the makeDisperse function creates other functions (closures), each of which with possibly different 'neighbors' depending on the arguments passed to makeDisperse.
//Returns a list of the 4 elements that are North, South, East and West of the
// button with id= 'b' + row + col
function getNeighbors (row, col) {
var result = [];
var nrow = (row == 0) ? SIZE - 1 : row - 1;
var ncol = col;
result.push(document.getElementById('b'+ nrow + ncol));
nrow = row
ncol = (col + 1) % SIZE;
result.push(document.getElementById('b' + nrow + ncol));
nrow = (row + 1) % SIZE;
ncol = col;
result.push(document.getElementById('b' + nrow + ncol));
nrow = row;
ncol = (col == 0) ? SIZE - 1 : col -1;
result.push(document.getElementById('b' + nrow + ncol));
return result;
}
//Creates and returns an event handler which is a closure that holds
// 'neighbors', a list of the 4 elements that are North, S, E, West of the
// button at row,col. The function it returns distributes the value of this
// over the 4 neighbors.
function makeDisperse(row, col){
var neighbors = getNeighbors(row,col);
function disperse () {
var myNumber = Number(this.value);
while (myNumber > 0){
for (var i =0; i < neighbors.length; i++){
var nelement = neighbors[i];
nelement.value = Number(nelement.value) + 1;
myNumber--;
if (myNumber <= 0 ) { break;}
}
}
this.value = 0;
updateScore();
};
return disperse;
}
//This method on <body onload="setup()". It sets an event-handler for every button.
function setup(){
for (var row =0; row < SIZE; row++){
for (var col=0; col < SIZE; col++){
var button = document.getElementById('b' + row + col);
button.onclick = makeDisperse(row,col);
}
}
}
//Updates the value of the score button to be the count of all the zeros in all the buttons.
function updateScore(){
var total = 0;
for (var row =0; row < SIZE; row++){
for (var col=0; col < SIZE; col++){
var button = document.getElementById('b' + row + col);
if ('0' == button.value) {
total++;
}
}
}
var scoreButton = document.getElementById('score');
score.value = total;
}
People do a lot of JavaScript programming without understanding closures. Still, they are a really useful and powerful feature of the language: used for creating private variables, custom functions (as above), and namespaces, among other uses. I think you will be a much better developer if you understand and use them as needed.
For this homework you will build a stand-alone math quiz/drill program. If you have ever visited the Khan Academy you will see that, in addition to all the cool videos, Kahn also has a webapp for practicing math. For this homework you will build JavaScript application that asks the user simple math questions, and provides him with feedback on his progress. Note that this will be a stand-alone application, independent of the survey webapp we have been developing (for now?). You will be using jQuery for this and jQueryUI if you want.
There are a few things that we know, from educational and video game research, about how to build these types of apps.
[0,1,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,5,5,6,6,6,6,6,7,7,7,7,7,8,8,8,8,8,9,9,9,9,9].This homework is due on Monday, March 14 @11am, you can turn it in here.
Check out the following code, which is live in this page.
<!DOCTYPE html> <html> <body> <input type="button" value="0" id="a" onclick="increase()"/>
<input type="button" value="10" id="b"/> <script> function increase(){ this.value = Number(this.value) + 1; } document.getElementById('b').onclick = increase; </script> </body> </html>
In my chrome and firefox, clicking on the first button does nothing, while clicking on the second one increases the number by 1. If we open up firebug and print out the onclick properties for the two elements, we can see why the first one does not work.
> document.getElementById('a').onclick
function onclick(event) {
increase()
}
> document.getElementById('b').onclick
function increase(){
this.value = Number(this.value) + 1;
}
The first one has a function called onclick wrapped around the call to increase. So, in the first case, increase gets called as a global function which means that this will be bound to the global object. In the second case increase is called as a method of the input element.
Why this distinction? I don't know. What do you need to know? 1) Use the second form for this homework and 2) always use a good javascript library for setting up and handling events; like jQuery, which you will start using next week.
Below is John Resig, jQuery author, on jQuery. The first part of the video is about JavaScript. You can skip to the 0:30 mark, or so, where he starts to talk about jQuery.
Crockford is back, this time discussing the Document Object Model. We will be talking about this, and jQuery, next week.
Basically, you should think of Crockford as the one teaching CSCE 242 and me as the TA.
I mentioned in class how you could use closures to create private variables, just like Java has. The code below shows how this is done. Notice that the only way to get at joe's name is using the given functions. If you wanted to make the name a constant then you could just get rid of setName and no one would be able to change joe's name. Pretty cool!
//This is how you make an object with private variables.
function Employee(){};
function newEmployee(theName) {
var name = theName;
Employee.prototype.getName = function(){return name;}
Employee.prototype.setName = function(n){name = n;}
return new Employee();
}
//The only way to change joe's name is by calling joe.setName.
joe = newEmployee('Joe');
joe.getName(); //get his name
joe.setName('bob'); //he is now bob
You don't need the name variable, we could have just used theName instead. But, maybe this makes it clearer? I find it a bit more intuitive this way.
This Friday we start the challenge rounds. The following students will report to my office at the given times.
I emailed grades earlier. Those of you who did not get it to work, please do so. Let me know if you need help. At worst, I can finish the coding for you (which will be better than you starting over with someone else's code). You will need this code in a couple of weeks when we start putting our JavaScript skills to work on prettying up the webapp.
I added some comments to the class example (see the script.js and jspage.html files). I'll be talking more about JavaScript and closures on Wednesday. Next week we will cover DOM manipulation and jQuery.
The example files show a simple way to handle events. However, the recommended way is to use a JavaScript library. Different browsers implement event-handling in different ways (they are converging, but there are a lot of old browsers in use) and there are many good javascript libraries that deal with all this ugliness so we don't have to. We will be using jQuery.
We will be building again on our surveys webapp in future weeks: adding some drag-and-drop editing and AJAX functionality, and graphics, gotta have graphics! Stay tuned.