New York Times-Style Text Selection Widget Using MooTools or jQuery

By  on  

NY Times Widget

Aaron Newton made a great request to me last week: why not make my MooTools Documentation Bookmarklet function more like the New York Time's text selection widget. NYT's text selection widget listens for text selection and presents the user with a "search" icon they may click on to learn more about that term. I've tried to answer that challenge -- not in bookmarklet form but in website widget form.

The Sample HTML

<div id="content-area">
	.htaccess AJAX Apache / Server APIs Blog Bookmarking / Social Books Browsers CSS / Design Google Guest Blogger Hosting / Domain JavaScript jQuery
	link() Microsoft MooTools MySQL Optimization PHP Poll rand() Security Shell Theory / Ideas Usability / Accessibility XML / XHTML
	This blog is targeted toward all levels of web designers and developers. All web topics are discussed, including CSS, JavaScript (MooTools and jQuery), PHP, and more.

The above code is next to meaningless per the widget -- I simply want to illustrate the area I'd like it to work in has an ID of content-area.

The MooTools JavaScript

	(function($) {
		//gets the selected text
		var getSelection = function() {
			return $try(
				function() { return window.getSelection(); },
				function() { return document.getSelection(); },
				function() { 
			        var selection = document.selection && document.selection.createRange();
					if(selection.text) { return selection.text; }
					return false;
			) || false;
		var url = '{term}', selectionImage;
		//event to listen
		$('content-area').addEvent('mouseup',function(e) {
			var selection = getSelection();
			if(selection && (selection = new String(selection).replace(/^\s+|\s+$/g,''))) {
				//ajax here { }
				if(!selectionImage) {
					selectionImage = new Element('a',{
						href: url,
						id: 'selection-image',
						title: 'Click here to learn more about this term',
						target: '_blank'
				//handle the every-time event
					top: - 30,	//offsets
					left: - 13 //offsets
		$(document.body).addEvent('mousedown',function() {
			if(selectionImage) { selectionImage.tween('opacity',1); }

During the mouseup event within the selected container (content-area), we determine if any text has been highlighted. If so, we:

  1. Insert the A element if it has not yet been injected into the body.
  2. Change the A element's URL to accommodate for the new search term.
  3. Position the element to at an offset position above where the mouse goes up.

During every mousedown event we hide the A element.

The jQuery JavaScript

/* attempt to find a text selection */
function getSelected() {
	if(window.getSelection) { return window.getSelection(); }
	else if(document.getSelection) { return document.getSelection(); }
	else {
		var selection = document.selection && document.selection.createRange();
		if(selection.text) { return selection.text; }
		return false;
	return false;
/* create sniffer */
$(document).ready(function() {
	var url = '{term}', selectionImage;
	$('#content-area').mouseup(function(e) {
		var selection = getSelected();
		if(selection && (selection = new String(selection).replace(/^\s+|\s+$/g,''))) {
			//ajax here { }
			if(!selectionImage) {
				selectionImage = $('<a>').attr({
					href: url, 
					title: 'Click here to learn more about this term',
					target: '_blank',
					id: 'selection-image'
				top: e.pageY - 30,	//offsets
				left: e.pageX - 13 //offsets
	$(document.body).mousedown(function() {
		if(selectionImage) { selectionImage.fadeOut(); }

Follows the same principal as above.

Ideas & Enhancements

  • Depending on your philosophy, you may want to implement a minimum character check as well:

    if(selection && (selection = new String(selection).replace(/^\s+|\s+$/g,'')) && selection.length > 4) { //5 char min
  • You may want to also fidget with adding/modifying text selection with keyboard keys as well. I've chosen to pass on that.
  • Saving the selection content via AJAX for analytical reasons may not be a bad idea either.

Have any other ideas for improvement? Would you have any use for this on your website(s)?

Recent Features

  • By
    CSS 3D Folding Animation

    Google Plus provides loads of inspiration for front-end developers, especially when it comes to the CSS and JavaScript wonders they create. Last year I duplicated their incredible PhotoStack effect with both MooTools and pure CSS; this time I'm going to duplicate...

  • By
    Create a CSS Flipping Animation

    CSS animations are a lot of fun; the beauty of them is that through many simple properties, you can create anything from an elegant fade in to a WTF-Pixar-would-be-proud effect. One CSS effect somewhere in between is the CSS flip effect, whereby there's...

Incredible Demos

  • By
    Advanced CSS Printing &#8211; Using JavaScript Double-Click To Remove Unwanted DIVs

    Like any good programmer, I'm constantly searching around the internet for ideas and articles that can help me improve my code. There are thousands of talented programmers out there so I stumble upon some great articles and code snippets that I like to print out...

  • By
    Full Width Textareas

    Working with textarea widths can be painful if you want the textarea to span 100% width.  Why painful?  Because if the textarea's containing element has padding, your "width:100%" textarea will likely stretch outside of the parent container -- a frustrating prospect to say the least.  Luckily...


  1. This is totally cool, and I KNOW this would be a great feature to add to a hyperlocal blog that I work for.

  2. Nice use! Could be a little neater on the MooTools side though…

    if(!selectionImage) { 
    	selectionImage = new Element('a', { 
    		'href': url.substitute({
    			'term': encodeURI(selection)
    		'id': 'selection-image', 
    		'title': 'Click here to learn more about this term', 
    		'target': '_blank', 
    		'fade': {
    			'duration': 50
    		'styles': { 
    			'top': - 30,
    			'left': - 13
    	}).inject(document.body, 'top'); 
  3. Rich

    Nice man. very cool and you got the jquery version which makes it so much better for me. I might have to try this on a project. thanks again for all the work you put into your blog. Its much appreciated.

  4. Mr.X.

    Very nice thanks!

  5. I am with a PHP web development company
    Very nice article thanks for explaining this. i am bookmarking this and will surely return for more knowledge:)

  6. Pretty sweet, always enjoy your blog.

  7. nice article dev….:)

  8. Is the plugin you’re using on this website?

  9. Yep — it was really easy to implement too!

  10. The mootools demo isn’t working for me (the jqery one does).

  11. @Graeme Coultrip: Updated!

  12. @David Walsh: It was simple opacity mistake.

  13. Cool. I think this could be very useful.

  14. Willian


    How can I change getSelected function to return the start and end position index?

  15. hi devid.

    i am following Your blog for Years.

    first of all , i appreciate you for your knowledge sharing ;)

    i am using Joomla 1.5 in my New Project and as you may know, Joomla Is using Mootools 1.11 in its core.

    So by know , i want to use this Useful plug-in and it does not work with this mootools version.

    how do you see this problem? any solution?

    i had updated the Joomla Mootools version, but some other part of the website drops :D

    best Regards,


  16. That’s really wow I say because this would be a source of getting inspiration and that is all what is required to start the things, thank you.

  17. The mootools demo isn’t working for me, too. It bothers me a lot. Who can help?

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!