corleoner corleoner - 4 months ago 11
jQuery Question

Ajax auto refresh causing my jquery embed script to repeat endlessly

OK, my disclaimer, regarding script, I'm green as a cucumber.

I've recently set up jquery-oembed on my site (phpbb forum), it's a code which auto embeds media content from various sites like youtube, twitter, facebook etc...

It works great, except I'm having trouble integrating it into my chat box. The chat functions through an ajax code which auto refreshes in intervals. Depending on where I put my script, the embed will either show a link and not embed until you manually refresh the page....or....it will embed, but constantly repeat itself over and over every time the ajax refreshes. I've been playing around with this a lot, I try to avoid bothering you guys unless it's absolutely necessary.

Here's the oembed code, which works find on the posts in my site.

(function($) {
$(document).ready(function() {
$(".avatarMessage .postlink").oembed(null, {
embedMethod: "append",
startClosed: true,
maxWidth: 300,
});
});
})


The best I could find through searching was this snippet which I tried. If I change it to add:

(function($) {
$(document).ready(function() {
$(".avatarMessage .postlink").oembed(null, {
embedMethod: "append",
startClosed: true,
maxWidth: 300,
});
while (update.firstChild) {
update.removeChild(update.firstChild);
}
});
})


Then it won't keep repeating it, but it also won't allow for new url's to embed, so I can't use this one.

Is there something I could add for this which would limit the removeChild to just the content of that message, or perhaps another idea that I'm just completely not seeing (don't get frustrated with me, I'm trying, I just don't have much experience outside the basic html and css).

In case anyone is interested, here is the ajax code which fires the auto refresh.

https://raiderforums.com/mchat/mchat_ajax_mini.js

Thanks for putting up with me :)

Answer

This is happening because each time you call $(".avatarMessage .postlink").oembed(....) all matched elemenets will be compiled even if they are already compiled. To prevent that you can add a new-post class and remove it after the element is compiled/embeded:

(function($) {
    $(document).ready(function() {
        $(".avatarMessage .postlink.new-post").oembed(null, {
            embedMethod: "append",
            startClosed: true, 
            maxWidth: 300,
        }).removeClass('new-post');
    });
})

Thus, the elements will not be matched on the next oembed call.

Here is another alternative, it uses a flag instead:

(function($) {
    $(document).ready(function() {
        $(".avatarMessage .postlink").each(function(index, element) {
            var $el = $(element);
            //If already embedded just return
            if ($el.data('oembedded')) return;
            //set the flag
            $el.data('oembedded', true);
            $el.oembed(null, {
                embedMethod: "append",
                startClosed: true,
                maxWidth: 300,
            });
        });
    });
});

I hope this will help you.