4

I'm trying to grab a particular string, " (TEXT 1)", " (TEXT 2)", etc. I cannot change the HTML.

When I do this:

$(this).parent().html(); // $(this) is equivalent to $('a.more').

I get:

<a class="more" href="/e1">Event 1</a> (TEXT 1)<br>
<a class="more" href="/e2">Event 2</a> (TEXT 2)<br>
<a class="more" href="/e3">Event 3</a> (TEXT 3)<br>

I've already tried this and this.

I can't seem to get a particular "(TEXT n)". Ideally I'd like to get a particular "(TEXT n)". Something along the lines of:

$('a.more').nextText(1); // this would return " (TEXT 2)"

How can I get a particular string with either JavaScript or jQuery?

Community
  • 1
  • 1
Howard
  • 3,648
  • 13
  • 58
  • 86

4 Answers4

5

As your post implies, if you want to create a custom .nextText() method, just access the nodeValue property of the DOM element's next sibling:

$.fn.nextText = function() {
  return this.length ? this[0].nextSibling.nodeValue : null;
};

Then you can use the .eq() method to get the element by its index and use the custom method:

Example Here

var text = $('.more').eq(0).nextText();
console.log(text); // (TEXT 1)

If you want to add a parameter to pass the index of the element you want to retrieve the text from:

Example Here

$.fn.nextText = function(index) {
  return this.length ? this[index || 0].nextSibling.nodeValue : null;
};

var text = $('.more').nextText(1);
console.log(text); // (TEXT 2)

If you want to get multiple elements and text nodes until a specific element (as the OP did in the comments), you can use this custom .nextTextUntil() method:

Example Here

$.fn.nextTextUntil = function(until) {
  var text = '', next;

  if (this.length) {
    next = this[0].nextSibling;

    while (next !== null && until && !$(next).is(until)) {
      text += next.nodeValue || next.textContent;
      next = next.nextSibling;
    }
  }

  return text;
};

Usage:

$('.more').eq(0).nextTextUntil('.more');

Would return:

(TEXT 1 MORE TEXT)

Based on the following HTML:

<a class="more" href="/e1">Event 1</a> (TEXT 1 <em>MORE TEXT</em>)
Josh Crozier
  • 233,099
  • 56
  • 391
  • 304
  • I'm having an issue. When the html looks like this: Event 1 (TEXT 1 MORE TEXT ASDF) - helloworld
    I'm only getting " (TEXT 1". How can I get the full " (TEXT 1 MORE TEXT ASDF) - helloworld "?
    – Howard Dec 28 '15 at 09:38
  • @rotaercz How do you know when to stop retrieving text? Do you want to get all elements and text nodes *until* the next `.more` element? – Josh Crozier Dec 28 '15 at 12:26
  • Basically I'd like to retrieve everything at the same sibling level (and children) as "(TEXT 1)". Does that make sense? – Howard Dec 28 '15 at 12:53
  • Yes, you're right. I'd like to get all elements and text nodes until the next .more element but at the sibling and children level (no parents). – Howard Dec 28 '15 at 13:00
  • 1
    @rotaercz Like this? https://jsfiddle.net/wn95Lksb/ I created a `.nextTextUntil()` method. – Josh Crozier Dec 28 '15 at 14:27
  • 1
    That worked perfectly. If I could upvote your answer again I would. Thank you! – Howard Dec 28 '15 at 14:35
2

You can use the nextSibling method of the underlying DOMElement to get the sibling textNode. Try this:

console.log($('.more')[0].nextSibling.nodeValue)); // = '(TEXT 1)'

Example fiddle

Note that to get the textNode next to the other .more elements, you can change the index to 1 or 2.

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
2

This seems to work, or am I misunderstandig your exact question?

https://jsfiddle.net/xhp86ygq/

document.querySelector('.more').nextSibling.nodeValue

Now if you need a function that does this for a given node:

getNextTextnodeValue = function(element) {
    return element.nextSibling.nodeValue;
};

Really writing this into a jQuery plugin would just add lots of bulk to the code, and you'd gain nothing as it's not chainable (returns a string, not a jQuery object).

Norbert
  • 603
  • 5
  • 10
1

My proposal, not efficent, but all in jQuery consists in finding a small area where you can reduce the search:

$.fn.getTextNodes = function(contentText) {
  return $(this).find(":not(iframe)").addBack().contents().filter(function() {
    return this.nodeType == 3 && this.nodeValue.indexOf(contentText) != -1;
  });
};

$(function () {
  var result = $('#areaWhereToSearch').getTextNodes('(TEXT 1)');
  if (result.length == 1) {
    $('#result').text($('#areaWhereToSearch').getTextNodes('(TEXT 1)')[0].nodeValue);
  }
});
<script src="//code.jquery.com/jquery-1.11.3.js"></script>


<div id="areaWhereToSearch">
    <a class="more" href="/e1">Event 1</a> (TEXT 1)<br>
    <a class="more" href="/e2">Event 2</a> (TEXT 2)<br>
    <a class="more" href="/e3">Event 3</a> (TEXT 3)<br>
</div>
<p id="result"></p>
gaetanoM
  • 41,594
  • 6
  • 42
  • 61