-1

I'm testing a simple script where I'm storing an html string into a variable, and want to replace a part of it. My actual code is a large html string, and I cannot use replace() in this case as I have wrap() and nextSibling() functions inside my each().

<script>
var htmlvar = "<html><head></head><body><p><i>test</i></p></body></html>";

htmlvar = $(htmlvar).find('i').each(function() {

          $(this).html('changed');

});

console.log('value: '+htmlvar[0].outerHTML);
</script>

After running the above the output is:

<i>changed</i>

I want to still have the full html tags after my each() function performs the logic on some of the tags. Is there any way to achieve this?

EDIT:

The same thing works with document object

<body>
<p><i>test</i>

<script>

    $(document).find('i').each(function() {

              $(this).wrap('<h1></h1>');

    });

    console.log('value: '+$(document).find('html').html());
    </script>

</body>

Output is full html of the current document.

Babybug
  • 61
  • 1
  • 5
  • `htmlvar` is a string. You can't alter it with jquery dom manipulation methods. – Kevin B Jan 31 '18 at 21:08
  • Are you going to have more than one `` to change? – j08691 Jan 31 '18 at 21:08
  • My actual html has lots of other tags. This is just a sample. – Babybug Jan 31 '18 at 21:09
  • Moving `.find('i').each(function() {` to a new line that acts on `htmlvar` would probably solve your problem. but... i expect it to also remove all the html/body/head tags. If you want to keep them, you might have to re-think your approach. – Kevin B Jan 31 '18 at 21:10
  • Thanks for the reply Kevin. Tried, and still losing other tags – Babybug Jan 31 '18 at 21:11
  • Yes, because when you create an element in an existing dom that contains those tags, those tags get removed. That's just how it be. An alternative would be *not* doing that, but that's probably not a good idea. – Kevin B Jan 31 '18 at 21:12
  • The latter portion of your question is answered here: https://stackoverflow.com/questions/3217632/scrape-an-html-document-with-jquery-is-it-possible/3218941#3218941 TLDR, jquery is useless in this case if you want to keep the html/body/head tags. At that point you're left with parsing the html with plain old string manipulation methods. goodluck with that – Kevin B Jan 31 '18 at 21:20
  • I have edited my question. It's working with document object. But not when I store an html in a variable. Any idea? – Babybug Jan 31 '18 at 21:30
  • the document is a full document. That's an entirely different scenario and isn't going to help with your problem. Read the answer i linked to. The document isn't an html string that is being parsed. – Kevin B Jan 31 '18 at 21:31

2 Answers2

0

If you convert your string to actual DOM nodes wrapped inside of a JQuery object, you then don't need .find. You can just search for the i element within the node (using the context argument to the JQuery selector) and change the text of it.

var $htmlvar = $("<html><head></head><body><p><i>test</i></p></body></html>");
console.log($htmlvar[0].outerHTML);
$("i", $htmlvar).text('changed');
console.log($htmlvar[0].outerHTML);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
  • A down vote 3 seconds after posting?! For the right answer! – Scott Marcus Jan 31 '18 at 21:15
  • Thanks for the reply Scott. My actual code is not a text replacement. It's something like this: $(this.nextSibling).html($(this.nextSibling).wrap( "
    ")); --My point to this question is, if each() function manipulates the found tag of the variable by keeping the other parts
    – Babybug Jan 31 '18 at 21:15
  • I mean... the find existing or not existing is irrelevant to the problem. what fixed it was the other changes you made but didn't mention. `$("i", $htmlvar)` is still a `.find()`. – Kevin B Jan 31 '18 at 21:15
-1

Use append() instead of html(). It will, as the name suggests, append a given string instead of replacing an entire element.

$(this).append('changed');

Philipp Meissner
  • 5,273
  • 5
  • 34
  • 59