如果一个表单里有大量的 combo 控件(20个以上), 则 combo 的性能影响就开始凸显.
研究了一下 easyui 的 combo 创建代码, 把性能提升 40% 以上是完全可行的,
我找到的 combo 代码版本比较旧, 只是用来说明问题吧,
原 combo 代码最大的性能瓶颈在于 init() 里调用了 setSize(target, width);
只要注释掉该函数, 性能立即提升 40%以上
;
该函数做了2件事:
1) 计算 combo-text 的宽度
2) 计算 panel 的尺寸
其中第2步完全没必要在 init 时计算, 第1步也有优化的余地. 我的改进方案如下:
// 传入 options 参数
function init(target,
opts){
$(target).hide();
var span = $('<span class="combo"></span>').insertAfter(target);
var input = $('<input type="text" class="combo-text">').appendTo(span);
$('<span><span class="combo-arrow"></span></span>').appendTo(span);
$('<input type="hidden" class="combo-value">').appendTo(span);
// jxc: 计算input的宽度
var width = calcInputWidth(opts);
input.width(width); var panel = $('<div class="combo-panel"></div>').appendTo('body');
panel.panel({
doSize:false,
closed:true,
style:{
position:'absolute'
},
onOpen:function(){
// jxc: open 时再计算 panel 尺寸
panel.panel('resize', {
width: (opts.panelWidth ? opts.panelWidth : span.outerWidth()),
height: opts.panelHeight
}); $(this).panel('resize');
}
});
var name = $(target).attr('name');
if (name){
span.find('input.combo-value').attr('name', name);
$(target).removeAttr('name').attr('comboName', name);
}
input.attr('autocomplete', 'off');
return {
combo: span,
panel: panel
};
}
// 缓存input和arrow的宽度, 避免重复计算 var inputWidth = null;
var arrowWidth = null;
function calcInputWidth(opts){
if (!inputWidth) {
var input = $('<input type="text" class="combo-text">').appendTo("body");
var arrow = $('<span class="combo-arrow">').appendTo("body");
inputWidth = input.outerWidth();
arrowWidth = arrow.outerWidth();
input.remove();
arrow.remove();
}
if (isNaN(opts.width)){
opts.width = inputWidth;
}
var width = opts.width - arrowWidth;
return width;
}
初始化部分的修改
// jxc: init 调用, 传入 optionsvar opts = $.extend({}, $.fn.combo.defaults, parseOptions(this), options);
var r = init(this, opts);
state = $.data(this, 'combo', {
options:
opts,
combo: r.combo,
panel: r.panel
});
// jxc: init 时不再调用 setSize// setSize(this);