Jump to content

Script Structure and Use Analysis


Recommended Posts

BACKGROUND:  I found the appended script on the net and am inclined to believe that it could prove very useful.  i would like to share it with you in the hope that those better versed in Javascript than I might provide insight into its proper use.  The annotation enclosed as follows  /* ... */ is mine and may be inaccurate.  

/*
*  Brief Description:  A script for tracking in real time.
*  Date: 20 February 2018 (downloaded from internet)
*  Source:  Neezer at Stackoverflow
*  Link:  https://stackoverflow.com/users/32154/neezer
*/

/****************************************************************************************
Gets element by class name, assigns each to an element of an array, and returns the array.
Apparently, the class name is trackit.
****************************************************************************************/
if (document.getElementsByClassName === undefined) {
    document.getElementsByClassName = function(className) {
      var hasClassName, allElements, results, element;

        hasClassName = new RegExp("(?:^|\\s)" + className + "(?:$|\\s)");
        allElements = document.getElementsByTagName("*");
        results = [];

        for (var i = 0; (element = allElements[i]) !== null; i++) {
            var elementClass = element.className;
            if (elementClass && elementClass.indexOf(className) != -1 && hasClassName.test(elementClass)) {
                results.push(element);
            }
        }

        return results;
    };
}

/****************************************************************************************
* The function that is called when a tracked element is clicked and sets the tracking in motion.
****************************************************************************************/
function addTracker(obj, type, fn) { // adds a tracker to the page, like $('xxx').event
  if (obj.addEventListener) {
    obj.addEventListener(type, fn, false);
  } else if (obj.addEventListener) {
    obj['e' + type + fn] = fn;
    obj[type + fn] = function() {
      obj['e' + type + fn]( window.event );
    };
    obj.attachEvent('on' + type, obj[type + fn]);
  }
}

/****************************************************************************************
* Creates a query string with the tracked information and assigns it to a relative path
leading to a PHP processing file.
****************************************************************************************/
function save_click(passed_object) { // this function records a click
  var now, then, path, encoded, to, from, name, img;

  now = new Date();
  path = '/lib/click.php';
  from = (window.decode) ? window.decodeURI(document.URL) : document.URL;
  to = (window.decodeURI) ? window.decodeURI(passed_object.href) : passed_object.href;
  name = (passed_object.name && passed_object.name != '') ? passed_object.name : '[No Name]';

  // timestamp the path!
  path += '?timestamp=' + now.getTime();

  path += '&to=' + escape(to) + '&from=' + escape(from) + '&name=' + name; // compile the path with the recorded information
  img = new Image();
  img.src = path; // when we call the image, we poll the php page; genius!

  while (now.getTime() < then) {
    now = new Date(); // resets the timer for subsequent clicks
  }
}

/*************************************************************************************************
* Fetches the targeted links by their class assignment and attaches the event handler save_click()
*************************************************************************************************/
function get_targeted_links(target) {
  var links, link;
  if (document.getElementsByClassName) {
    links = document.getElementsByClassName(target);
    for (var i = 0; i < links.length; i++) {
      link = links[i];
      if (link.href) {
        addTracker(links[i], 'mousedown', save_click(links[i])); 
      }
    }
  }
}
/*************************************************************************************************
* The Function Call - Calls the addTracker() function and loads the get_targeted_links() function.
*************************************************************************************************/
addTracker(window, 'load', get_targeted_links('trackit'));

The following is my understanding of the script and my confusion with same. I am requesting that you help to unravel my confusion, so that I might easily implement the script.

SET UP

1) The class name 'trackit' is assigned to those elements on a page that the users wishes to track.

2) The entire script is loaded into the page at the outset by a <script> tag in the <head> element of the document.

3) In the document's jQuery ready( ) function is inserted  the call to the addTracker( ) function.

4) When the page is loaded the activity of the elements to which the class name 'trackit' has been assigned is tracked.

