Skip to content

Instantly share code, notes, and snippets.

@stubbornella
Created October 2, 2013 00:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stubbornella/6787249 to your computer and use it in GitHub Desktop.
Save stubbornella/6787249 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body>
<div class="text">text to be replaced</div>
<ul>
<li>foo - clicks here should not alert</li>
<li>bar</li>
<li>baz</li>
</ul>
</body>
</html>
/* tests:
*
* 1. click on children of .text should alert their index
* 2. click on other elements should not
* 3. if two nodes have the same content, a click on the latter should not return the index of the former
*/
// how to make it execute after document is loaded?
var textNodes = document.getElementsByClassName("text"),
content = "<div>a</div><div>e</div><div>t</div><div>7</div><div>1</div>"; // what if the server returned json, or content was an array.
function forEach(array, action) {
for (var i=0; i< array.length; i++) {
action(array[i]);
}
}
forEach(textNodes, function(node) {
node.innerHTML = content;
});
function findIndex(node) {
var siblings,
sibling,
index;
siblings = node.parentNode.children;
for (index=0; index<siblings.length; index++) {
if (siblings[index] == node) return index;
}
return -1; // no match found, this should not happen
}
function registerEventHandler(node, event, handler) {
if (typeof node.addEventListener == "function") {
node.addEventListener(event, handler, false);
}
else {
node.attachEvent("on" + event, handler);
}
}
function normaliseEvent(event) {
if (!event.stopPropagation) {
event.stopPropagation = function() {this.cancelBubble = true;};
event.preventDefault = function() {this.returnValue = false;};
}
if (!event.stop) {
event.stop = function() {
this.stopPropagation();
this.preventDefault();
};
}
if (event.srcElement && !event.target)
event.target = event.srcElement;
if ((event.toElement || event.fromElement) && !event.relatedTarget)
event.relatedTarget = event.toElement || event.fromElement;
if (event.clientX !== undefined && event.pageX === undefined) {
event.pageX = event.clientX + document.body.scrollLeft;
event.pageY = event.clientY + document.body.scrollTop;
}
if (event.type == "keypress") {
if (event.charCode === 0 || event.charCode === undefined)
event.character = String.fromCharCode(event.keyCode);
else
event.character = String.fromCharCode(event.charCode);
}
return event;
}
function addHandler(node, type, handler) {
function wrapHandler(event) {
handler(normaliseEvent(event || window.event));
}
registerEventHandler(node, type, wrapHandler);
return {node: node, type: type, handler: wrapHandler};
}
function removeHandler(object) {
unregisterEventHandler(object.node, object.type, object.handler);
}
var foo = addHandler(document.body,"click", function(event) {
alert(findIndex(event.target));
});
ul {
padding: 0;
list-style-type: none;
li {
background-color: #e2e2e2;
padding: 10px;
border-bottom: solid 10px gray;
}
}
.text div{
background-color: #e2e2e2;
padding: 10px;
border-bottom: solid 10px gray;
}
@stubbornella
Copy link
Author

Goals:

  1. Insert elems (content var above) into the text node
  2. Attach click handlers to inserted nodes
  3. Alert the index of the clicked element when items are clicked

This is the second version.

CHANGELOG:

  1. It has better event handling than the first version
  2. No more accidental global vars
  3. Added a forEach method so I wouldn't have to keep making iterators (and especially naming them)

@stubbornella
Copy link
Author

Oh yeah, @jared-wyles inspired this revision by asking me two things?

  1. What did variables and hoisting tell me about what I might have screwed up?
  2. How do attachEvent and eventListener handle the event object differently?

For the latter question, I'm reading PPK's article on events, which Jared suggested. I'll post another gist when I figure it out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment