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