×

Search anything:

Tracking cursor using JavaScript

Binary Tree book by OpenGenus

Open-Source Internship opportunity by OpenGenus for programmers. Apply now.

In this article, I will show you how to keep track of the cursor position with a timestamp and download the data into a text file.


Table of contents:

  1. Demo

  2. HTML structure

  3. Styles with CSS

  4. JavaScript functionality:

    • cursor position
    • text file creation

1. Demo

tracking_cursor

2. HTML structure

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Tracking cursor</title>
    <link rel="stylesheet" href="./style.css" type="text/css" />
  </head>
  <body>
    <h1>Tracking cursor using JavaScript</h1>
    <div id="content">
      <h3>Cursor position</h3>
      <p>X: <span id="clientX"></span></p>
      <p>Y: <span id="clientY"></span></p>
      <p>Timestamp: <span id="timestamp"></span></p>
      <button id="download">Download file</button>
    </div>
    <script src="./index.js"></script>
  </body>
</html>

The HTML structure is very simple.

Inside the body element, I have a div with an id content that contains the p and span elements which hold the data of the cursor position. I also have a button that will download the data for us in a text file.

The p elements hold the information such as the XY coordinates of the cursor and the timestamp whenever the cursor moves.

The span elements will be referenced in the JavaScript code and their text content will be the data.

3. Styles with CSS

/* Reset CSS */
*,
*::before,
*::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20%;
  height: 100vh;
  padding: 50px 0;
}

h1 {
  color: rgb(82, 82, 82);
}

#content {
  border: solid gainsboro;
  width: 50%;
  max-width: 600px;
  padding: 15px;
  display: flex;
  flex-direction: column;
  gap: 15px;
}

h3 {
  color: rgb(70, 186, 253);
  margin-bottom: 20px;
}

p {
  color: rgb(70, 186, 253);
  font-weight: 700;
}

span {
  color: rgb(82, 82, 82);
  font-weight: normal;
}

button {
  padding: 10px;
  cursor: pointer;
  font-weight: 700;
  width: 150px;
  border: 1px solid gainsboro;
}

I personally like to reset the styles every time I'm using regular CSS to style my projects. The benefit of this is that we can remove the default styles (for example margin and padding) so our project can look quite the same across the browsers. The box-sizing property lets us include both padding and border in the element's width and height.

I centered everything on the page and added basic styling to the elements.

4. JavaScript functionality

const positionX = document.getElementById('clientX');
const positionY = document.getElementById('clientY');
const timeStamp = document.getElementById('timestamp');
const downloadBtn = document.getElementById('download');

const data = [];

document.addEventListener('mousemove', (event) => {
  positionX.textContent = event.clientX;
  positionY.textContent = event.clientY;
  timeStamp.textContent = event.timeStamp;
  data.push(
    `Timestamp: ${timeStamp.textContent}, Cursor position-X: ${positionX.textContent}, position-Y: ${positionY.textContent}\n`
  );
  console.log(data);
});

downloadBtn.addEventListener('click', () => {
  // Create a new file with the data
  const file = new Blob([data], { type: 'text/plain' });
  // Create a link element
  const link = document.createElement('a');
  // Create a URL
  link.href = URL.createObjectURL(file);
  // Download the file
  link.download = 'tracking_data.txt';
  // Click the link
  link.click();
});

At the top of the file, I reference all the span elements by their id and store them in variables. After that, I declared a variable called, data, and assigned an empty array where I will keep the data.

Cursor position

document.addEventListener('mousemove', (event) => {
  positionX.textContent = event.clientX;
  positionY.textContent = event.clientY;
  timeStamp.textContent = event.timeStamp;
  data.push(
    `Timestamp: ${timeStamp.textContent}, Cursor position-X: ${positionX.textContent}, position-Y: ${positionY.textContent}\n`
  );
  console.log(data);
});

I added an event listener to the document object to listen to the mousemove event.
Whenever we start to move the cursor on the page, the callback function inside the event listener gets called.
We will get the XY coordinates for the cursor by getting the events clientX and clientY methods and assign them to be the span elements text content.
We do the same for the timestamp, once we start moving the cursor the time starts to run in milliseconds. You can see in the demo above, once the cursor stops, the time stops being recorded in the text content but it still runs in the background (it doesn't stop once the event started). So like this, we can get the exact timestamp for the current cursor positions.
Every time we move the cursor we get new data and each data is added to the data array. I used string interpolation to gather the data and in the end, I added a new line character (\n) which means each data will be on its own line in the text file.

Text file creation

downloadBtn.addEventListener('click', () => {
  // Create a new file with the data
  const file = new Blob([data], { type: 'text/plain' });
  // Create a link element
  const link = document.createElement('a');
  // Create a URL
  link.href = URL.createObjectURL(file);
  // Download the file
  link.download = 'tracking_data.txt';
  // Click the link
  link.click();
});

To download the data into a text file, we need to add an event listener to the button. This button listens for the click event and once it heard it, it runs the callback function.
Inside the callback, we need to create a file first. We are creating a new instance of Blob which is a file-like object, the first parameter is going to be the data we want to store and the second argument is the type of the file, in this case, it's just a simple text file.
After that, I created another variable called, link, and I'm creating a link element that is assigned to this variable.
For the link element, we need a URL that has to be created as well. For this, I'm using the createObjectURL method on the url object and passing in the file variable as an argument. So it creates a URL for this file.
Since we already created a link element, we can add a download method to it so that when we click the button, the link element's download method gets called and downloads the data into a text file called, tracking_data.txt.
In the end, the click method gets called which means that the link is being clicked whenever we click the button.

Text file example:

Timestamp: 1504.9000000000233, Cursor position-X: 583, position-Y: 0
Timestamp: 1519.9000000000233, Cursor position-X: 606, position-Y: 38
Timestamp: 1526.9000000000233, Cursor position-X: 615, position-Y: 53
Timestamp: 1540.9000000000233, Cursor position-X: 632, position-Y: 85
Timestamp: 1561.9000000000233, Cursor position-X: 653, position-Y: 130
Timestamp: 1576.9000000000233, Cursor position-X: 670, position-Y: 161
Timestamp: 1597.9000000000233, Cursor position-X: 695, position-Y: 209
Timestamp: 1611.9000000000233, Cursor position-X: 707, position-Y: 236
Timestamp: 1625.9000000000233, Cursor position-X: 720, position-Y: 267
Timestamp: 1647.9000000000233, Cursor position-X: 728, position-Y: 293

Here is the live link so you can try it out as well: Tracking cursor with JS

Tracking cursor using JavaScript
Share this