I recently had to create a small web application for university that was required to track user's mouse movements and interactions.

I could use any existing libraries I wanted, but had to keep it reasonable. I did some searching but didn't find any simple code snippets that showed succinctly how to record user's activity and log it to some file using JavaScript.

I pieced together a couple different sources and managed to come up with the following solution. The full source code is available at the bottom for those who need no explanation.

Step One

Buttons to save log data gathered so far

First, we need some buttons to push so that we can capture a snapshot of the users data captured so far, and one to view the data.


<a id="createLogFile">Create Log File</a>
<a id="downloadLogFile">Download Log File</a>

Step Two

Set up the logger.js module

// Anonymous function protects the namespace
(function () {
    var textFile = null,
    data = "", // The data we want to log. We'll populate this in Step Three

    makeTextFile = function (text) {
        var textData = new Blob([text], {type: 'text/plain'});

        // If we are replacing a previously generated file we need to
        // manually revoke the object URL to avoid memory leaks.
        if (textFile !== null) {
            window.URL.revokeObjectURL(textFile);
        }

        textFile = window.URL.createObjectURL(textData);
        return textFile;
    };
})();

The above code defines an anonymous function which is immediately called. Inside this function we define several things, textFile will contain a link to download the textfile.

Step Three

Recording the data

Inside the anonymous function, we'll define how to link the previous two steps.

// When the createLogFile link is clicked,
// we set downloadLogFile's href to the location of the data file.
$("#createLogFile").on("click", function() {
    var link = $('#downloadLogFile');
    link.attr("href", makeTextFile(data));
});

// Anytime mouse is moved on the page,
// append info about the action to our data variable
$(document).mousemove(function(e) {
    data += $.now() + " ";
    data += e.pageX + " ";
    data += e.pageY + " ";
    data += "mousemove\n";
});

// Record similar data for mouseclicks,
// but change the type of the entry
$(document).click(function(e) {
    data += $.now() + " ";
    data += e.pageX + " ";
    data += e.pageY + " ";
    data += "mouseclick\n";
});

This now populates our data variable with information about the user's action.

Conclusion

Putting this all together gives us the following basic structure:

<html>
    <body>
        <a id="createLogFile">Create Log File</a>
        <a id="downloadLogFile">Download Log File</a>

        <script>
            (function () {
                var textFile = null,
                data = "",
                makeTextFile = function (text) {
                    var textData = new Blob([text], {type: 'text/plain'});

                    if (textFile !== null) {
                        window.URL.revokeObjectURL(textFile);
                    }

                    textFile = window.URL.createObjectURL(textData);
                    return textFile;
                };

                $("#createLogFile").on("click", function() {
                    var link = $('#downloadLogFile');
                    link.attr("href", makeTextFile(data));
                });

                $(document).mousemove(function(e) {
                    data += $.now() + " ";
                    data += e.pageX + " ";
                    data += e.pageY + " ";
                    data += "mousemove\n";
                });

                $(document).click(function(e) {
                    data += $.now() + " ";
                    data += e.pageX + " ";
                    data += e.pageY + " ";
                    data += "mouseclick\n";
                });
            })();
        </script>
    </body>
</html>

The result of clicking the 'Download Log File' button is a page such as this:

1445551809516 411 533 mousemove
1445551809527 410 533 mousemove
1445551809538 410 533 mousemove
1445551809551 409 533 mousemove
1445551809577 401 532 mousemove
1445551809589 393 529 mousemove
1445551809601 384 527 mousemove
1445551809613 373 524 mousemove
1445551809626 363 522 mousemove
1445551809638 353 520 mousemove
1445551809649 344 519 mousemove
1445551809664 335 519 mousemove
1445551809676 328 519 mousemove
1445551809688 322 519 mousemove
1445551809700 317 519 mousemove
1445551809712 312 519 mousemove
1445551809897 312 519 mouseclick
1445551810011 312 519 mousemove
1445551810024 312 517 mousemove
1445551810035 314 514 mousemove
1445551810048 318 506 mousemove
1445551810060 328 493 mousemove
1445551810074 346 474 mousemove
1445551810086 372 449 mousemove

Where the first column is a unix-timestamp from JavaScript's Date library (via jquery.now()), the second and third column are x and y mouse coordinate, and the fourth column is the type of action.

This code style is easily extendable by defining new event handlers that add to this log file (for example logging keyboard presses as well as mouse input).

Thanks for reading! I hope I've helped someone somewhere.



Check out my other blog posts! If you found this post interesting, feel free to let me know either on Twitter (@Isaac_M_Jordan), or in the comments section below.

Enjoyed my post? Sign up to the newsletter to receive a small email when I post. No spam, I promise.