Highlight and Capture Text Using jQuery

At a previous job I was trying to help a fellow developer out with what they were trying to accomplish and in doing so, I came up with what you’re going to see below. Just as a note, they never ended up needing this at all ^_^!

So what’s this post about? Well, I’m going to try and show you another option for collecting and saving content. I’ve heard some magazine and newspaper websites are doing things like this, but I haven’t seen it anywhere except for analytics tracking. As a note, this is not at all a polished nor finished demo, but I’d like to see what kind of examples other developers can or maybe have already done with this. I hope you’ll find my code as a good starting place for getting started with your own tests.

 

So the first thing we need to do is setup the highlighting functionality so we can figure out which piece of content we’re actually on. As a note, I took this from someone else’s post a while back and have just slightly modified.

// Make sure the object is created if it's already not
if(!window.CurrentSelection){
    CurrentSelection = {}
}
//define the selector object
CurrentSelection.Selector = {}

//get the current selection
CurrentSelection.Selector.getSelected = function(){
    var sel = '';
    if(window.getSelection){
        sel = window.getSelection()
    }
    else if(document.getSelection){
        sel = document.getSelection()
    }
    else if(document.selection){
        sel = document.selection.createRange()
    }
    return sel
}
//function to be called on mouseup
CurrentSelection.Selector.mouseup = function(){
    var st = CurrentSelection.Selector.getSelected()
    if(document.selection && !window.getSelection){
        var range = st
        range.pasteHTML("<span class='selectedText'>" + range.htmlText + "</span>");
    }
    else{
        var range = st.getRangeAt(0)    
        var newNode = document.createElement("span");
        newNode.setAttribute("class", "selectedText");
        range.surroundContents(newNode)                
    }
}

$(function(){
    $(document.body).bind("mouseup",CurrentSelection.Selector.mouseup)
})

Let’s take a look at this piece of code here:

range.pasteHTML("<span class='selectedText'>" + range.htmlText + "</span>");

What this is doing is inserting a span with the class of selectedText around the currently highlighted piece of text. You can then place an event handler on that span tag, such as what I’ve done below.

   
//event handler for clicking the selected highlighted text
$("span.selectedText").live("click",function(){
    if($(this).hasClass("goodText")){
        $(this).addClass("badText").removeClass("goodText")    
    }
    else if($(this).hasClass("badText")){
        $(this).addClass("goodText").removeClass("badText")    
    }
    if(!$(this).hasClass("badText") && !$(this).hasClass("goodText")){
        $(this).addClass("goodText")
    }
})
//extracting all of the selected highlighted text
$("#extractText").live("click",function(){
    var badTextHtml = '',
        goodTextHtml = ''
    $.each($(".selectedText"),function(i,currItem){
        if($(currItem).text() != ''){
            if($(currItem).hasClass("goodText")){
                goodTextHtml += "<li>"+$(currItem).text()+"</li>"    
            }
            if($(currItem).hasClass("badText")){
                badTextHtml += "<li>"+$(currItem).text()+"</li>"    
            }                        
        }
    })
    
    $("#badText").html(badTextHtml)
    $("#goodText").html(goodTextHtml)
    $("#resultsCont").fadeIn()
})
//clear the results and set the content back to text and not html
$("#clearHighlights").live("click",function(){
	var hLCont = $("#highlightContainer p")
	hLCont.text(hLCont.text()) 
	$("#resultsCont").hide()
})

Now that we’ve got some event handlers for the selections, we can then decide what we want to do with the content. In this case, I’m just outputting in different types, Bad Text and Good Text.

For the sake of humanity, I’m going to skip the HTML lecture and throw it into the final code with the JavaScript.

<div id="highlightContainer">
    <p id="textWithinHighlightContainer" style="line-height:1.9em; font-size:16px; margin:10px; border:1px #333 solid; padding:5px; width: 450px">
Jowl pig chuck pork, tri-tip salami jerky andouille ham ground round rump beef ribs filet mignon hamburger. Brisket filet mignon pork belly fatback. Ham ball tip prosciutto tail. Sausage fatback filet mignon kielbasa andouille beef pancetta cow, sirloin ham hock bresaola pork loin shoulder strip steak boudin. Turducken capicola cow short loin venison ball tip. Flank pork loin boudin, short loin salami ribeye beef bacon ham hock ball tip rump pork belly. Beef ribs bresaola pork ground round hamburger pancetta short ribs, t-bone shank capicola ham sausage.
<br />
Strip steak biltong ham hock, ham pig salami andouille prosciutto filet mignon cow. Chuck turkey jerky boudin, jowl cow drumstick ball tip short loin ham hock shankle venison sirloin tail t-bone. Spare ribs bacon venison, ribeye ham hock pork tail beef ribs capicola bresaola. Beef frankfurter salami, ham hock t-bone ball tip ground round shoulder short loin meatball filet mignon brisket chuck pastrami. Kielbasa filet mignon drumstick, ham ribeye chuck jerky beef ribs pork belly ball tip bresaola biltong.
    </p>
