0

I search this site a lot and have had many good answers, this is the first time I've needed to ask a question because I just can't find an answer.

My script is injected into pages that users load, so those pages could be totally arbitrary structure. There's always some special text on the page that I want to be able to retrieve automatically the next time they visit that page (it's a live value so I'm kind of scraping this value).

The pages are so arbitrary, the only way I can do it is to have the user double click on the value to 'train' the script and detect the event and the element that was double clicked. This works fine, I can retrieve the value I want and I have a jQuery object for the element.

What I can't figure out is how to store that element (or more precisely a selector for it) so I can retrieve the data next time they go to the page without needing them to double-click it.

Here's a jsFiddle http://jsfiddle.net/troywray/YvSH9/ and if you double-click the red text, the text I want is easily retrieved. But what can I store away to be able to reproduce the selector later?

$('body').bind("dblclick", function(event){
    var dblClickElement = $(event.target);
    var specialText = dblClickElement.html();
    alert("I picked up: " + specialText);
    console.log(dblClickElement);
    console.log("selector result:", $(dblClickElement).selector); // empty string
});

Console says that dblClickElement is an object [span.abcde] but it's a clickable object in firebug. What I want is the string 'span.abcde' so I could use that to select in future. There doesn't seem to be a property of the jquery object that equals span.abcde

I thought I'd found something relevant here: Get the current jQuery selector string? but it doesn't work here (proof is in the fiddle and I get why).

I don't really want suggestions for parsing inner/outer html to build a selector string - if I have to do that, then no doubt I can figure that out.

Also, I do realise that in many cases the selector might not give me a single unique element but I can handle that.

Community
  • 1
  • 1
Troy Wray
  • 938
  • 5
  • 15
  • 3
    The problem is - a single node can have many many selectors. You can't convert a node into a selector without traversing the DOM tree and building a selector you like. – Dogbert May 20 '13 at 18:24
  • Are you okay with DOM-traversal to build the selector manually, or do you want to avoid *all* traversale/HTML manipulation? – David Thomas May 20 '13 at 18:26
  • @Dogbert - thanks - good point. I suppose I'm thinking that in the jsFiddle, *I* didn't tell jQuery to use span.abcde but something has decided that's the selector - and tag.class would be a good selector in this instance. I shouldn't have said I have to have span.abcde. I just need a selector that will return one or more elements, including the one I really want (I'm assuming I can get an array of elements and determine what index is the one I want e.g. $('span')[4] – Troy Wray May 20 '13 at 18:37
  • @David - I'm not against dom traversal but can that give me a unique selector for the element if I don't know the intervening elements have ids, names or even classes? I figured something like firebug shows the path to an element as body/div[2]/p/span[1] might be useful to describe the element – Troy Wray May 20 '13 at 18:41
  • 1
    I would like to suggest this link. http://stackoverflow.com/questions/2068272/getting-a-jquery-selector-for-an-element/2068381#2068381 – Stephan Ahlf May 20 '13 at 18:43
  • the biggest problem with building the selector via tree traversal is that there are many third party browser addins that may alter the DOM. it's not a guarantee from visit to visit. – fnostro May 20 '13 at 18:49
  • @Stephan - thanks, that is a very relevant link, I failed to find that. – Troy Wray May 20 '13 at 18:54
  • @fnostro good point although in this application they could 'retrain' the app at any time if it stops scraping the right value – Troy Wray May 20 '13 at 18:54
  • @Troy - ah...no worries then :) – fnostro May 20 '13 at 18:56

2 Answers2

0

Why not set a cookie? There's a jquery plugin for that http://www.electrictoolbox.com/jquery-cookies/ if you cna only retrieve the text once the page is loaded, or if the text is available on the server, have the server set the cookie?

Joe Miller
  • 3,843
  • 1
  • 23
  • 38
  • no, cross purposes I think. I can send a selector back to the server to be stored no problem (I could use cookies too). The issue is not the storage/retrieval of the selector, it's putting the selector in a form I can use so when that same page loads in future I can do (in principle) x = $(myStoredSelector).html() – Troy Wray May 20 '13 at 18:44
0

The answer was to use the top voted getPath function from the link pointed out by @Stephan. Note that there's reference to another getPath function that doesn't work with ambiguous nodes.

getPath gives a string that can be saved for future reference e.g.

html>body>div>p:eq(2)>span.abcde

For finding the element in future from the stored path I used (not optimised):

var bits = path.split(">");
var currentElement = null;
for (var k = 0; k < bits.length; k += 1) {
    if (k === 0) {
        currentElement = $(bits[k]);
    } else {
        currentElement = currentElement.children(bits[k]);
    }
}
var desiredText = currentElement.html();

As pointed out by @fnostro, this depends on the DOM structure remaining constant between uses but for my application that's not a problem.

Troy Wray
  • 938
  • 5
  • 15