[英]Jquery plugin with prototype
我嘗試使用Jquery插件的基礎知識和原型概念,但最終出現了異常行為。
HTML:
<div>
<span>
<textarea>Text Area with 500 characters. Adding Some text.</textarea>
<span class="cl"></span>
</span>
<span>
<textarea>Text Area with 100 characters</textarea>
<span class="cl"></span>
</span>
</div>
jQuery的:
(function ($) {
var tisCharsLeftCntxt = null;
function fnCharsLeft(ele, genStngs) {
this.jqe = $(ele);
this.maxChars = genStngs.maxChars;
tisCharsLeftCntxt = this;
this.fnInit();
}
fnCharsLeft.prototype = {
fnInit: function () {
tisCharsLeftCntxt.fnUpdateRemainingChars();
tisCharsLeftCntxt.jqe.keyup(function (event) {
key = event.keyCode ? event.keyCode : event.which;
if ((37 != key) && (38 != key) && (39 != key) && (40 != key)) {
tisCharsLeftCntxt.fnUpdateRemainingChars();
}
});
},
fnUpdateRemainingChars: function () {
var charsLft = tisCharsLeftCntxt.maxChars - tisCharsLeftCntxt.jqe.val().length,
jqeDestToUpdt = tisCharsLeftCntxt.jqe.siblings('.cl');
charsLft = (charsLft < 0) ? 0 : charsLft;
if (charsLft) {
jqeDestToUpdt.text(charsLft + ' more of ' + tisCharsLeftCntxt.maxChars + ' characters');
} else {
tisCharsLeftCntxt.jqe.val(tisCharsLeftCntxt.jqe.val()
.substring(0, tisCharsLeftCntxt.maxChars));
tisCharsLeftCntxt.jqe.scrollTop(tisCharsLeftCntxt.jqe[0].scrollHeight);
jqeDestToUpdt.text("Maximum limit of " + tisCharsLeftCntxt.maxChars + " characters reached");
return false;
}
}
};
$.fn.fnCharsLeftPlgn = function (genStngs) {
return $(this).data("charsleft", new fnCharsLeft(this, genStngs));
};
})(window.jQuery);
$('div span:nth-child(1) textarea').fnCharsLeftPlgn({maxChars: 500});
$('div span:nth-child(2) textarea').fnCharsLeftPlgn({maxChars: 100});
小提琴: http : //jsfiddle.net/5UQ4D/&http : //jsfiddle.net/5UQ4D/1/
要求是,插件應顯示可以在文本區域中添加的字符數。 如果頁面中只有一個文本區域,則效果很好。 但是,如果有多個,則只有與插件最后關聯的文本區域可以正常工作。
關於此處的代碼,在初始化期間,兩個文本區域中剩余的字符數都已正確更新(僅第一次)。 但是稍后,當更改文本區域的內容時,只有第二個100個字符(或與插件關聯的最新文本區域)可以正常工作。
似乎,我無法將插件上下文單獨限制為一個文本區域。 請指教,..
問題一:
正如在評論中提到的,你要創建一個命名的變量tisCharsLeftCntxt
其他環境之外,然后分配this
在你的構造吧。 每次運行插件時,您tisCharsLeftCntxt
使用新的this
在tisCharsLeftCntxt
上tisCharsLeftCntxt
。
沒有理由以您所使用的批發方式this
進行引用。 您的代碼中只有一個地方范圍發生變化, this
不再是您的實例。 該位置在keyup
事件處理功能的內部。 你應該你的別名本地化this
只是其中包含事件處理程序的方法。
問題2:
我相信問題的另一部分(如果您對匹配多個元素的選擇器運行該插件,將會看到此問題)在插件函數內部(該函數$.fn
)。
$.fn.fnCharsLeftPlgn = function (genStngs) {
return $(this).data("charsleft", new fnCharsLeft(this, genStngs));
};
它應該是:
$.fn.fnCharsLeftPlgn = function (genStngs) {
return this.each(function () {
$(this).data("charsleft", new fnCharsLeft(this, genStngs));
});
};
當直接在已添加到jQuery原型( $.fn
)中的方法內部時, this
指的是當前集合的整體,而不是元素。 一個插件應each
本身以針對其各個成員運行元件的特定邏輯。
如果不使用.each()
您所呼叫.data()
對整個集合,其所有的設置charsleft
數據屬性的一個實例fnCharsLeft
。 通過使用.each()
您可以為fnCharsLeft
中的每個元素創建.each()
的新實例。
由於.each()
然后返回集合,並且插件應該是可鏈接的,因此您只需返回它。
一條經驗法則是,如果你傳遞this
到jQuery的工廠( $()
直接在插件內,函數,那么你所做的是錯的,因為它已經集合。 作為第二個經驗法則,除旨在返回有關元素的信息(例如,在未提供參數的情況下, .val()
.html()
或.text()
那些插件定義之外),幾乎所有插件定義都應以return this.each(function() {...
開頭return this.each(function() {...
解決方案:
將這些更改匯總在一起將產生以下錯誤: http : //jsfiddle.net/5UQ4D/4/
這段代碼:
(function ($) {
var fnCharsLeft = function (ele, genStngs) {
this.jqe = $(ele);
this.maxChars = genStngs.maxChars;
this.fnInit();
};
fnCharsLeft.prototype = {
fnInit: function () {
var instance = this;
this.fnUpdateRemainingChars();
this.jqe.on('keyup', function (e) {
key = e.keyCode ? e.keyCode : e.which;
if (37 != key && 38 != key && 39 != key && 40 != key) {
instance.fnUpdateRemainingChars();
}
});
},
fnUpdateRemainingChars: function () {
var charsLft = this.maxChars - this.jqe.val().length,
jqeDestToUpdt = this.jqe.siblings('.cl');
charsLft = charsLft < 0 ? 0 : charsLft;
if (charsLft) {
jqeDestToUpdt.text(charsLft + ' more of ' + this.maxChars + ' characters');
} else {
this.jqe
.val(this.jqe.val().substring(0, this.maxChars))
.scrollTop(this.jqe[0].scrollHeight);
jqeDestToUpdt.text("Maximum limit of " + this.maxChars + " characters reached");
return false;
}
}
};
$.fn.fnCharsLeftPlgn = function (genStngs) {
return this.each(function () {
$(this).data('charsleft', new fnCharsLeft(this, genStngs));
});
};
}(window.jQuery));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.