Joshua Wood

Tracking copied text using Javascript, jQuery, and PHP

Everyone knows that most web site usage statistics are tracked by web servers, including user local, operating systems, page views, unique visits, etc. However, if you're really serious about tracking your user's activity, you'll use an analytics solution such as WebTrends, which is used by the New York Times to log on-screen actions which cannot be tracked by traditional means. Using the WebTrends dcsMultiTrack function, it's possible to capture virtually any event that can trigger a JavaScript function, whether it's on a static HTML page or inside a flash application.

One of the more creative pieces of tracking code that I ran across while browsing the New York Times source code (yeah, most people read the news... so?) was when a user copies text from an article. It's really such a simple concept, but one that never occurred to me: when the user selects text on screen, use JavaScript to capture it. Then set up a trigger to submit the selected text to the server via AJAX when the copy command is detected. Imagine the analytics that could be created based on popular locations within individual articles!

So I decided to work up a little demonstration using jQuery to log the event and PHP to handle the request server-side. This is very basic, but should be enough to get started toward your own super-analytics. You will need to include jQuery 1.3.2.

The JavaScript

``` javascript /** * Copyright (c) 2009 Joshua Wood * * Based on research by Mark S. Kolich and The New York Times WordReference function * * Copyright (c) 2009 Mark S. Kolich * * * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ // Create a new Object for our code to reside in (makes it pretty and manageable) var Example = Example || {}; Example = (function(){ var selection, selectionText, responseText; // Global object variables // Get currently selected text // Method based on getSelected() from CodeToad at // function getSelection() { var t = ''; if(window.getSelection){ return window.getSelection(); } else if(document.getSelection){ return document.getSelection(); } else if(document.selection){ var selection = document.selection && document.selection.createRange(); selection.toString = function() { return this.text }; return selection; } return t; } // This is the callback function for the mouseup event function handleClick(event) { selection = getSelection(); selectionText = selection && selection.toString(); } // This is the callback function for the oncopy event function handleCopy(event) { var wc = wordCount(selectionText); if(wc) { // Do something with copied text (send to server via ajax) responseText = $.ajax({ url: "log.php", global: false, type: "POST", data: ({text : selectionText}), dataType: "text", success: function(msg){ $('#response').text(msg); } } ).responseText; } } // A simple function to count the words in a string, copied directly from function wordCount(inStr) { var wc; wc = inStr && inStr.replace(/[^\s\w]+/g, ""); // sans-punctuation wc = wc && wc.replace(/^\s*/, "").replace(/\s*$/, ""); // trim wc = wc && wc.length && wc.split(/\s+/).length; // count words return Number(wc); } return { initialize: function() { $(document).bind("mouseup", handleClick); document.getElementsByTagName("html")[0].oncopy = handleCopy; } }; })(); // Initialize our little program and wait for copied text! $(document).ready(function(){ Example.initialize(); }); ```


``` php // Log some text from the request and spit it back out // (This is where you would do something with it)

$text = $_REQUEST['text']; echo $text; ```

This example will wait for the user to copy text on screen, and then submit it to the server-side file log.php which can process it, save it, etc (in this case it sends it back to the browser and puts it in the DIV with the id "request").

View Example Download

What other tracking applications can you see for JavaScript and Ajax?


I'm Josh Wood, a tech entrepreneur and software developer. I founded and I'm all about building awesome apps! More »