I needed to write a quick bit of code today to track when a user selects any text on a page. The key was to bind a method to the "mouseup" event which would grab the selected text and do something with it. This was plain 'ole JS and thankfully <a href="http://dean.edwards.name">Dean Edwards</a> and <a href="http://crisp.tweakblogs.net/">Tino Zijdel</a> had created a nice <a href="http://therealcrisp.xs4all.nl/upload/addEvent_dean.html">cross-browser event handler routine</a> which worked great. And <a href="http://davidwalsh.name/">David Walsh</a> has a <a href="http://davidwalsh.name/text-selection-ajax">nice post on similar functionality</a> using MooTools & jQuery so I was able to leverage some of that code that deals with grabbing the selected text:

[code lang="js"]
function findSelected() {
	if(window.getSelection) { 
		return window.getSelection(); 
	}
	else if(document.getSelection) { 
		return document.getSelection(); }
	else {
		var selection = document.selection &amp;&amp; document.selection.createRange();
		if(selection.text) { 
			return selection.text; }
		return false;
	}
	return false;
}

function getSelectedText() {
	var selected = findSelected();
	if(selected &amp;&amp; (selected = new String(selected).replace(/^\s+|\s+$/g,''))) {
		alert( selected );
	}
}
[/code]

From there it was just a matter of actually binding the method to "mouseup":

[code lang="js"]
addEvent(document,&quot;mouseup&quot;,getSelectedText);
[/code]

All this seemed great and it worked perfectly in Internet Explorer and Firefox but when I tried it on Chrome, I found an issue. When I would select the text an alert box would appear which was expected but when I closed the box and clicked on any whitespace in the viewport, the alert box would reappear! To see it in action, try these steps:

<ol>
	<li>Open this page: <a href="http://reybango.com/ms/test.html">http://reybango.com/ms/test.html</a></li>
	<li>Using your mouse select any part of the text and release. An alert box should appear.</li>
	<li>Close the alert box and click on any whitespace in the viewport.</li>
</ol>

In both Chrome and Safari, you should see that a second alert box is displayed. This doesn't happen in Firefox or IE.

After quite a bit of debugging, running it by John Resig & Pete Higgins and running short on time, I decided to create a work-around which resolved the issue. By using a closure to keep a persistent copy of the last selected text, I can compare that value to the newly selected text and if it matches the persistent copy, I can ignore it. It's a very basic way to filter out the second call being done by Chrome & Safari:

[code lang="js"]
getSelectedText = (function() {
	var selected = &quot;&quot;;
	
	return (function() {
		var currSelection = findSelected();
		if (selected != currSelection) {
			selected = currSelection;
			if(selected &amp;&amp; (selected = new String(selected).replace(/^\s+|\s+$/g,''))) {
				alert( selected );
			}
		}
	})
})();
[/code]

Now I acknowledge that this is not the ideal solution and I need to determine what the browser inconsistency is here. It seems like it might be Webkit-related since it only affects Chrome & Safari so I'll have to dig further into that. For now, though, the closure works and since I don't a circular reference between any DOM or JS objects, it looks like memory leaks shouldn't be an issue. 