带有原型的jQuery插件

我尝试使用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

没有理由以您所使用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()then会返回该集合,并且插件应该是可链接的,因此您只需返回它即可。

一条经验法则是,如果要直接在插件内部传递thisjQuery工厂($())函数,那么您做错了什么,因为它已经是集合。根据经验,第二个规则,其目的除了那些几乎所有的插件定义返回有关元素的信息(如.val().html().text()没有给予PARAM时)应与启动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));

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

带有原型的jQuery插件

来自分类Dev

带有Scala的jQuery插件

来自分类Dev

带有jQuery验证插件的新reCaptcha

来自分类Dev

带有jQuery Validate插件的jQuery UI Tooltip

来自分类Dev

带有jQuery插件的jQuery对象文字或模块模式

来自分类Dev

jQuery插件开发:原型回调参数

来自分类Dev

带有插件的Jsoup

来自分类Dev

带有插件的Jsoup

来自分类Dev

带有scrollTo插件的jQuery DataTables自动参见div

来自分类Dev

带有多个选择框的jQuery Validate插件

来自分类Dev

带有两个提交按钮的jQuery Validation插件?

来自分类Dev

带有Webpack和Typescript的JQuery插件(数据表)

来自分类Dev

带有旋转插件的jQuery Flo隐藏X轴标签

来自分类Dev

使用带有Slick插件的Jquery加载方法

来自分类Dev

使用带有响应的jQuery插件时导入错误

来自分类Dev

带有ajax和jquery noty插件的Rails Flash消息

来自分类Dev

带有多个选择框的jQuery Validate插件

来自分类Dev

带有通配符选择器的jQuery验证插件errorPlacement

来自分类Dev

带有JSON对象的Dynatree树视图jquery插件问题

来自分类Dev

带有AJAX的jQuery Validate插件不会提交

来自分类Dev

带有#导航链接的jQuery插件的AngularJS问题

来自分类Dev

带有Angular指令的jQuery输入掩码插件

来自分类Dev

带有 jquery 插件和 WebEncore 的 Symfony 4

来自分类Dev

未知的联系关系:带有NSCollectionView的原型

来自分类Dev

带有原型单元的tableView.insertRowsAtIndexPaths

来自分类Dev

带有jquery datepicker错误的jquery验证插件(请输入有效日期)

来自分类Dev

如何通过其原型扩展jquery插件的公共方法?

来自分类Dev

将ES6插件扩展到jQuery原型

来自分类Dev

如何通过其原型扩展jquery插件的公共方法?

Related 相关文章

热门标签

归档