Javascript Chrome未捕获范围错误:超过最大调用堆栈大小单击递归

Javascript Chrome未捕获范围错误:超过最大调用堆栈大小单击递归,javascript,jquery,Javascript,Jquery,我有以下jquery自定义函数。“全部取消选中”和“全部选中”函数按它们所说的执行。然而,当我点击一个复选框时,我得到了超过最大调用堆栈大小的错误。我遇到了一个正在发生递归的砖墙测试。请告知。多谢各位 $.fn.multiselect = function(fn, options) { if (typeof fn === 'object') { options = fn; fn = 'init'; } if (typeof fn === '

我有以下jquery自定义函数。“全部取消选中”和“全部选中”函数按它们所说的执行。然而,当我点击一个复选框时,我得到了超过最大调用堆栈大小的错误。我遇到了一个正在发生递归的砖墙测试。请告知。多谢各位

$.fn.multiselect = function(fn, options) {
    if (typeof fn === 'object') {
        options = fn;
        fn = 'init';
    }
    if (typeof fn === 'undefined') {
        fn = 'init';
    }
    //return direct methods
    var directMethods = {
        'widget': function() {
            return  $(this).data('multiselect-widget');
        },
        'modal': function() {
            return  $(this).data('multiselect-modal');
        }
    };
    var args = arguments;
    Array.prototype.shift.call(args);
    if (args.length > 0) {
        args.shift();
    }
    if (typeof directMethods[fn] === 'function') {
        return directMethods[fn].apply(this, args);
    }

    var methods = {
        init: function(options) {
            var config = $.extend({}, {}, options || {
                list: 1,
                body: 'body'
            }, $(this).data());
            var $$ = $(this).hide();
            $$.data('multiselect', config);
            var $div = $('<div class="input-append dropdown-multiselect">').insertAfter($$);
            $$.data('multiselect-widget', $div);
            var $span = $('<span class="input-xlarge uneditable-input label" />').appendTo($div);
            var $btn = $('<span class="add-on"><i class="icon-chevron-down"></i></span>').appendTo($div);
            var $modal = $('<div class="modal hide fade modal-multiselect" />')
                    .appendTo($(config.body));
            if ($$.attr('id')) {
                $modal.attr('id', 'modal-multiselect-' + $$.attr('id'));
            }
            $div.click(function() {
                $modal.modal('show');
            });
            $$.data('multiselect-modal', $modal);
            var $menu = $('<div class="modal-body" role="multiselect" />').appendTo($modal);
            var $controls = $('<div class="modal-footer" role="multiselectcontrols" />').appendTo($modal);
            $("<span>").addClass('btn')
                    .appendTo($controls)
                    .text('Close')
                    .click(function() {
                        $modal.modal('hide');
                    });
            if ($$.attr('multiple')) {
                $controls.append($("<span class='btn btn-mini pull-left'>").html('<i class="icon-check-empty"></i>uncheck all').click(function() {
                    $$.val('');
                    $menu.find(":checkbox").prop('checked', false);
                    $$.multiselect('refreshLabel');
                }));
                $controls.append($("<span class='btn btn-mini pull-left'>").html('<i class="icon-check"></i>check all').click(function() {
                    $menu.find(":checkbox").prop("checked", !$(this).prop("checked")).each(function() {
                        $(this).trigger('click');
                        $(this).prop('checked', true);
                    });
                }));
            }
            $$.multiselect('refresh');
        },
        refresh: function() {
            var $menu = $(this).multiselect('modal').find('[role=multiselect]').empty();
            var $controls = $(this).multiselect('modal').find('[role=multiselectcontrols]');
            var $$ = $(this);
            var val = $$.val();
            var type = ($$.attr('multiple')) ? 'checkbox' : 'radio';
            var clickIn = function() {
                var check = $(this).is(":checked");
                var self = this;
                if ($$.attr('multiple')) {
                    var values = $$.val() || [];
                    if (check) {
                        values.push($(this).val());
                    } else {
                        values.splice($.inArray($(this).val(), values), 1);
                    }
                    $$.val(values).multiselect('refreshLabel').trigger('change');
                } else {
                    $menu.find("input[type=radio]").each(function() {
                        if (this !== self) {
                            $(this).prop('checked', false);
                        }
                    });
                    $$.multiselect('modal').modal('hide');
                    $$.val($(this).val()).multiselect('refreshLabel').trigger('change');
                }
                return $(this);
            };
            var $lastParent = $$;
            var $appendTo = $('<ul class="multiselect-menu">').appendTo($menu);
            var $optGroup = null;
            $$.find('option').each(function() {
                if ($(this).parent().is($lastParent) === false) {
                    $lastParent = $(this).parent();
                    if ($lastParent.is('optgroup')) {
                        $optGroup = $('<li>').append($('<label class="optgroup">').text($lastParent.attr('label')));
                    }
                }

                if ($optGroup !== null) {
                    $($optGroup).append(
                            $("<ul>").append($("<li>").append($('<label>').append(
                            $('<input type="' + type + '">')
                            .attr({
                                checked: (typeof val === 'string') ? val === $(this).val() : $.inArray($(this).val(), val) > -1,
                                value: $(this).val()
                            })
                            .click(function() {
                                clickIn.apply(this);
                            })
                            )
                            .append($(this).text()))));
                    $($optGroup).appendTo($appendTo);
                }

                if ($optGroup === null) {
                    $("<li>").appendTo($appendTo)
                            .append($('<label>')
                                    .append(
                                            $('<input type="' + type + '">')
                                            .attr({
                                                checked: (typeof val === 'string') ? val === $(this).val() : $.inArray($(this).val(), val) > -1,
                                                value: $(this).val()
                                            })
                                            .click(function() {
                                                clickIn.apply(this);
                                            })
                                            )
                                    .append($(this).text()));
                }
            });
            $$.multiselect('refreshLabel');
        },
        refreshLabel: function() {
            var self = this;
            var $$ = $(this).multiselect('widget');
            var txt = '';
            var options = $(this).data('multiselect');
            var val = $(this).val() || [];
            if (typeof val === 'string') {
                txt = $(this).find('[value="' + val + '"]').text();
            } else {
                var len = (val) ? val.length : 0;
                if (len > options.list || len === 0) {
                    txt = len + ' of ' + $(this).find('option').length + ' selected';
                } else {
                    var texts = [];
                    $.each(val, function(index, v) {
                       texts.push($(self).find('[value=' + v + ']').text());
                    });
                    txt = texts.join(', ');
                }
            }
            $$.find('.label').text(txt);
        }
    };
    return $(this).each(function() {
        methods[fn].apply(this, args);
    });

};

我认为问题在于将复选框包装到
标记中。在我的案例中,这会导致相同的错误。因此,您可以将复选框如下所示:

<label for="checkbox-1">Some label</label>
<input type="checkbox"  id="checkbox-1">
一些标签

您的焦点事件似乎正在点击$(someele)。触发焦点事件的每个()都会重复该过程。但是,我在您的代码中看不到它(那里的代码太多了…),因此基本上出于某种原因,当您聚焦元素时,焦点事件会再次触发,从而导致无限循环。您是否尝试在代码中的某个位置设置断点,以便可以看到递归发生的位置?这是一个复杂的插件。
<label for="checkbox-1">Some label</label>
<input type="checkbox"  id="checkbox-1">