Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I ensure saved click coordinates can be reloaed to the same place, even if the page layout changed?

Tags:

javascript

I'm storing click coordinates in my db and then reloading them later and showing them on the site where the click happened, how do I make sure it loads in the same place?

Storing the click coordinates is obviously the simple step, but once I have them if the user comes back and their window is smaller or larger the coordinates are wrong. Am I going about this in the wrong way, should I also store an element id/dom reference or something of that nature.

Also, this script will be run over many different websites with more than one layout. Is there a way to do this where the layout is independent of how the coordinates are stored?

like image 845
Tomas Avatar asked Apr 13 '10 17:04

Tomas


2 Answers

Yeah, there are many, many ways a page's layout can alter between loads. Different window sizes, different font sizes, different font availability, different browser/settings (even a small change in layout or font preference can throw out the wrapping). Storing page-relative co-ordinates is unlikely to be that useful unless your page is almost entirely fixed-size images.

You could try looking up the ancestors of the clicked element to find the nearest easily-identifiable one, then make a plot from that element down to the element you want based on which child number it is.

Example using simple XPath syntax:

document.onclick= function(event) {     if (event===undefined) event= window.event;                     // IE hack     var target= 'target' in event? event.target : event.srcElement; // another IE hack      var root= document.compatMode==='CSS1Compat'? document.documentElement : document.body;     var mxy= [event.clientX+root.scrollLeft, event.clientY+root.scrollTop];      var path= getPathTo(target);     var txy= getPageXY(target);     alert('Clicked element '+path+' offset '+(mxy[0]-txy[0])+', '+(mxy[1]-txy[1])); }  function getPathTo(element) {     if (element.id!=='')         return 'id("'+element.id+'")';     if (element===document.body)         return element.tagName;      var ix= 0;     var siblings= element.parentNode.childNodes;     for (var i= 0; i<siblings.length; i++) {         var sibling= siblings[i];         if (sibling===element)             return getPathTo(element.parentNode)+'/'+element.tagName+'['+(ix+1)+']';         if (sibling.nodeType===1 && sibling.tagName===element.tagName)             ix++;     } }  function getPageXY(element) {     var x= 0, y= 0;     while (element) {         x+= element.offsetLeft;         y+= element.offsetTop;         element= element.offsetParent;     }     return [x, y]; } 

You can see it in action using this JSFiddle: http://jsfiddle.net/luisperezphd/L8pXL/

like image 154
bobince Avatar answered Sep 24 '22 18:09

bobince


I prefer not using the id selector and just going recursive.

function getPathTo(element) {     if (element.tagName == 'HTML')         return '/HTML[1]';     if (element===document.body)         return '/HTML[1]/BODY[1]';      var ix= 0;     var siblings= element.parentNode.childNodes;     for (var i= 0; i<siblings.length; i++) {         var sibling= siblings[i];         if (sibling===element)             return getPathTo(element.parentNode)+'/'+element.tagName+'['+(ix+1)+']';         if (sibling.nodeType===1 && sibling.tagName===element.tagName)             ix++;     } } 
like image 24
Scott Izu Avatar answered Sep 24 '22 18:09

Scott Izu