Mark Boulder
Mark Boulder

Reputation: 14297

Extract elements and text out of one paragraph and insert into another

I have a paragraph full of YouTube videos, and I'm trying to extract those including any text before or after into a chronological succession of new paragraphs. Ie.:

<div>
    <p>before <a class="youtube" href="https://www.youtube.com/watch?v=a5z69NLAdCo"><img src="http://i.ytimg.com/vi/a5z69NLAdCo/hqdefault.jpg"></a> middle 1 <a class="youtube" href="https://www.youtube.com/watch?v=a5z69NLAdCo"><img src="http://i.ytimg.com/vi/a5z69NLAdCo/hqdefault.jpg"></a><a class="youtube" href="https://www.youtube.com/watch?v=a5z69NLAdCo"><img src="http://i.ytimg.com/vi/a5z69NLAdCo/hqdefault.jpg"></a> middle 2 <a class="youtube" href="https://www.youtube.com/watch?v=a5z69NLAdCo"><img src="http://i.ytimg.com/vi/a5z69NLAdCo/hqdefault.jpg"></a> after</p>
</div>

Should be:

<div>
    <p>before</p>
    <p><a class="youtube" href="https://www.youtube.com/watch?v=a5z69NLAdCo"><img src="http://i.ytimg.com/vi/a5z69NLAdCo/hqdefault.jpg"></a></p>
    <p>middle 1</p>
    <p><a class="youtube" href="https://www.youtube.com/watch?v=a5z69NLAdCo"><img src="http://i.ytimg.com/vi/a5z69NLAdCo/hqdefault.jpg"></a></p>
    <p><a class="youtube" href="https://www.youtube.com/watch?v=a5z69NLAdCo"><img src="http://i.ytimg.com/vi/a5z69NLAdCo/hqdefault.jpg"></a></p>
    <p>middle 2</p>
    <p><a class="youtube" href="https://www.youtube.com/watch?v=a5z69NLAdCo"><img src="http://i.ytimg.com/vi/a5z69NLAdCo/hqdefault.jpg"></a></p>
    <p>after</p>
</div>

What I have, unfortunately, messes up the order and creates separate divs for each YouTube as opposed to gathering everything into a single div.

http://jsfiddle.net/frank_o/kyrmq3cn/

$(function () {
    $('.youtube').each(function () {
        var elem = $(this),
            parent = elem.parent(),
            parentContainer = parent.parent(),
            content = parent.contents(),
            index = content.index(this),
            before = content.slice(0, index),
            after = content.slice(index + 1),
            beforeText = before.text(),
            afterText = after.text();

        var beforeOut = $('<p/>').text(beforeText || ''),
            youtubeOut = $('<p/>').append(elem.clone()),
            afterOut = $('<p/>').text(afterText || ''),

            resultDiv = $('<div/>');

        resultDiv.append(beforeOut);
        resultDiv.append(youtubeOut);
        resultDiv.append(afterOut);

        resultDiv.css('border', '5px solid blue');
        resultDiv.insertAfter(parentContainer);

        parentContainer.css('opacity', '0.2')
    });
});

Upvotes: 0

Views: 73

Answers (1)

PeterKA
PeterKA

Reputation: 24638

This should do it. Iterate through the contents of div p and wrap each in a p element, then finally remove the empty div p -- first element.

$(function() {
  $('div p').contents().each(function() {
    $(this).closest('div').append( $('<p/>').html( this )[0] );
  });
  $('div p:empty').remove();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div>
    <p>before <a class="youtube" href="https://www.youtube.com/watch?v=a5z69NLAdCo"><img src="http://i.ytimg.com/vi/a5z69NLAdCo/hqdefault.jpg"></a> middle 1 <a class="youtube" href="https://www.youtube.com/watch?v=a5z69NLAdCo"><img src="http://i.ytimg.com/vi/a5z69NLAdCo/hqdefault.jpg"></a><a class="youtube" href="https://www.youtube.com/watch?v=a5z69NLAdCo"><img src="http://i.ytimg.com/vi/a5z69NLAdCo/hqdefault.jpg"></a> middle 2 <a class="youtube" href="https://www.youtube.com/watch?v=a5z69NLAdCo"><img src="http://i.ytimg.com/vi/a5z69NLAdCo/hqdefault.jpg"></a> after</p>
</div>

Upvotes: 2

Related Questions