I need help understanding this JavaScript assignment. We are being asked to use
ID: 3603785 • Letter: I
Question
I need help understanding this JavaScript assignment. We are being asked to use namespaces and the module pattern to modify a clock/stopwatch. I'm somewhat getting it up until the last step, and then I'm lost.
1. In the namespace library, review the code that creates the namespace and adds a namespace creator method. Then, use that method to add the following namespaces:
time
utility
time.clock
time.stopwatch
2. Move the padSingleDigit function and the $ function from the clock.js file to the library_utility.js file, and add them to the utility namespace.
3. Change the library_clock.js file so it uses the module pattern and adds the object it creates to the clock namespace.
4. Change the library_stopwatch.js file so it uses the module pattern and adds the object it creates to the stopwatch namespace.
5. Change the code in the clock.js file to use the new namespaces and module objects. Since you no longer create the clock and stopwatch objects, remove that code and pass the callbacks to the start methods. Use aliases for the namespaces, and make sure you don’t add anything to the global namespace.
Note: In step 3 and 4, you’ll need to adjust the objects so the callback function is passed to the start method and then stored so the function called by the timer can use it.
// clock.js
"use strict";
var $ = function(id) { return document.getElementById(id); };
var padSingleDigit = function(num) {
return (num < 10) ? "0" + num : num;
};
// callback function for displaying clock time
var displayTime = function(now) {
$("hours").firstChild.nodeValue = now.hours;
$("minutes").firstChild.nodeValue = padSingleDigit(now.minutes);
$("seconds").firstChild.nodeValue = padSingleDigit(now.seconds);
$("ampm").firstChild.nodeValue = now.ampm;
// display date in "m/d/yyyy" format - correct for zero-based month
var date = (now.getMonth() + 1) + "/" + now.getDate() + "/" + now.getFullYear();
$("date").firstChild.nodeValue = date;
};
// callback function for displaying stopwatch elapsed time
var displayTick = function(elapsed) {
$("s_minutes").firstChild.nodeValue = padSingleDigit(elapsed.minutes);
$("s_seconds").firstChild.nodeValue = padSingleDigit(elapsed.seconds);
$("s_ms").firstChild.nodeValue = elapsed.milliseconds;
};
// callback function for clearing stopwatch elapsed time display
var resetStopwatch = function() {
$("s_minutes").firstChild.nodeValue = "00";
$("s_seconds").firstChild.nodeValue = "00";
$("s_ms").firstChild.nodeValue = "000";
};
// onload event handler
window.onload = function() {
var clock = createClock(displayTime);
var stopwatch = createStopwatch(displayTick);
// start clock
clock.start();
// set up stopwatch event handlers
$("start").onclick = function() {
stopwatch.start();
};
$("stop").onclick = function() {
stopwatch.stop();
};
$("reset").onclick = function() {
stopwatch.reset(resetStopwatch);
};
};
// library_clock.js
"use strict";
var createClock = function(displayTimeCallbackFunction) {
// private state
var displayCurrentTime = function() {
var now = new Date();
// add own properties to instance of Date object
now.hours = now.getHours();
now.minutes = now.getMinutes();
now.seconds = now.getSeconds();
now.ampm = "AM"; // set default value
// correct hours and AM/PM value for display
if (now.hours > 12) { // convert from military time
now.hours = now.hours - 12;
now.ampm = "PM";
} else { // adjust 12 noon and 12 midnight
switch (now.hours) {
case 12: // noon
now.ampm = "PM";
break;
case 0: // midnight
now.hours = 12;
now.ampm = "AM";
}
}
// use callback function to display time - pass it the now variable
if (displayTimeCallbackFunction && typeof displayTimeCallbackFunction === 'function') {
displayTimeCallbackFunction(now);
}
};
// public methods
return {
start: function() {
displayCurrentTime();
setInterval(displayCurrentTime, 1000);
return this;
}
};
};
// library_namespace.js
"use strict";
// create the namespace and nested namespace creator method
var myapp = myapp || {};
myapp.addNamespace = function (namespace) {
var currentName;
var parent = this;
var names = namespace.split(".");
for (var i in names) {
currentName = names[i];
parent[currentName] = parent[currentName] || {};
parent = parent[currentName];
}
return this;
}.bind(myapp);
// add the namespaces the application will use
// library_stopwatch.js
"use strict";
var createStopwatch = function(displayTickCallbackFunction) {
// private state
var timer;
var elapsed = { minutes:0, seconds:0, milliseconds:0 };
var tickStopwatch = function() {
// increment milliseconds by amount of interval
elapsed.milliseconds = elapsed.milliseconds + 10;
// roll over milliseconds to seconds, seconds to minutes
if (elapsed.milliseconds === 1000) {
elapsed.seconds++;
elapsed.milliseconds = 0;
}
if (elapsed.seconds === 60) {
elapsed.minutes++;
elapsed.seconds = 0;
}
// use callback to display new stopwatch time - pass it the elapsed time object
if (displayTickCallbackFunction && typeof displayTickCallbackFunction === 'function') {
displayTickCallbackFunction(elapsed);
}
};
// public methods
return {
start: function() {
tickStopwatch();
timer = setInterval(tickStopwatch, 10);
return this;
},
stop: function() {
clearInterval(timer);
return this;
},
reset: function(resetStopwatchCallbackFunction) {
clearInterval(timer);
elapsed = { minutes:0, seconds:0, milliseconds:0 };
// use callback to reset stopwatch display
if (resetStopwatchCallbackFunction && typeof resetStopwatchCallbackFunction === 'function') {
resetStopwatchCallbackFunction();
}
return this;
}
};
};
// library_utitlity.js
"use strict";
//otherwise currently empty
Explanation / Answer
"use strict";
var $ = function(id) { return document.getElementById(id); };
var padSingleDigit = function(num) {
return (num < 10) ? "0" + num : num;
};
// callback function for displaying clock time
var displayTime = function(now) {
$("hours").firstChild.nodeValue = now.hours;
$("minutes").firstChild.nodeValue = padSingleDigit(now.minutes);
$("seconds").firstChild.nodeValue = padSingleDigit(now.seconds);
$("ampm").firstChild.nodeValue = now.ampm;
// display date in "m/d/yyyy" format - correct for zero-based month
var date = (now.getMonth() + 1) + "/" + now.getDate() + "/" + now.getFullYear();
$("date").firstChild.nodeValue = date;
};
// callback function for displaying stopwatch elapsed time
var displayTick = function(elapsed) {
$("s_minutes").firstChild.nodeValue = padSingleDigit(elapsed.minutes);
$("s_seconds").firstChild.nodeValue = padSingleDigit(elapsed.seconds);
$("s_ms").firstChild.nodeValue = elapsed.milliseconds;
};
// callback function for clearing stopwatch elapsed time display
var resetStopwatch = function() {
$("s_minutes").firstChild.nodeValue = "00";
$("s_seconds").firstChild.nodeValue = "00";
$("s_ms").firstChild.nodeValue = "000";
};
// onload event handler
window.onload = function() {
var clock = createClock(displayTime);
var stopwatch = createStopwatch(displayTick);
// start clock
clock.start();
// set up stopwatch event handlers
$("start").onclick = function() {
stopwatch.start();
};
$("stop").onclick = function() {
stopwatch.stop();
};
$("reset").onclick = function() {
stopwatch.reset(resetStopwatch);
};
};
// library_clock.js
"use strict";
var createClock = function(displayTimeCallbackFunction) {
// private state
var displayCurrentTime = function() {
var now = new Date();
// add own properties to instance of Date object
now.hours = now.getHours();
now.minutes = now.getMinutes();
now.seconds = now.getSeconds();
now.ampm = "AM"; // set default value
// correct hours and AM/PM value for display
if (now.hours > 12) { // convert from military time
now.hours = now.hours - 12;
now.ampm = "PM";
} else { // adjust 12 noon and 12 midnight
switch (now.hours) {
case 12: // noon
now.ampm = "PM";
break;
case 0: // midnight
now.hours = 12;
now.ampm = "AM";
}
}
// use callback function to display time - pass it the now variable
if (displayTimeCallbackFunction && typeof displayTimeCallbackFunction === 'function') {
displayTimeCallbackFunction(now);
}
};
// public methods
return {
start: function() {
displayCurrentTime();
setInterval(displayCurrentTime, 1000);
return this;
}
};
};
// library_namespace.js
"use strict";
// create the namespace and nested namespace creator method
var myapp = myapp || {};
myapp.addNamespace = function (namespace) {
var currentName;
var parent = this;
var names = namespace.split(".");
for (var i in names) {
currentName = names[i];
parent[currentName] = parent[currentName] || {};
parent = parent[currentName];
}
return this;
}.bind(myapp);
// add the namespaces the application will use
// library_stopwatch.js
"use strict";
var createStopwatch = function(displayTickCallbackFunction) {
// private state
var timer;
var elapsed = { minutes:0, seconds:0, milliseconds:0 };
var tickStopwatch = function() {
// increment milliseconds by amount of interval
elapsed.milliseconds = elapsed.milliseconds + 10;
// roll over milliseconds to seconds, seconds to minutes
if (elapsed.milliseconds === 1000) {
elapsed.seconds++;
elapsed.milliseconds = 0;
}
if (elapsed.seconds === 60) {
elapsed.minutes++;
elapsed.seconds = 0;
}
// use callback to display new stopwatch time - pass it the elapsed time object
if (displayTickCallbackFunction && typeof displayTickCallbackFunction === 'function') {
displayTickCallbackFunction(elapsed);
}
};
// public methods
return {
start: function() {
tickStopwatch();
timer = setInterval(tickStopwatch, 10);
return this;
},
stop: function() {
clearInterval(timer);
return this;
},
reset: function(resetStopwatchCallbackFunction) {
clearInterval(timer);
elapsed = { minutes:0, seconds:0, milliseconds:0 };
// use callback to reset stopwatch display
if (resetStopwatchCallbackFunction && typeof resetStopwatchCallbackFunction === 'function') {
resetStopwatchCallbackFunction();
}
return this;
}
};
};
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.