开发者

Best way to pick up text in a HTML element that is in the parent node only

开发者 https://www.devze.com 2022-12-09 03:04 出处:网络
I have, for example, markup like this <div id=\"content\"> <p>Here is some wonderful text, and here is a <a href=\"#\">link</a>. All links should have a `href` attribute.</

I have, for example, markup like this

<div id="content">
    <p>Here is some wonderful text, and here is a <a href="#">link</a>. All links should have a `href` attribute.</p>
</div>

Now I want to be able to perform some regex replace on the text inside the p element, but not in开发者_如何学Python any HTML, i.e. be able to match the href within backticks, but not inside the anchor element.

I thought about regex, but as the general consensus is, I shouldn't be using them to parse HTML.

My current method of doing this is like so: I've got a bunch of words in an array, and I am looping through them and making an object of data like so:

termsData[term] = {
       regex: new RegExp('(\\b' + term + '\\b)', 'gmi'),
       replaceWith:  '<span>{TERM}</span>'
    };

I then loop through it again, making the replacements like so:

var html = obj.html();

$.each(terms, function(i, term) {


     // Replace each word in the HTML with the span
     html = html.replace(termsData[term].regex, termsData[term].replaceWith.replace(/{TERM}/, '$1'));


 });

 obj.html(html);

Now I did a lot of this last night at an ungodly hour, and copying and pasting it into here seems to make think I should refactor some of this.

So from you should be able to tell, I want to be able to replace plain text, but not anything inside a HTML tag.

What would be the best way to do it?

Note: The source code is coming from here if you'd like a better look.


You're right to not want to be processing HTML with regex. It's also bad news to be assigning huge chunks of .html(); apart from the performance drawbacks of serialising and reparsing a large amount of HTML, you'll also lose unserialisable data like event listeners, form data and JS properties/references.

See the findText function in this answer and call something like (assuming obj is a jQuery wrapper over your topmost node to search in):

findText(obj[0], /\b(term1|term2|term3)\b/g, function(node, match) {
    var span= document.createElement('span');
    node.splitText(match.index+match[0].length);
    span.appendChild(node.splitText(match.index));
    node.parentNode.insertBefore(span, node.nextSibling);
});
0

精彩评论

暂无评论...
验证码 换一张
取 消