brendanhalloran Posted April 12, 2010 Share Posted April 12, 2010 I am working on some JavaScript to enhance my Google Analytics tracking code. I would like to be able to get the div id value when an anchor link is clicked on.For example, when the link "Home" is clicked on from the webpage http://www.diird.vic.gov.au/home which contains the following source code (which has been greatly simplified): <html><head><title>Home - Dept of Innovation, Industry & Regional Development</title></head><body><!-- START Left Column --> <div id="contentleft"> <ul id="mainnav"> <li class=""><a href="http://www.diird.vic.gov.au/home">Home</a></li> </ul> </div><!-- END Left Column --></body></html> I would like to be able to get the div id value of "contentleft" and insert it into the resulting Google Analytics tracking cookie. The tracking cookie already contains the following information:document.titleinnerHTMLhrefbut I would like to be able to add the div id value. If this can be done, the resulting relevant text string in the tracking cookie would like like this:PageTitle=Home - Dept of Innovation, Industry & Regional Development&LinkText=Home&LinkHREF=http://www.diird.vic.gov.au/home&LinkDIV=contentleftI have some partially working code, but this only gets the immediate parentNode value of the clicked link, rather than the div id value: function getDIV(oEvent){ var divID; if (oEvent.srcElement){ divID = oEvent.srcElement.parentNode.id; } else{ divID = oEvent.target.parentNode.id; } return divID;} Link to comment Share on other sites More sharing options...
jeffman Posted April 12, 2010 Share Posted April 12, 2010 Pass a reference to the clicked element itself. In-tag script would look like this: onclick = "getDIV(this)"; Now you have a reference to the source without sweating over it. Use a while loop to work your way up the tree: function getDIV(mynode){ while (mynode.nodeName.lowerCase() != "div") { mynode = mynode.parentNode; if (mynode.nodeName.lowerCase() == "body") { return false; // failsafe } } return mynode;} That's off the top of my head. Better check it for errors.Of course the whole thing becomes much simpler if you can give your <a> and <div> elements id's that are similar in some way, so the the <div> id can be derived from the <a> id. Link to comment Share on other sites More sharing options...
Synook Posted April 12, 2010 Share Posted April 12, 2010 Note that DD's function has conflicting casing for the mynode variable. Link to comment Share on other sites More sharing options...
jeffman Posted April 12, 2010 Share Posted April 12, 2010 Good catch. I think my edit got it right. Link to comment Share on other sites More sharing options...
brendanhalloran Posted April 13, 2010 Author Share Posted April 13, 2010 Good catch. I think my edit got it right.Thanks for your help with this problem.I agree that it would be easier for all anchor links to have id's, however, implementing that would be a task involving significant resources. The main reason for trying to write some JavaScript code is to automatically pick up information based on existing website setups without having to go back and change existing coding.I put replaced my code with your code and the following error was reported in Firebug:mynode.nodeName is undefinedAlso, I think that your suggestion won't solve the problem because I need to use event listeners rather than the "while" method. This is because a tracking cookie needs to be fired off at the instant the link is clicked.A colleague of mine that that the following code might be closer to the solution:function getDIV(mynode){ var divID; if (mynode.srcElement){ divID = mynode.srcElement.parentNode.id; } else{ divID = mynode.target.parentNode.id; } while (divID.nodeName.lowerCase() != "div"){ divID = divID.parentNode; if (divID.nodeName.lowerCase() == "body"){ return false; // failsafe } } return divID;} however, the following error the following error was reported in Firebug:divID.nodeName is undefinedPerhaps a fuller explanation of what is trying to be achieved here would help.This function is being written in an attempt to get the "parent" div id value when an anchor link is clicked on a page on a website. This is an effort to make sure that there is a unique identifier for all links on a page, because a link might appear twice on a page with the same innerHTML. Such duplicate links should be in different divs, so this would enable them to be uniquely identified.The full JavaScript of this "click tracking" measurement attempt is below - it is integrated into existing code that automatically tracks clicks on outbound links, file downloads and mailto links: // Start Tracking external links, file downloads, mailto links - www.diird.vic.gov.au //// START OF FILE ///*gaAddons.jsAuthor: Stephane Hamel - shamel67@gmail.com - http://immeria.netContributors:- Andy Edmonds - http://alwaysbetesting.com- Damon Gudaitis - http://www.damongudaitis.com- Brian Clifton - http://www.advanced-web-metrics.com- Brendan Halloran & Chaminda Subasinghe - http://www.diird.vic.gov.auLicense: Version: MPL 1.1The contents of this file are subject to the Mozilla Public License Version1.1 (the "License"); you may not use this file except in compliance withthe License. You may obtain a copy of the License athttp://www.mozilla.org/MPL/Software distributed under the License is distributed on an "AS IS" basis,WITHOUT WARRANTY OF ANY KIND, either express or implied. See the Licensefor the specific language governing rights and limitations under theLicense.GENERAL NOTES (BH):* This gaAddons.js file should be called after the main Google Analytics tracking code, but before the closing "body" tag.* Has been tested on and works with both IE and Firefox - should work with all other major browsers.* Does not track javascript actions, for example "java script:()" - some other scripts track this type of interaction and it shows up in your GA reports as "undefined" (or similar).* If any "download/undefined" or "outbound/undefined" records show up in your reports, it is likely that there are some hyperlinks that have been incorrectly coded - check to see if there are any "font" or other tags within the "ahref" tag of the links.PAGEVIEW VS EVENT TRACKING:* This script has been split into two sections. The first section is for pageview tracking implementation, and the second is for event tracking.* The pageview implementation tracks mouse and keyboard interaction, but the event implementation only tracks mouse interaction.* This is because you can't filter event tracking data in Google Analytics, and you need to be able to implement the filters described below for accurate data collection and reporting where keyboard interaction occurs.IMPORTANT NOTES RE DATA INTEGRITY - PAGEVIEW TRACKING IMPLEMENTATION ONLY:* Most other similar javascript files track "click" mouse actions only (this is when a user pushes down and then releases the left mouse button).* This javascript file tracks "mouseup" (the release of a left, middle or right mouse button) and "keyup" (the release of any key on the keyboard) actions.* PLEASE NOTE that all "keyup" actions are tracked - you must restrict the reporting to when the user releases appropriate keys. In order to do do this, a "flag" has been added to the end of the pageview constructor, and all pageviews without the correct "flag" should be filtered out by use of an exclude filter. The filter below is based on identifying what are not valid combinations: * Filter Name: Exclude pageviews from undesired keyup actions generated by gaAddons.js Filter Type: Custom filter Exclude Filter Field: Request URI Filter Pattern: .*KeyCode=(([4-9])|([1][0-2])|([1][4-9])|([2-9][0-9])|([1-9][0-9][0-9])).* Case Sensitive: No* If you want to ensure that ?EventType=[type]&KeyCode=[number]&Button=[number] does not appear in your Top Content reports, you need to implement a second filter that will remove this string. The filter is as follows: * Filter Name: Remove ?EventType=...&KeyCode=...&Button=... from end of URLs Filter Type: Advanced Field A -> Extract A: Request URI (.*)(\?EventType.*) Field B -> Extract B: - Output To -> Constructor: Request URI $A1 Field A Required Yes Field B Required No Override Output Field Yes Case Sensitive No* The order of the filters is crucial - they must be in the order above.WHAT IS BEING TRACKED?(Pageview tracking implementation)* Left, centre and right mouse button actions (mouseup) in both IE and FF for Outbound, Download and Mailto* Enter key after tabbing and also after activiating the contextmenu (activated by holding down Shift+F10) in both IE and FF for Outbound, Download and Mailto - exceptions are: * Enter Key after tabbing in FF not tracking for Mailto * Enter Key after contextmenu in IE not tracking for Outbound or Download(Event tracking implementation)* Left, centre and right mouse button actions (mouseup) in both IE and FF for Outbound, Download and Mailto* The data being sent to Google Analytics when using Event Tracking is in the following format: Category (download, outbound, mailto) Action (click) Label (filename.pdf, www.outbound-domains.com, emailaddress@all-domains.com) Value (not used)*/var extTrack = ["diird.vic.gov.au"];/** Specifies the domain/s (and all associated subdomains) that is/are NOT to be treated as outbound links.* Insert the root domain of the website here without the leading "www."* If you do insert the leading "www." here, links to any subdomains of the website will be treated as outbound links.* Alternatively, you can use [location.host] to automatically recognise current website domain as internal. However, links to any subdomains of the website will be treated as outbound links.* For example, if you have links from www.domain.com to sub.domain.com and don't want clicks on those links to show up as "outbound", then you should not use [location.host].* You can have more than one domain listed here - the method is ["website1.com","website2.org"]. This is handy if you have links to shopping carts on 3rd party provider websites (for example).*/var gaA_fileTypes = new RegExp(/\.(docx*|xlsx*|pptx*|doc|xls|ppt|exe|zip|pdf|xpi|csv|js|txt|rdf|wma|mov|avi|wmv|wav|mp3|mp4|mpg|pps|ppt|swf|rar|rtf)$/i);/*Indicate each file extension that needs to be tracked: gaA_fileTypes is the regular expressionthat matches downloadable files.*/var gaPAGE_pageTracker = WOVGTracker;var gaPAGE_pageTracker = DIIRDTracker;var gaPAGE_pageTracker = pageTracker;var gaPAGE_pageTracker = SiteOverlayTracker;/** The above variable(s) must reflect those in your GATC.* You can add more lines for additional tracker variables depending on the number of accounts/profiles you have included in your Google Analytics tracking code and whether you want these accounts/profiles to record this data. For example, you could add var gaPAGE_pageTracker = rollupTracker; if you had rollupTracker._trackPageview(); in your Google Analytics tracking code.* You will need to modify the remainder of this script based on whether you have one profile or multiple profiles to report into, and also whether you want the data going into multiple profiles to be identified differently in each case.*/// PAGEVIEW TRACKING VERSION - MOUSEUP AND KEYUP //if (document.getElementsByTagName && typeof gaPAGE_pageTracker === "object"){ var hrefs = document.getElementsByTagName('a'); for (var l = 0, m = hrefs.length; l < m; l++){ var fireListner = 0; if (hrefs[l].href.indexOf("mailto:") != -1){ startListening(hrefs[l], "mouseup", trackMailtoLinks); startListening(hrefs[l], "keyup", trackMailtoLinks); } // Loop trough all the extTrack parameters and set up listners only if links are outbound (external: not listed in extTrack, and also not a mailto link, regardless of domain). // for (var j=0; j<extTrack.length; j++){ if (hrefs[l].href.indexOf(extTrack[j]) == -1 && hrefs[l].href.indexOf('google-analytics.com') == -1 && hrefs[l].href.indexOf("mailto:") == -1){ fireListner++; } } if (fireListner == extTrack.length){ startListening(hrefs[l], "mouseup", trackExternalLinks); startListening(hrefs[l], "keyup", trackExternalLinks); } // Set up listener for file downloads only if link is internal (listed in extTrack). Links to file downloads on outbound (external) websites will be captured as outbound. // if (gaA_fileTypes.test(hrefs[l].pathname) && fireListner != extTrack.length){ startListening(hrefs[l], "mouseup", trackDocuments); startListening(hrefs[l], "keyup", trackDocuments); } // Set up listner for Site Overlay Tracking - tracks activity on all HREFs - uses Event tracking. // startListening(hrefs[l], "mouseup", trackAllAnchorLinks); } // Set up listner for Site Overlay Tracking - tracks activity on all form submit buttons - uses Event tracking. // startFormsListener();}function startListening(obj, evnt, func){ if (obj.addEventListener) obj.addEventListener(evnt, func, false); else if (obj.attachEvent){ obj.attachEvent("on" + evnt, func); }}function startFormsListener(){ if (window.addEventListener){ window.addEventListener("load", attachFormSubmit, false); } else if (window.attachEvent){ window.attachEvent("onload", attachFormSubmit); }}function attachFormSubmit(){ var forms = document.getElementsByTagName('form'); for (var x = 0, y = forms.length; x < y; x++){ if (forms[x]){ if (forms[x].addEventListener){ forms[x].addEventListener("submit", trackFormSubmit, false); } else if (forms[x].attachEvent){ forms[x].attachEvent("onsubmit", trackFormSubmit); } } }}function getValues(eEvent){ var eVal = [], e; if (eEvent.which){ eVal[0] = eEvent.type; eVal[1] = eEvent.which; eVal[2] = eEvent.button; } else{ e = window.event; eVal[0] = e.type; eVal[1] = e.keyCode; eVal[2] = e.button; } return eVal;}function extractFName(oFName){ var exFName = oFName.toString().split(/[\///]/g).reverse()[0]; return exFName;}function removeSpaces(a){ a = a.replace(/^[\s]*|[\s]*$/g,''); // Strips out single leading and trailing spaces around the LinkText value in trackAllAnchorLinks return a}function getDIV(mynode){ if (mynode.nodeName.lowerCase() != "div"){ mynode = mynode.parentNode; if (mynode.nodeName.lowerCase() == "body"){ return false; } } return divID;}function trackMailtoLinks(evnt){ eVals = getValues(evnt); var elmnt = evnt.srcElement; if (elmnt){ if (elmnt.protocol == "mailto:") WOVGTracker._trackPageview("DIIRD/diird.vic.gov.au/mailto/" + elmnt.href.replace(/mailto:/, "") + "?EventType=" + eVals[0] + "&KeyCode=" + eVals[1] + "&Button=" + eVals[2] + "&refURL=" + location.pathname + location.search + "&LinkText=" + elmnt.innerHTML); DIIRDTracker._trackPageview("diird.vic.gov.au/mailto/" + elmnt.href.replace(/mailto:/, "") + "?EventType=" + eVals[0] + "&KeyCode=" + eVals[1] + "&Button=" + eVals[2] + "&refURL=" + location.pathname + location.search + "&LinkText=" + elmnt.innerHTML); pageTracker._trackPageview("mailto/" + elmnt.href.replace(/mailto:/, "") + "?EventType=" + eVals[0] + "&KeyCode=" + eVals[1] + "&Button=" + eVals[2] + "&refURL=" + location.pathname + location.search + "&LinkText=" + elmnt.innerHTML); SiteOverlayTracker._trackPageview("mailto/" + elmnt.href.replace(/mailto:/, "") + "?EventType=" + eVals[0] + "&KeyCode=" + eVals[1] + "&Button=" + eVals[2] + "&refURL=" + location.pathname + location.search + "&LinkText=" + elmnt.innerHTML); } else{ if (this.protocol == "mailto:") WOVGTracker._trackPageview("DIIRD/diird.vic.gov.au/mailto/" + this.href.replace(/mailto:/, "") + "?EventType=" + eVals[0] + "&KeyCode=" + eVals[1] + "&Button=" + eVals[2] + "&refURL=" + location.pathname + location.search + "&LinkText=" + this.innerHTML); DIIRDTracker._trackPageview("diird.vic.gov.au/mailto/" + this.href.replace(/mailto:/, "") + "?EventType=" + eVals[0] + "&KeyCode=" + eVals[1] + "&Button=" + eVals[2] + "&refURL=" + location.pathname + location.search + "&LinkText=" + this.innerHTML); pageTracker._trackPageview("mailto/" + this.href.replace(/mailto:/, "") + "?EventType=" + eVals[0] + "&KeyCode=" + eVals[1] + "&Button=" + eVals[2] + "&refURL=" + location.pathname + location.search + "&LinkText=" + this.innerHTML); SiteOverlayTracker._trackPageview("mailto/" + this.href.replace(/mailto:/, "") + "?EventType=" + eVals[0] + "&KeyCode=" + eVals[1] + "&Button=" + eVals[2] + "&refURL=" + location.pathname + location.search + "&LinkText=" + this.innerHTML); }}function trackExternalLinks(evnt, atext){ eVals = getValues(evnt); var elmnt = evnt.srcElement; if (elmnt){ while (elmnt.tagName !== "A") elmnt = elmnt.parentNode; if (/http/.test(elmnt.protocol)) WOVGTracker._trackPageview("DIIRD/diird.vic.gov.au/outbound/" + elmnt.href + "?EventType=" + eVals[0] + "&KeyCode=" + eVals[1] + "&Button=" + eVals[2] + "&refURL=" + location.pathname + location.search + "&LinkText=" + elmnt.innerHTML); DIIRDTracker._trackPageview("diird.vic.gov.au/outbound/" + elmnt.href + "?EventType=" + eVals[0] + "&KeyCode=" + eVals[1] + "&Button=" + eVals[2] + "&refURL=" + location.pathname + location.search + "&LinkText=" + elmnt.innerHTML); pageTracker._trackPageview("outbound/" + elmnt.href + "?EventType=" + eVals[0] + "&KeyCode=" + eVals[1] + "&Button=" + eVals[2] + "&refURL=" + location.pathname + location.search + "&LinkText=" + elmnt.innerHTML); SiteOverlayTracker._trackPageview("outbound/" + elmnt.href + "?EventType=" + eVals[0] + "&KeyCode=" + eVals[1] + "&Button=" + eVals[2] + "&refURL=" + location.pathname + location.search + "&LinkText=" + elmnt.innerHTML); } else{ if (/http/.test(this.protocol)) WOVGTracker._trackPageview("DIIRD/diird.vic.gov.au/outbound/" + this.href + "?EventType=" + eVals[0] + "&KeyCode=" + eVals[1] + "&Button=" + eVals[2] + "&refURL=" + location.pathname + location.search + "&LinkText=" + this.innerHTML); DIIRDTracker._trackPageview("diird.vic.gov.au/outbound/" + this.href + "?EventType=" + eVals[0] + "&KeyCode=" + eVals[1] + "&Button=" + eVals[2] + "&refURL=" + location.pathname + location.search + "&LinkText=" + this.innerHTML); pageTracker._trackPageview("outbound/" + this.href + "?EventType=" + eVals[0] + "&KeyCode=" + eVals[1] + "&Button=" + eVals[2] + "&refURL=" + location.pathname + location.search + "&LinkText=" + this.innerHTML); SiteOverlayTracker._trackPageview("outbound/" + this.href + "?EventType=" + eVals[0] + "&KeyCode=" + eVals[1] + "&Button=" + eVals[2] + "&refURL=" + location.pathname + location.search + "&LinkText=" + this.innerHTML); }}function trackDocuments(evnt){ eVals = getValues(evnt); fileName = extractFName ((evnt.srcElement) ? evnt.srcElement.pathname : this.pathname); WOVGTracker._trackPageview("DIIRD/diird.vic.gov.au/download/" + ((evnt.srcElement) ? fileName + "?EventType=" + eVals[0] + "&KeyCode=" + eVals[1] + "&Button=" + eVals[2] + "&refURL=" + location.pathname + location.search + "&LinkText=" + evnt.srcElement.innerHTML : fileName + "?EventType=" + eVals[0] + "&KeyCode=" + eVals[1] + "&Button=" + eVals[2] + "&refURL=" + location.pathname + location.search + "&LinkText=" + this.innerHTML)); DIIRDTracker._trackPageview("diird.vic.gov.au/download/" + ((evnt.srcElement) ? fileName + "?EventType=" + eVals[0] + "&KeyCode=" + eVals[1] + "&Button=" + eVals[2] + "&refURL=" + location.pathname + location.search + "&LinkText=" + evnt.srcElement.innerHTML : fileName + "?EventType=" + eVals[0] + "&KeyCode=" + eVals[1] + "&Button=" + eVals[2] + "&refURL=" + location.pathname + location.search + "&LinkText=" + this.innerHTML)); pageTracker._trackPageview("download/" + ((evnt.srcElement) ? fileName + "?EventType=" + eVals[0] + "&KeyCode=" + eVals[1] + "&Button=" + eVals[2] + "&refURL=" + location.pathname + location.search + "&LinkText=" + evnt.srcElement.innerHTML : fileName + "?EventType=" + eVals[0] + "&KeyCode=" + eVals[1] + "&Button=" + eVals[2] + "&refURL=" + location.pathname + location.search + "&LinkText=" + this.innerHTML)); SiteOverlayTracker._trackPageview("download/" + ((evnt.srcElement) ? fileName + "?EventType=" + eVals[0] + "&KeyCode=" + eVals[1] + "&Button=" + eVals[2] + "&refURL=" + location.pathname + location.search + "&LinkText=" + evnt.srcElement.innerHTML : fileName + "?EventType=" + eVals[0] + "&KeyCode=" + eVals[1] + "&Button=" + eVals[2] + "&refURL=" + location.pathname + location.search + "&LinkText=" + this.innerHTML));}function trackAllAnchorLinks(evnt){ var elmnt = evnt.srcElement; divIDs = getDIV(evnt); // Attempt to get the div id value of the link that is clicked on. // START - Attempt to get the link number of the link that is clicked on. Currently returning "-1" // for (var l = 0, m = hrefs.length; l < m; l++){ for (var j = 0; j < extTrack.length; j++) var linkNumber = hrefs[l].href.indexOf(extTrack[j] == -1 || extTrack[j] != -1); } // END - Attempt to get the link number of the link that is clicked on. Currently returning "-1" // if (elmnt){ SiteOverlayTracker._trackEvent("SiteOverlayTracking", "click", ("PageTitle=" + document.title + "&LinkText=" + removeSpaces(elmnt.innerHTML) + "&LinkHREF=" + elmnt.href + "&LinkDIV=" + divIDs + "&LinkNumber=" + linkNumber)); } else{ SiteOverlayTracker._trackEvent("SiteOverlayTracking", "click", ("PageTitle=" + document.title + "&LinkText=" + removeSpaces(this.innerHTML) + "&LinkHREF=" + this.href + "&LinkDIV=" + divIDs + "&LinkNumber=" + linkNumber)); }}function trackFormSubmit(attachFormSubmit){ divIDs = getDIV(attachFormSubmit); SiteOverlayTracker._trackEvent("SiteOverlayTracking", "click", ("PageTitle=" + document.title + "&LinkDIV=" + divIDs));}// END OF FILE //// End Tracking external links, file downloads, mailto links - www.diird.vic.gov.au // Link to comment Share on other sites More sharing options...
jeffman Posted April 13, 2010 Share Posted April 13, 2010 If nodeName is undefined, then you are not accessing a page element. Indeed, looking at your code, I see you're passing the function I gave you an event, when I specifically showed you that you should be passing a node reference (that's what the this keyword does). An event won't work; of course it has no nodeName property. You can certainly bind the function to the change event using addEventListener/attachEvent if you like, but either way the function was designed to receive a node reference, not an event. The whole point of passing an element reference instead of an event was to bypass all that nasty source/target businessThe version of my function that you embedded in the big code box above will not work because you're returning the value of a variable (divID) that doesn't exist in the function.I have no idea what the problem is with the function you quote at the top of the page because I have no idea what object reference you are passing it. Link to comment Share on other sites More sharing options...
brendanhalloran Posted April 14, 2010 Author Share Posted April 14, 2010 If nodeName is undefined, then you are not accessing a page element. Indeed, looking at your code, I see you're passing the function I gave you an event, when I specifically showed you that you should be passing a node reference (that's what the this keyword does). An event won't work; of course it has no nodeName property. You can certainly bind the function to the change event using addEventListener/attachEvent if you like, but either way the function was designed to receive a node reference, not an event. The whole point of passing an element reference instead of an event was to bypass all that nasty source/target businessThe version of my function that you embedded in the big code box above will not work because you're returning the value of a variable (divID) that doesn't exist in the function.I have no idea what the problem is with the function you quote at the top of the page because I have no idea what object reference you are passing it.Thanks for your further help with this. After considering your feedback, we have been able to further modify the code so that we are now able to get the div id value of the clicked link and pass it into the tracking cookie. The code is now:function getDIV(evnt){ var divID; if (evnt.srcElement){ divID = evnt.srcElement; } else{ divID = evnt.target; } while (divID.nodeName.toLowerCase() != "div"){ divID = divID.parentNode; if (divID.nodeName.toLowerCase() == "body"){ return false; } } return divID.id;} Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.