John Doe John Doe - 6 months ago 11
Javascript Question

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

Answer

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)
Comments