jQuery бесконечная рекурсия при попытке вызвать плагин для элементов, добавленных в DOM

РЕДАКТИРОВАТЬ: http://jsfiddle.net/J26Dw/ (нажмите Добавить)

Я хочу позвонить, для каждого флажка, отмеченного атрибутом data-widget="bootstrap-switch", bootstrapSwitch() плагин. Это прекрасно работает с этой простой функцией:

$(function () {
    var activator = 'data-widget="bootstrap-switch"';

    $('input[type="checkbox"][' + activator + ']')
        .each(function () {
            $(this).bootstrapSwitch();
        });
});

Что если флажок был создан / добавлен на лету в DOM, то есть нажатием кнопки?

Я пытался поймать DOMNodeInserted событие, а затем позвоните bootstrapSwitch() на добавленном элементе, только если .data('bootstrap-switch') является undefined, Я получаю следующую ошибку консоли (вместе с большим количеством флажков: P):

Uncaught RangeError: Превышен максимальный размер стека вызовов.

Кто-нибудь может указать мне правильное направление?

$('body').on('DOMNodeInserted', '[' + activator + ']', function(e) {
    var el = $(e.target);

    console.log(el.attr('data-widget')); // Returns "bootstrap-switch", OK

    if (!el.data('bootstrap-switch')) {
        el.bootstrapSwitch(); // Infinite recursion
    }
});

1 ответ

bootstrapSwitch должен вызывать цикл рекурсии. Это явно перестраивает флажок. При этом он должен что-то предпринять, чтобы DomNodeInserted обратный вызов, как удалить целевой элемент и повторно добавить его в документ.

В любом случае, я думаю, что это завершает то, что вы пытаетесь сделать:

$(function () {
    var options   = {},
        selector  = 'input[type="checkbox"][data-widget="bootstrap-switch"]',
        activator = function () { $(this).bootstrapSwitch(options); };

    $(selector).each(activator);

    $('#btn-add').click(function () {
        var $newInput = $('<input>', {
           "type": 'checkbox',
           "data-widget": 'bootstrap-switch'
        });
        $('.holder').append($newInput);
        activator.apply($newInput);
    });

    $('#btn-copy').click(function () {
        var $clonedInput = $('#switch').clone();
        $('.holder').append($clonedInput);
        activator.apply($clonedInput);
    });
});

Скрипка здесь: http://jsfiddle.net/klenwell/LAUx9/

Другие вопросы по тегам