David
David

Reputation: 16756

find(), each() and replacewith() in passed HTML in jQuery

I have some HTML code that i'm passing to a function which is mean't to find all iframes, replace the iframe code with an image and then return the modified html. However, it doesn't seem to replace the iframe code in the returned html. I'm pretty sure im just referencing hte replacement wrongly, but can't find any examples online similar to what im trying to do. They all reference searching the whole of a document or after the html is displayed in the document. This HTML isn't and can't be due to application requirements.

Please Note: I have already generated youtube code to replace the iframe code. The problem is with performing the replace.

function article_youtube_convert(html) {
    //go throught the iframes for youtube and convert them to embed

    $(html).find('iframe').each(function(i) {
                     alert(this.src);
        //ok what we need to do here is check if it's youtube 
        src_youtube = this.src;
        if(src_youtube.indexOf('http://www.youtube.com')!=-1){
           //so now we need the video id 
           url_parts = src_youtube.split('/');

           youtube_id = url_parts[url_parts.length-1];

           url_parts = youtube_id.split('?');
           youtube_id = url_parts[0];

           youtube_link = 'http://www.youtube.com/watch?v='+youtube_id;
           img_youtube = '<a id="tempvid" href="'+youtube_link+'"><img src="http://img.youtube.com/vi/'+youtube_id+'/0.jpg"/><br />View YouTube Video</a>';

            $(this).replaceWith(img_youtube);


                     //alert(document.getElementById('tempvid').innerHTML);  
        }
    });
    return html;


}

UPDATE

I have decided to try using an outerHTML approach and replace the text with the new replacement text in the variable as per below. I alert the full source without a problem, but it still doesn't replace it.

jQuery.fn.outerHTML = function(s) {
    return s
    ? this.before(s).remove()
    : jQuery("<p>").append(this.eq(0).clone()).html();
};


function article_youtube_convert(passed) {
    //go throught the iframes for youtube and convert them to embed
    //alert('inside');
    newhtml = passed;
    //alert(newhtml);
    $(newhtml).find('iframe').each(function(i) {
                     //alert(this.src);
        //ok what we need to do here is check if it's youtube 
        src_youtube = this.src;
        if(src_youtube.indexOf('http://www.youtube.com')!=-1){
           //so now we need the video id 
           url_parts = src_youtube.split('/');
                                   alert('youtube vid');
           youtube_id = url_parts[url_parts.length-1];

           url_parts = youtube_id.split('?');
           youtube_id = url_parts[0];

           youtube_link = 'http://www.youtube.com/watch?v='+youtube_id;
           img_youtube = '<a id="tempvid" href="'+youtube_link+'"><img src="http://img.youtube.com/vi/'+youtube_id+'/0.jpg"/><br />View YouTube Video</a>';
                                   alert('alert: '+$(this).outerHTML());
                                   sourcethe = $(this).outerHTML();
                                   passed.replace(sourcethe,img_youtube);
            //$(this).replaceWith(img_youtube);
                                   //alert($(this));


                     //alert(document.getElementById('tempvid').innerHTML);  
        }
    });
    alert(passed);
    return passed;


}

Upvotes: 2

Views: 1810

Answers (3)

Chris
Chris

Reputation: 27627

It looks like you are not actually returning what you want from that function...

You never actually alter html in your method, you just use it to do some stuff that gets discarded and then return what you put in.

What you most likely want to do is something like

var jqHtml = $(html);
...Do stuff to modify jqHtml...
return jqHtml.html();

One thing I am not sure on and haven't tested is whether .html() returns what you want. The docs say it uses the elements innerHTML property but I'm not sure if that will give the correct thing with jquery objects constructed from strings (I think it should).

Anyway, that is your basic problem, you are not modifying html at all. $(html) is taking a copy of the html string, not a reference to it that it can update as needed.

Upvotes: 1

Martin Vrkljan
Martin Vrkljan

Reputation: 879

David, I just made a quick test and wrote a simple HTML page with three iframe elements and copied your code. I wrapped the iframes in a <div id="test"> element and called article_youtube_convert ("div#test");. The iframes got replaced flawlessly.

<div id="test">
  <iframe width="560" height="315" src="http://www.youtube.com/embed/Z5y-UIjhjuM" frameborder="0" allowfullscreen></iframe>
  <iframe width="560" height="315" src="http://www.youtube.com/embed/Z5y-UIjhjuM" frameborder="0" allowfullscreen></iframe>
  <iframe width="560" height="315" src="http://www.youtube.com/embed/Z5y-UIjhjuM" frameborder="0" allowfullscreen></iframe>
</div>

Are you sure you're passing the right html context to the article_youtube_convert function?

Upvotes: 1

paulslater19
paulslater19

Reputation: 5917

I think you want

  url_parts = youtube_id.split('?');
  youtube_id = url_parts.pop();

But note that the youtube_id will include the v=, so you could do: url_parts.pop().substring(2)

Upvotes: 0

Related Questions