在开发过程中,经常需要在不改变原有代码的基础上,为现有的jQueryWidget添加新的功能。这可以通过多种方式实现,但本文将介绍一种简单且有效的方法。这种方法不仅允许添加新的选项、私有字段和方法,还可以覆盖现有的方法,并在覆盖的方法中调用基方法。
首先,创建一个简单的文本格式化器(textFormatter)Widget,它用于改变元素的字体大小。虽然这只是一个简单的功能,但它将作为技术演示的基础。
(function($) {
var textFormatter = {
options: {
defaultFontSize: '12px'
},
_currentFontSize: null,
_create: function() {
this._currentFontSize = this.options.defaultFontSize;
},
_init: function() {
this._refreshText();
},
changeSize: function(size) {
this._currentFontSize = size;
this._refreshText();
},
_refreshText: function() {
$(this.element).css('font-size', this._currentFontSize);
}
};
$.widget('hik.textFormatter', textFormatter);
})(jQuery);
接下来,展示如何使用这个textFormatterWidget。
<div id="TestDiv">A text for test</div>
<script type="text/javascript">
$('#TestDiv').textFormatter({
defaultFontSize: '14px'
});
$('#TestDiv').textFormatter('changeSize', '20px');
</script>
现在,想要为这个Widget添加一个新的功能:改变文本颜色。为此,需要添加一个新的选项defaultColor,一个新的方法changeColor,并覆盖现有的_refreshText方法,以便在刷新文本时同时更新字体大小和颜色。
(function($) {
var base = {
_create: $.hik.textFormatter.prototype._create,
_refreshText: $.hik.textFormatter.prototype._refreshText
};
$.extend(true, $.hik.textFormatter.prototype, {
options: {
defaultColor: 'green'
},
_currentColor: null,
_create: function() {
base._create.apply(this, arguments);
this._currentColor = this.options.defaultColor;
},
changeColor: function(color) {
this._currentColor = color;
this._refreshText();
},
_refreshText: function() {
base._refreshText.apply(this, arguments);
$(this.element).css('color', this._currentColor);
}
});
})(jQuery);
为了在覆盖方法时保留对基方法的引用,首先定义了一个名为base的对象。然后,使用jQuery.extend方法(设置deep=true)来合并选项,并添加所有定义的方法到textFormatter Widget。
现在,可以调用新的changeColor方法,并使用defaultColor选项,如下所示:
<div id="TestDiv">A text for test</div>
<script type="text/javascript">
$('#TestDiv').textFormatter({
defaultFontSize: '14px',
defaultColor: 'blue'
});
$('#TestDiv').textFormatter('changeSize', '20px');
$('#TestDiv').textFormatter('changeColor', 'red');
</script>
接下来,想要为Widget添加一个新的功能:改变字体粗细(例如,使文本加粗或正常)。以下是扩展:
(function($) {
var base = {
_create: $.hik.textFormatter.prototype._create,
_refreshText: $.hik.textFormatter.prototype._refreshText
};
$.extend(true, $.hik.textFormatter.prototype, {
options: {
defaultFontWeight: 'normal'
},
_currentFontWeight: null,
_create: function() {
base._create.apply(this, arguments);
this._currentFontWeight = this.options.defaultFontWeight;
},
changeFontWeight: function(fontWeight) {
this._currentFontWeight = fontWeight;
this._refreshText();
},
_refreshText: function() {
base._refreshText.apply(this, arguments);
$(this.element).css('font-weight', this._currentFontWeight);
}
});
})(jQuery);
<div id="TestDiv">A text for test</div>
<div>
<div>
Enter new font size:
<input type="text" id="NewFontSize" value="20px"/>
<button id="ChangeFontSize">Change font size</button>
</div>
<div>
Enter new color:
<input type="text" id="NewColor" value="red"/>
<button id="ChangeColor">Change font color</button>
</div>
<div>
Enter new font weight:
<input type="text" id="NewFontWeight" value="bold"/>
<button id="ChangeFontWeight">Change font weight</button>
</div>
</div>
<script type="text/javascript">
$('#TestDiv').textFormatter({
defaultFontSize: '14px',
defaultColor: 'blue',
defaultFontWeight: 'regular'
});
$('#ChangeFontSize').click(function () {
$('#TestDiv').textFormatter('changeSize', $('#NewFontSize').val());
});
$('#ChangeColor').click(function () {
$('#TestDiv').textFormatter('changeColor', $('#NewColor').val());
});
$('#ChangeFontWeight').click(function () {
$('#TestDiv').textFormatter('changeFontWeight', $('#NewFontWeight').val());
});
</script>