</div>     
<br />
<input type="button" id="extractText" value="Extract Highlighted Text" style="margin-left:10px" /> <input type="button" id="clearHighlights" value="Clear Highlights" style="margin-left:10px" />
<br />
<br />
<div style="margin:10px; display:none" id="resultsCont">
    <div style="float:left; width:300px">
        <h3>Bad Text Results</h3>
        <ul id="badText">
        
        </ul>
    </div>
    <div style="float:left; width:300px">
        <h3>Good Text Results</h3>
        <ul id="goodText">
        
        </ul>
    </div>
</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script> 
<script type="text/javascript">  
	//define the parent container so we retrict where we're able to highlight
	var parentContainerId = "textWithinHighlightContainer"
	
	// Make sure the object is created if it's already not
	if(!window.CurrentSelection){
		CurrentSelection = {}
	}
	//define the selector object
	CurrentSelection.Selector = {}
	
	//get the current selection
	CurrentSelection.Selector.getSelected = function(){
		var sel = '';
		if(window.getSelection){
			sel = window.getSelection()
		}
		else if(document.getSelection){
			sel = document.getSelection()
		}
		else if(document.selection){
			sel = document.selection.createRange()
		}
		return sel
	}
	//function to be called on mouseup
	CurrentSelection.Selector.mouseup = function(){
		var st = CurrentSelection.Selector.getSelected()
		if(document.selection && !window.getSelection){
			var range = st
			range.pasteHTML("<span class='selectedText'>" + range.htmlText + "</span>");
		}
		else{
			var range = st.getRangeAt(0)    
			var newNode = document.createElement("span");
			newNode.setAttribute("class", "selectedText");
			range.surroundContents(newNode)                
		}
	}
        
	$(function(){
		$("#"+parentContainerId).bind("mouseup",CurrentSelection.Selector.mouseup)
		

		//event handler for clicking the selected highlighted text
		$("span.selectedText").live("click",function(){
			if($(this).hasClass("goodText")){
				$(this).addClass("badText").removeClass("goodText")    
			}
			else if($(this).hasClass("badText")){
				$(this).addClass("goodText").removeClass("badText")    
			}
			if(!$(this).hasClass("badText") && !$(this).hasClass("goodText")){
				$(this).addClass("goodText")
			}
		})
		//extracting all of the selected highlighted text
		$("#extractText").live("click",function(){
			var badTextHtml = '',
				goodTextHtml = ''
			$.each($(".selectedText"),function(i,currItem){
				if($(currItem).text() != ''){
					if($(currItem).hasClass("goodText")){
						goodTextHtml += "<li>"+$(currItem).text()+"</li>"    
					}
					if($(currItem).hasClass("badText")){
						badTextHtml += "<li>"+$(currItem).text()+"</li>"    
					}                        
				}
			})
			
			$("#badText").html(badTextHtml)
			$("#goodText").html(goodTextHtml)
			$("#resultsCont").fadeIn()
		})
		//clear the results and set the content back to text and not html
		$("#clearHighlights").live("click",function(){
			var hLCont = $("#highlightContainer p")
			hLCont.text(hLCont.text()) 
			$("#resultsCont").hide()
		})
	})        
</script>   

So there you have it. It’s nothing too advanced, but it’s a fun and powerful option that should give you more ideas for collecting data, allowing users to highlight and store specific pieces of content, or maybe even play around with some easter eggs and try to see who finds them! Again, here is the link to my demo and you can download the code.


Please be sure to let me know of some examples anyone has developed using something like this. I’m definitely interested in seeing what could be done.

Browsers tested: IE7+, Google Chrome, and FireFox.

Tags: , ,

6 Responses to "Highlight and Capture Text Using jQuery"

  • Arvind says:
  • Jason says:
  • Gletzer says:
  • Rahul Verma says:
  • Thomas says:
Leave a Comment

Switch to our mobile site