One question I have is, am I being redundant in passing the window object and then using :
O_o
No. The fragment in question represents a tiny shim.
You could change the fragment, but you aren't really paying for anything, and you do potentially gain some coverage.
Wouldn't "event" already be part of the window? Like, when I add the eventListener to the document, I don't need to call window.loadInterfaces, I just type "loadInterfaces". Does this same type of principle apply to everything encapsulated in the function?
I will not, as before, go into a lot of actual details or implementation issues.
The functions in Javascript have multiple hidden arguments. You already know about the `this' reference. The functions also have hidden `global' and `closure' arguments. (You can, by using certain methods or exploiting implementation details, change the hidden references.) The references are chained according to a rather long list of rules, but you don't need to worry about the majority. You already have a basic handle on the `this' reference. You can imagine the `closure' reference as the anonymous, the syntax you use without the `.' operator, reference you create by using variables from an enclosing scope. The `global' reference you may imagine as a `closure' you can't see.
Would using CSS for the focus/hover/active coloring, and using tab and click to just .focus() on the desired element, work better? I am not sure myself, I'm just wondering aloud.
I would argue that using CSS, directly or indirectly, is the only correct way to change the colors.
I'm hoping someone more up to date in Javascript stuff will comment further
I don't have time to explain, but I can show an example of basically everything technique covered in the discussion.
Of course, I don't code quite like anyone else in the Javascipt language. I'm not going to get into all the reasons just now. Basically though, my reaction to years of "NO! The * goes $(Preference)!" and such similar nonsense was the creation of a C++ style everyone can find something to love and hate. I use a lot of stylistic conventions designed to annoy people. I eventually just ported the awful beast to every language I use.
Soma
Code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript">
(function(fModule, fEnvironment) {
/* I am, again, just showing an example. I do a lot of checks. */
/* I also use several techniques to normalize the environment. */
var Register;
Register = (function() {
/* The registration function has a variable implementation depending on the actual environment. */
/* The implementation is ultimately exposed for the use of dependent modules. */
if (fEnvironment) {
return function(fModule) {
fEnvironment['$UUID!'] = fModule;
return fModule;
};
}
}());
return Register(fModule({
document: fEnvironment.document,
environment: fEnvironment,
register: Register,
}));
}(function(fContext) {
'use strict';
/* I use the '$' character as a resolution operator. */
/* You might think of the combination as the anonymous namespace from the C++ language. */
var gDocument, gEnvironment, gModule, SElement, SElement$RemoveClass;
/* I have quite a bit of context to import by name. */
gDocument = fContext.document;
gEnvironment = fContext.environment;
/* I actually use a much more elaborate mechanism. */
/* I just don't have time to explain or show an example. */
SElement = function(fIdentifier) {
if (this instanceof SElement) {
if (typeof fIdentifier === 'string') {
this.mNative = gDocument.getElementById(fIdentifier);
} else {
this.mNative = fIdentifier;
}
} else {
/* I prefer to use `new' yet appreciate the strategy. */
return new SElement(fIdentifier);
}
};
/* I know. I really do know, but the actual validator is thousands of characters long. */
SElement$RemoveClass = function(fSelf, fIdentifier, fRemove) {
var sFilter, sResult;
sFilter = new RegExp('(^|\\s)' + fIdentifier + '(\\s|$)');
sResult = fSelf.className.match(sFilter);
if (sResult && fRemove) {
fSelf.className = fSelf.className.replace(sFilter, '');
}
return sResult;
};
/* I actually shim some of the missing characteristics of other languages offering prototype-based polymorphisms. */
/* I, again, simply don't have time to explain all the code. */
SElement.prototype.addClass = function(fIdentifier) {
if (!this.hasClass(fIdentifier)) {
this.mNative.className += ' ' + fIdentifier;
return true;
}
return false;
};
SElement.prototype.hasClass = function(fIdentifier) {
return SElement$RemoveClass(this.mNative, fIdentifier, false);
};
SElement.prototype.removeClass = function(fIdentifier) {
return !SElement$RemoveClass(this.mNative, fIdentifier, true);
};
SElement.prototype.attachHandler = function(fIdentifier, fHandler) {
var sHandler = function(fEvent) {
fEvent = fEvent || gEnvironment.event;
fHandler(fEvent.currentTarget, fEvent);
};
this.mNative.addEventListener(fIdentifier, sHandler);
return sHandler;
};
gModule = function(fIdentifier) {
return new SElement(fIdentifier);
};
return gModule;
}, typeof window === 'undefined' ? this : window));
document.addEventListener('DOMContentLoaded', function() {
var $, sOne, sTwo, ProcessMouseDown, ProcessMouseUp;
/* Nope. I wasn't being silly. I often use a UUID for modules. */
$ = window['$UUID!'];
ProcessMouseDown = function(f) {
f = $(f);
f.addClass('held');
};
ProcessMouseUp = function(f) {
f = $(f);
f.removeClass('held');
};
sOne = $('one');
sTwo = $('two');
sOne.attachHandler('mousedown', ProcessMouseDown);
sOne.attachHandler('mouseup', ProcessMouseUp);
sOne.attachHandler('mouseout', ProcessMouseUp);
sTwo.attachHandler('mousedown', ProcessMouseDown);
sTwo.attachHandler('mouseup', ProcessMouseUp);
sTwo.attachHandler('mouseout', ProcessMouseUp);
sOne.addClass('highlighted');
setInterval((function() {
var sCurrent, sLast;
sCurrent = sOne;
sLast = sTwo;
return function() {
var sTemporary;
sTemporary = sCurrent;
sCurrent = sLast;
sLast = sTemporary;
sLast.addClass('highlighted');
sCurrent.removeClass('highlighted');
};
}()), 500);
});
</script>
<style>
tr {
background-color: #F00;
} tr.highlighted {
background-color: #F0F;
} tr:hover {
background-color: #0F0;
} tr.held {
background-color: #00F;
} tr.held.highlighted {
background-color: #0FF;
}
</style>
<title>Title</title>
</head>
<body>
<table>
<tbody>
<tr id="one">
<td>one</td><td>1111</td>
</tr>
<tr id="two">
<td>two</td><td>2222</td>
</tr>
</tbody>
</table>
</body>
</html>