5) Each time a click event takes place, the gathered information is assigned to a query string and appended to a relative path that points to a PHP processing file.

WHAT I DO NOT UNDERSTAND

1) Although it appears that the tracked elements are stored in an array called results, the relationship between the activity that is tracked for each element of the array and the array itself is unclear.  In effect, the user can easily know which elements are being tracked, but to what use is this information when all of the tracking information is stored in a query string?

2) There appears to be know mechanism for sending the query string to the designated relative path -- namely, .../lib/click.php.  For example, when sending form data to a PHP processing file, the type-submit, input control initiates the HTTPRequest.

3) The author has added the comment "adds a tracker to the page, like $('xxx').event".  I simply do not understand the meaning or use of the expression $('xxx').event in this context.  is it not enough to simply assign the class name 'trackit' to each element that the user wishes to track.

HAVE I UNDERSTOOD THE FOLLOWING CORRECTLY

  • timestamp // When the click event takes place.
  • from // the URL of the document on which the click event takes place.
  • to // the address of the document called when the click event takes place.
  • name //  a property of the passed event object that identifies the object -- perhaps, the value of a name or id attribute.

Finally, please comment on my annotations, if you feel that they do not properly explain the role of the function.

Roddy

Good documentation is a somewhat rare commodity on the internet.

Link to post
Share on other sites

I wouldn't recommend using this code.  First, there's a polyfill to define document.getElementsByClassName if it's not already defined, that's there to support browsers older than IE11.  document.getElementsByClassName is supposed to return a list of elements that have a particular class.  That's all the result array is used for.  That's the list of matching elements that gets returned.

The addTracker function is supposed to be a cross-browser way to attach an event, but it's not written correctly.  Spot the error:

  if (obj.addEventListener) {
    obj.addEventListener(type, fn, false);
  } else if (obj.addEventListener) {

The get_targeted_links function is going to immediately send a tracking request for all links on the page, it does not wait for them to be clicked.  In fact, nothing happens when they are clicked.

Quote

There appears to be know mechanism for sending the query string to the designated relative path -- namely, .../lib/click.php.  For example, when sending form data to a PHP processing file, the type-submit, input control initiates the HTTPRequest.

That's where he sets the source of a new image to the PHP page.  The browser will send a request for that URL.  That's a rather lazy way of sending data to the server.  Ajax communication has been possible since IE5, I'm not sure why he describes setting the src of an image as "genius". About the only thing that will do is only cause 1 tracking request per user because the browser will cache that URL thinking it's supposed to be an image.

Quote

The author has added the comment "adds a tracker to the page, like $('xxx').event".  I simply do not understand the meaning or use of the expression $('xxx').event in this context.  is it not enough to simply assign the class name 'trackit' to each element that the user wishes to track.

That "addTracker" function is just supposed to assign an event handler to an element.  We already have terminology for that so I'm not sure why he's calling event handlers "trackers".

Then, finally, all he's doing is tracking page clicks.  That would only be useful if he's trying to track clicks to external websites, otherwise his own web server is already keeping logs of every page the server sends out, and there are plenty of statistics packages to analyze server logs.  Then there are things like Google Analytics which will capture the same kind of information and a whole lot more.  So I'm not sure how much information he's really gathering that's going to be useful.

The save_click function also has a while loop at the end that compares the current timestamp to a variable called then, but he never sets the value of then.  I'm not sure what the point of that loop is, but you never want to use infinite loops in Javascript, you'll bring the browser down.  There's always a better way to do something than have a while loop keep going until the time changes.

  • Thanks 1
Link to post
Share on other sites

Thank you for your insight.  I believe that you have saved me much wasted effort.

I have decided to go with Matomo.  I am not expecting it to be the easiest implementation in the world, but it does appear to be comprehensive and well documented.  Best of all, it is open source and appears to be used by reputable companies.  Hopefully my bad experience with RSS feeds has taught me a lesson.  Go where the documentation is best

Roddy

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...