Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modifying inserted element inside DOMNodeInserted event produces "too much recursion"

I'm writing code for a message board and when the user is writing a post and clicks "preview" it creates a new DIV element that contains the parsed post. I need to detect when this preview element is created and modify its contents. The following code creates infinite recursion in Chrome, Firefox halts after 5 recursions.

$('#c_post').on('DOMNodeInserted', function(){
    var $preview = $('#c_post-preview');
    if($preview.length) { 
        $preview.html(applyForEach(funcs, $preview.html())); 
    }
});

It's not related to applyForEach because I just added that code and I was getting the recursion error before that but here's the code for that anyway:

function applyForEach(arr, s) {
    for(var i = 0; i < arr.length; ++i) {
        s = arr[i](s);
    }
    return s;
}

var funcs = [createGifvVideo, createGfycatVideo, createHtml5Video];

The functions simply take a string, call replace on it, and returns the string.

like image 768
TheMagician Avatar asked Oct 01 '15 09:10

TheMagician


2 Answers

You may break the infinite recursion by unbinding and binding event . so it would not go into infinite call.Try following-

$('#c_post').on('DOMNodeInserted',DomInsCallback);

function DomInsCallback(){
    var $preview = $('#c_post-preview');
    if($preview.length) {
        $('#c_post').off('DOMNodeInserted');//here unbind first 
        $preview.html(applyForEach(funcs, $preview.html())); 
        $('#c_post').on('DOMNodeInserted',DomInsCallback);//bind again
    }
}
like image 135
Rohit Kumar Avatar answered Nov 05 '22 12:11

Rohit Kumar


I suppose #c_post-preview is inside #c_post. So when you modify #c_post-preview, the event DOMNodeInserted is triggered again. And you catch it again, and you modify #c_post-preview, and so on ...

like image 1
Magus Avatar answered Nov 05 '22 11:11

Magus