Skip to content

Instantly share code, notes, and snippets.

@stubbornella
Created October 14, 2013 00:21
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/6968898 to your computer and use it in GitHub Desktop.
Save stubbornella/6968898 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<meta name="description" content="[add your bin description]" />
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body>
<h1>Using onclick</h1>
<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 - PASS
* 2. click on other elements should not - PASS
* 3. if two nodes have the same content, a click on the latter should not return the index of the former - PASS
*/
// how to make it execute after document is loaded?
var content = "<div>a</div><div>e</div><div>t</div><div>7</div><div>1</div><div>a</div>",
textNode = document.getElementsByClassName("text")[0]; // what if the server returned json, or content was an array.
textNode.innerHTML = content;
textNode.onclick = findIndex;
if (textNodes.captureEvents) textNodes.captureEvents(Event.CLICK);
function findIndex(e) { // does js have an api for the index?
if (!e) var e = window.event;
alert(Array.prototype.indexOf.call( e.target.parentNode.children, e.target ));
}
@stubbornella
Copy link
Author

This version came from @goonieiam saying that my solution was overly complicated and that alerting the index could be done in one line, which made me look for possible native methods that could find the index of an element. It turns out that HTMLCollections do not have an indexOf method like arrays do, so I used the array method on the HTMLCollection via 'Array.prototype'. Crazy that that is even possible.

@stubbornella
Copy link
Author

Next question: what if you were searching through 1000 nodes, or 10,000 nodes?

@stubbornella
Copy link
Author

The first thing I'd say is that it depends on the data we can understand about the nodes. What is the click distribution for the most important use cases? Are more users clicking on the first 5 items? The first 10? Is 75% of the list below the fold and thus much less likely to be seen?

Some options:

  • Custom search algorithm based on the data
  • Filter nodes included in the search list based on their visibility on the page
  • Standard algorithmic ways of searching through the nodes for a match (but I'd look at this only after understanding more about the nodes being searched through)

@stubbornella
Copy link
Author

Success criteria: the new method needs to be faster than simply searching through all the nodes with a reasonable academic algorithm.

My initial plan, I will do a combination of these points.

  1. Find out which nodes are visible
  2. Only search those nodes

How to find out which nodes are visible?

I don't want to check every node, that would be even slower than searching the whole list. Figure out at how many nodes (x) searching becomes slower than the user is willing to tolerate (~200ms, but again, gather data). Then check visibility at those increments. There are three cases the solution must satisfy:

  • The beginning of the list is visible
  • The middle of the list is visible
  • The end of the list is visible

@stubbornella
Copy link
Author

So, the way I've already written it is super fast. Even with 100,000 nodes, the alert is instantaneous. With a million nodes, the browser can't handle even scrolling, so I can't see optimizing for that situation.

@goonieiam - what do you think?

@stubbornella
Copy link
Author

@jared-wyles said I should focus on these things next:

  1. maintainability, and
  2. what if the div wrappers for the content could be any element, a span for example, or li

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