2

I have a bit of a strange question, I'm wondering whether this is at all possible.

I'm parsing the DOM and there is an element like this:

<!-- <a class="pager" title="next" href="www.text.com">NEXT</a> -->

I need to be able to select this element with jQuery and return its href value. I've tried this:

$('a.pager[title="Next"]').attr('href');

but to no avail - from reading here Selecting HTML Comments with jQuery it seems that jQuery can only select elements with a particular nodetype.

Is it possible to return the value www.text.com from the HTML element above? To make things a little more tricky, i need to do it without relying on jQuery plugins - native Javascript or plain jQuery only please.

The following code returns the whole comment (as well as the text contained in all other comments on the page):

$("*")
    .contents()
    .filter(function(){ return this.nodeType == 8;})
    .each(function(){ alert(this.nodeValue);});

but I need to ONLY return the value of the a href, and no other comments. Ideas?

Community
  • 1
  • 1
JVG
  • 20,198
  • 47
  • 132
  • 210

3 Answers3

3

Actually, all you have to do is trim it :

var markup = $("*").contents().filter(function(){ 
    return this.nodeType == 8;
}).get(0).nodeValue;

var href = $($.trim(markup)).attr('href');

FIDDLE

EDIT:

to make it more specific you could always do some string matching :

var markup = $("*").contents().filter(function(){ 
    return this.nodeType == 8 && this.nodeValue.indexOf('class="pager"') != -1;
});

EDIT AGAIN:

You could also do :

var href = $.map($("*").contents(), function(el) {
    var html   = $.parseHTML( $.trim(el.nodeValue) ),
        anchor = $('<div />').append(html).find('a.pager[title="next"]');

    return el.nodeType === 8 && anchor.length ? anchor.attr('href') : null;
});

FIDDLE

adeneo
  • 312,895
  • 29
  • 395
  • 388
  • See edited question above - there are multiple comments on the page, I only need the one which contains `title='next'`, and find the href from that element. – JVG Jun 20 '13 at 10:34
  • @Jascination - does it matter, surely you know how to iterate, as you're doing it in the question ? – adeneo Jun 20 '13 at 10:35
  • Kinda true, but I'm unsure about how to iterate and return only the comment that contains `title='next'`. – JVG Jun 20 '13 at 10:41
  • ah, prefect, `&& this.nodeValue.indexOf('class="pager"') != -1;` was exactly what I was looking for (still learning javascript so I'm often unsure of when to use these things! – JVG Jun 20 '13 at 10:45
2

After selecting the comments, you need to parse their text content as HTML before you can reliably traverse the encoded DOM:

var matches = [];
$("*").contents().each(function(){
  if(this.nodeType != 8) return;
  var $div = $("<div>");
  $div.append(this.nodeValue);
  $div.find("a.pager[title='next']").each(function(){
    //replace $(this).attr("href") with this.href if you don't mind
    //relative URLs getting converted to absolute URLs
    matches.push($(this).attr("href"))
  });
});
John Dvorak
  • 26,799
  • 13
  • 69
  • 83
  • This is close, but for some reason the code returns all comment URLs from the page. See here: http://jsfiddle.net/zM5se/159/ click the button and note it shows a jsFiddle comment's url too. – JVG Jun 20 '13 at 10:51
  • @Jascination what do you mean? There is one comment with one `href` inside, and it is found. However, I did notice the browser converts the URL to an absolute URL. If that matters, `this.href` will need to be replaced: http://jsfiddle.net/zM5se/160/ – John Dvorak Jun 20 '13 at 10:54
  • @Jascination you have used a relative URL, which resolves to a link to JSFiddle. The `this.href` property reflects the actual target (at least in Chrome), even if the corresponding attribute doesn't. – John Dvorak Jun 20 '13 at 10:59
-1
$("*")
    .contents()
    .filter(function(){ return this.nodeType == 8;})
    .each(function(){
        var regex = new RegExp('href=\"(.*)\"','g');
        var hrefValue = regex.exec(this.nodeValue)[1];
        alert(hrefValue);
    });
codetantrik
  • 315
  • 2
  • 9
  • Why are you using `new RegExp` instead of the literal syntax? Also, this will crash if _any_ comment on the page doesn't have a HREF inside. – John Dvorak Jun 20 '13 at 11:02
  • does not using literal syntax deserve a negative rating? lol. this will work on all comments in the page which have a href tag-attribute. And yes you are right, i need to check if the regex actually returns a match to avoid a crash. But it does point in the right direction :P. Rest is up to OP to improvise. – codetantrik Jun 20 '13 at 11:18
  • Crashing if there's a non-match is enough to warrant a downvote. I'm wondering if I should downvote Daniel's answer just for using a regex (I think I will). `new RegExp` is merely a red flag that deserves demanding an explanation. And no, the answers should not be incomplete when they claim they are complete. – John Dvorak Jun 20 '13 at 11:23