我有以下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);
});
};
调用堆栈为:
jQuery.event.trigger
(anonymous function)
jQuery.extend.each
jQuery.fn.jQuery.each
jQuery.fn.extend.trigger
jQuery.fn.(anonymous function)
e.fn.extend.focus
(anonymous function)
jQuery.event.dispatch
elemData.handle.eventHandle
jQuery.event.trigger
(anonymous function)
jQuery.extend.each
jQuery.fn.jQuery.each
jQuery.fn.extend.trigger
jQuery.fn.(anonymous function)
e.fn.extend.focus
(anonymous function)
jQuery.event.dispatch
elemData.handle.eventHandle
jQuery.event.trigger
(anonymous function)
jQuery.extend.each
jQuery.fn.jQuery.each
jQuery.fn.extend.trigger
jQuery.fn.(anonymous function)
e.fn.extend.focus
(anonymous function)
jQuery.event.dispatch
elemData.handle.eventHandle
jQuery.event.trigger
(anonymous function)
jQuery.extend.each
etc..
最佳答案
我认为问题在于您将复选框包装到<label>
标记中。在我的情况下,这会导致相同的错误。因此,您可以像这样放置您的复选框:
<label for="checkbox-1">Some label</label>
<input type="checkbox" id="checkbox-1">
关于javascript - Chrome未捕获RangeError:最大调用堆栈大小超过了单击递归,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19963137/