John Doe
John Doe

Reputation: 29

Change a line of text inside element without changing other nested elements

I want to change text in my div (since it is server-bounded) so I need to change it through a script. Why is my javascript not working?

JS:

$(function() { 
     $(".byline:contains('May)").html('Posted during period of May');
});

HTML screenshot:

enter image description here

edit: when I fixed ('May) to (May) or ('May'), the new problem is that "geplaatst door" is also replaced, I only want to replace the line that contains May

Upvotes: 0

Views: 238

Answers (3)

Aprillion
Aprillion

Reputation: 22304

you have extra single quote in :contains('May) => :contains(May)

edit: to only change 1 particular child of .byline, you need select only that one particular child element, not the whole parent element

edit2:

  • if you wish to only replace the exact text May to a new text, you can do that using regex replace, where the /.../g means global replacement, if the text May can be present multiple times:

    $(function() {
      var elem = $(".byline:contains(May)")
      var new_html = elem.html().replace(
        /May/g,
        "$1Posted during period of May$2");
      elem.html(new_html);
    }); 
    
  • but if you wish the change the whole textual part of the .byline element in between other nested elements that contains May, then it'll get more complicated - either avoid that by editing the HTML to wrap the text to its own element like <span class="date">May, 2015</span>, or see Is there an alternative to jQuery / sizzle that supports textNodes as first class citizens in selectors?, or use a bit more complex regular expression:

    $(function() {
      var elem = $(".byline:contains(May)")
      var new_html = elem.html().replace(
        /((?:^|>)\s*)[^<>]+May[^<>]+(\s*(?:<|$))/,
        "$1Posted during period of May$2");
      elem.html(new_html);
    });
    

fiddle: https://jsfiddle.net/Aprillion/f6mcawd1/3/

regex explanation: https://regex101.com/r/hL1eN7/

/((?:^|>)\s*)[^<>]+May[^<>]+(\s*(?:<|$))/g
    1st Capturing group ((?:^|>)\s*)
        (?:^|>) Non-capturing group
            1st Alternative: ^
                ^ assert position at start of the string
            2nd Alternative: >
                > matches the characters > literally
        \s* match any white space character [\r\n\t\f ]
            Quantifier: * Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
    [^<>]+ match a single character not present in the list below
        Quantifier: + Between one and unlimited times, as many times as possible, giving back as needed [greedy]
        <> a single character in the list <> literally (case sensitive)
    May matches the characters May literally (case sensitive)
    [^<>]+ match a single character not present in the list below
        Quantifier: + Between one and unlimited times, as many times as possible, giving back as needed [greedy]
        <> a single character in the list <> literally (case sensitive)
    2nd Capturing group (\s*(?:<|$))
        \s* match any white space character [\r\n\t\f ]
            Quantifier: * Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
        (?:<|$) Non-capturing group
            1st Alternative: <
                < matches the characters < literally
            2nd Alternative: $
                $ assert position at end of the string
    g modifier: global. All matches (don't return on first match)

Upvotes: 1

Kartikeya Sharma
Kartikeya Sharma

Reputation: 553

You can try this approach: You have to expand the selector and it will work

$(".byline>span:contains('May)").html('Posted during period of May');`

Upvotes: 0

napo
napo

Reputation: 869

Looks like you were missing a closing single quote in May.

$(".byline:contains('May')").html('Posted during period of May');

Working example right here: https://jsfiddle.net/b55Lv052/

Upvotes: 0

Related Questions