Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 带有原型的Jquery插件_Javascript_Jquery - Fatal编程技术网

Javascript 带有原型的Jquery插件

Javascript 带有原型的Jquery插件,javascript,jquery,Javascript,Jquery,我尝试了Jquery插件的基础知识和原型概念,但最终出现了一个不寻常的行为 HTML: <div> <span> <textarea>Text Area with 500 characters. Adding Some text.</textarea> <span class="cl"></span> </span> <span>

我尝试了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>

包含500个字符的文本区域。添加一些文本。
包含100个字符的文本区域
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});
(函数($){
var tisCharsLeftCntxt=null;
功能fnCharsLeft(电气、发电机){
this.jqe=$(ele);
this.maxChars=genStngs.maxChars;
tisCharsLeftCntxt=此;
this.fnInit();
}
fnCharsLeft.prototype={
fnInit:函数(){
tisCharsLeftCntxt.fupdateremainingchars();
tisCharsLeftCntxt.jqe.keyup(函数(事件){
key=event.keyCode?event.keyCode:event.which;
如果((37!=键)&&(38!=键)&&(39!=键)&(40!=键)){
tisCharsLeftCntxt.fupdateremainingchars();
}
});
},
fnUpdateMainingChars:函数(){
var charsLft=tisCharsLeftCntxt.maxChars-tisCharsLeftCntxt.jqe.val().length,
jqeDestToUpdt=tisCharsLeftCntxt.jqe.sillides('.cl');
charsLft=(charsLft<0)?0:charsLft;
if(charsLft){
jqeDestToUpdt.text(charsLft+'more of'+tisCharsLeftCntxt.maxChars+'characters');
}否则{
tisCharsLeftCntxt.jqe.val(tisCharsLeftCntxt.jqe.val()
.substring(0,tisCharsLeftCntxt.maxChars));
tisCharsLeftCntxt.jqe.scrollTop(tisCharsLeftCntxt.jqe[0].scrollHeight);
jqeDestToUpdt.text(“已达到“+tisCharsLeftCntxt.maxChars+”字符的最大限制”);
返回false;
}
}
};
$.fn.fnCharsLeftPlgn=函数(genStngs){
返回$(this).data(“charsleft”,新的fnCharsLeft(this,genStngs));
};
})(window.jQuery);
$('div span:nth child(1)textarea').fnCharsLeftPlgn({maxChars:500});
$('div span:nth child(2)textarea').fnCharsLeftPlgn({maxChars:100});
小提琴: &

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

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


看起来,我无法将插件上下文单独限制为文本区域。请注意,…

问题1:

如注释中所述,您正在其他上下文之外创建一个名为
tisCharsLeftCntxt
的变量,然后在构造函数中将
this
赋值给它。每次运行插件时,您都会用一个新的
this
踩下
tisCharsLeftCntxt

没有理由以您所拥有的批发方式引用此。代码中只有一个地方的作用域发生了更改,
不再是您的实例。该位置位于
keyup
事件处理功能的内部。您应该将
this
的别名本地化为仅包含该事件处理程序的方法

问题2:

我相信您的问题的另一部分(如果您针对匹配多个元素的选择器运行插件,就会看到这一点)在插件函数内部(依赖于
$.fn

应该是:

$.fn.fnCharsLeftPlgn = function (genStngs) {
    return this.each(function () {
        $(this).data("charsleft", new fnCharsLeft(this, genStngs));
    });
};
当直接在已添加到jQuery原型(
$.fn
)的方法内部时,
指的是当前集合的整体,而不是元素。插件应该
每个
自身,以便针对其单个成员运行特定于元素的逻辑

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

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

经验法则是,如果您将
这个
直接传递到插件内部的jQuery工厂(
$()
),那么您就做错了,因为它已经是集合。第二条经验法则是,除了那些用于返回元素信息的插件定义(如
.val()
.html()
,或
.text()
,如果没有指定参数),几乎所有插件定义都应该以
开头。每个(函数(){…

解决方案:

将这些变化结合在一起会产生以下结果:

该代码:

(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));
(函数($){
var fnCharsLeft=功能(元件、发电机){
this.jqe=$(ele);
this.maxChars=genStngs.maxChars;
this.fnInit();
};
fnCharsLeft.prototype={
fnInit:函数(){
var实例=这个;
此.fnUpdateMainingChars();
this.jqe.on('keyup',函数(e){
key=e.keyCode?e.keyCode:e.which;
如果(37!=键和38!=键和39!=键和40!=键){
.fnUpdateMainingChars()实例;
}
});
},
fnUpdateMainingChars:函数(){
var charsLft=this.maxChars-this.jqe.val().length,
jqeDestToUpdt=this.jqe.sillides('.cl');
查尔斯夫特
(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));