JSFiddle - React, Tailwind, and code Playground

HTML

<span id="root">
    <span id="2">@child1</span>
    <span>@child2</span>
    @between
    <span>@child3</span>
    <span>
        @childbefore
        <span>@grandchild1</span>
        <span>@grandchild2</span>
    </span>
    @after
</span>
</p>
<button>Mentionify me.</button>

<script src="https://cdnjs.cloudflare.com/ajax/libs/xregexp/2.0.0/xregexp-min.js"></script>

CSS

span{
    display: block;
    padding: 10px;
}

#root              { border: 2px solid red;    }
#root > span       { border: 2px solid yellow; }
#root > span > span{ border: 2px solid green;  }

JavaScript

/*** Declares ***/
//var string = '<span class="mention">@test</span> @test2';
//var wanted = '<span class="mention">@test</span> <span class="mention">@test2</span>';
var regex = /(^|[^@\w])@(\w{1,30})\b/g;
var uniqueCount = 0;





/*** Processing ***/
$('button').on('click',function(){
    mentionRecursive($('span'));
    p('total unique '+uniqueCount);

});

function mentionRecursive(that){
    p('Going inside '+ that[0].innerHTML);
    
    
    //Already mentioned, exit out.
    if(that.hasClass('mention')){
        p('already mentioned. ', 'gray');
        return;
    }
    
    //Has more children, go inside.
    if(that.children().length > 0){
        p('have '+that.children().length+' children.')
        that.children().each(function(){
            mentionRecursive($(this));
        });
    }
    
    
    
    //Out of children
    
    p('found unique '+that[0].innerHTML, 'green');
    console.log(that);
    
    uniqueCount++;
    that.addClass('mention');
    
    

    
}//endfunction













/*** Function Helpers ***/

function p(text, color){
  var $p = $('<p></p>').text(text);
  if(color)
     $p.css('color',color);
    
  $('body').append($p);
}