jQuery无限递归当字符串调用DOM上添加的元素上的插件时

jQuery infinite recursion when tring to call a plugin on elements added on the DOM

本文关键字:添加 插件 元素 DOM 递归 无限 字符串 调用 jQuery      更新时间:2023-09-26

编辑: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(:

未捕获的范围错误:超过了最大调用堆栈大小。

有人能给我指正确的方向吗?

$('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
    }
});

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);
    });
});

Fiddle here:http://jsfiddle.net/klenwell/LAUx9/