gpt4 book ai didi

javascript - 带原型(prototype)的 Jquery 插件

转载 作者:行者123 更新时间:2023-11-28 01:33:29 25 4
gpt4 key购买 nike

我正在尝试 Jquery 插件的基础知识和原型(prototype)概念,但最终出现了不寻常的行为。

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});

fiddle : http://jsfiddle.net/5UQ4D/ & http://jsfiddle.net/5UQ4D/1/

要求是,插件应显示可以在文本区域中添加的字符数。如果页面中只有一个文本区域,则效果很好。但如果有多个,则只有最后与插件关联的文本区域才能正常工作。

关于这里的代码,在初始化期间,两个文本区域中剩余的字符数都被正确更新(仅第一次)。但稍后当文本区域内容发生更改时,只有第二个 100 个字符的文本区域(或与插件关联的最新文本区域)可以正常工作。

看起来,我无法将插件上下文独立限制到文本区域。请指教,..

最佳答案

问题 1:

正如评论中提到的,您将在其他上下文之外创建一个名为 tisCharsLeftCntxt 的变量,然后在构造函数中将 this 分配给它。每次运行插件时,您都会使用新的 this 来踩踏 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 原型(prototype) ($.fn) 的方法内部时,this 指的是当前集合的整体,而不是元素。插件应该each本身,以便针对其各个成员运行元素特定的逻辑。

如果不使用.each(),您将针对整个集合调用.data(),并将其所有charsleft数据属性设置为fnCharsLeft 的一个实例。通过使用 .each(),您可以为集合中的每个元素创建一个 fnCharsLeft 的新实例。

由于 .each() 返回集合,并且插件应该是可链接的,因此您只需返回它即可。

经验法则是,如果您将 this 直接传递到插件、函数内部的 jQuery 工厂 ($()),那么您正在执行的操作出了问题,因为它已经是集合了。作为第二条经验法则,几乎所有插件定义除了那些旨在返回有关元素的信息(例如 .val().html().text() 当没有给定参数时)应以 return this.each(function() {...

开头

解决方案:

将这些更改放在一起会产生这个 fiddle : 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));

关于javascript - 带原型(prototype)的 Jquery 插件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21805722/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com