2

For the following project I will be using PHP and jQuery.

I have the following code:

$('*').onclick(function(){

});

Once a user clicks on an element I want it to return the XPath location of that element.

What I want to do essentially is sort of a filtering system with a little help of jQuery.

PHP will retrieve a document from an outside source with PHP, using jQuery a user click on an element/relevant parts of that document. This jQuery function will return the XPath location of where the user clicked and is stored and associated with that document.

In the future if that document is updated, using the XPath, PHP will retrieve only the XPath that was selected by the user previously instead of the whole document.

I will need this jQuery function to also return element attributes such as the title in a <p> or href location in an anchor link.

Long story short: My question is, is this even possible in jQuery? Returning the XPath location of a selected element along with it's attributes? I have no idea what this would look like in jQuery so any help would be appreciated.

Any other additional feedback would be great too. As far as I know I could be using the wrong tools... or something. Thanks.

Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431
Tek
  • 2,888
  • 5
  • 45
  • 73
  • 1
    You should *never* use `$('*').eventhandler`, it'll attach a handler to every single element in the DOM, which is just...bad, very bad. – Nick Craver Dec 10 '10 at 00:08
  • No worries, that wasn't production code, it was just to get the idea out. – Tek Dec 10 '10 at 01:04

2 Answers2

6

You can use the .parents() method, to get all ancestors of the clicked element.

$(document).delegate('*','click',function(){
  var path = $(this).parents().andSelf();
  return false;
});

and then extract the info you want.

Use the .delegate method to handle the event, so you do not need to attach it to all elements. And also use the .andSelf() method to include in the path the item that was clicked as well.


A more complete example

$(document).delegate('*','click',function(){
    var path = $(this).parents().andSelf();
    var xpath='/';
    for (var i = 0; i < path.length; i++)
    {
        var nd = path[i].nodeName.toLowerCase();
        xpath += '/';
        if (nd != 'html' && nd != 'body')
        {xpath += nd+'['+ ($(path[i-1]).children().index(path[i])+1) +']';}
        else
        {xpath += nd;}                    
    }
    alert(xpath);
    return false;
});

Example with a test html to play at http://www.jsfiddle.net/gaby/hsv97/1/


update with id and class shown as well : http://www.jsfiddle.net/gaby/hsv97/2/

Gabriele Petrioli
  • 191,379
  • 34
  • 261
  • 317
  • Would he not also need to get the index of siblings inside each parent – redsquare Dec 10 '10 at 00:14
  • Yes, this is just to point in the right direction. There could be many optimizations, like if there is an `id` in the hierarchy it could start from there, etc. But from the example, you have a list of all the elements in the xpath and you can start extracting the info you want for each. – Gabriele Petrioli Dec 10 '10 at 00:17
1

a fix to Gaby aka G. Petrioli

added "nd" to children

.children(nd)

full:

$(document).delegate('*','click',function(){
        var path = $(this).parents().andSelf();
        var xpath=''; // firebug xpath starts with '/html'
        for (var i = 0; i < path.length; i++) {
            var nd = path[i].nodeName.toLowerCase();
            if (nd =="tbody") continue;  // php DOMxpath ignores tbody? or browser fixes html?
            xpath += '/';
            if (nd != 'html' && nd != 'body')
            {xpath += nd+'['+ ($(path[i-1]).children(nd).index(path[i])+1) +']';} //! saving time ha?
            else
            {xpath += nd;}                    
        }
        alert(xpath);
        return false;
    });
Hontoni
  • 1,332
  • 1
  • 16
  • 27