Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/70.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插件,多个实例同一页面;应用于元素类和唯一元素ID;使用$.data保护选项;公共访问功能_Javascript_Jquery_Jquery Plugins_Boilerplate - Fatal编程技术网

Javascript JQuery插件,多个实例同一页面;应用于元素类和唯一元素ID;使用$.data保护选项;公共访问功能

Javascript JQuery插件,多个实例同一页面;应用于元素类和唯一元素ID;使用$.data保护选项;公共访问功能,javascript,jquery,jquery-plugins,boilerplate,Javascript,Jquery,Jquery Plugins,Boilerplate,我这是第一次编写JQuery插件——几乎就在那里——并试图找到最好的“样板文件”来满足以下需求 这是我的问题: 我不能让插件通过它们的类名来处理元素 这是有效的: var myPlugin = $('#single').myPlugin(); // Yes - it gets initialised myPlugin.doAFunction(" Some Params "); // Yes - public access func works 此无效: var myPluginFo

我这是第一次编写JQuery插件——几乎就在那里——并试图找到最好的“样板文件”来满足以下需求

这是我的问题:


我不能让插件通过它们的类名来处理元素

这是有效的:

var myPlugin = $('#single').myPlugin();   // Yes - it gets initialised
myPlugin.doAFunction(" Some Params ");    // Yes - public access func works
无效:

var myPluginFooClass = $('.foo').myPlugin(); // Yes, it gets initialised
myPlugin.doAFunction(" Some Params ");       // NO - now this falls over
以下是我需要实现的目标:

  • 同一页上有多个实例
  • 每个实例都有自己的变量,部署时不会被其他实例覆盖(我使用的是$.data)
  • 公共访问功能只影响该实例,而不影响其他实例
  • 实例可以通过其id(#myElement)部署到单个元素上
  • 实例可以按类(.foo)部署到元素上-这是不起作用的
这是我的JQUERY代码:

(function($){

$.fn.myPlugin = function(options) {
    // support multiple elements
    if (this.length > 1){
        this.each(function() { $(this).myPlugin(options) });
        return this;
    }

    // -- private variables --
    var $this = $(this);

    // default settings
    var defaults = { 
            initialText: 'I have been initialized'
        };
    // Merge defaults with setup options
    var options = $.extend({}, defaults, options);

    // Protect final options, placing inside jQuery element data 
    $this.data('myPlugSettings', options);

    // Shortcut var to access option data
    var settings = $this.data('myPlugSettings');

    // private methods
    var fooPrivate = function() {
        // do something private ...
    };

    // public methods        
    this.changeText = function(param) {
        $this.text(param);
    };

    // Constructor
    this.init = function() {
        $this.text( settings.initialText );
        // Return this for chainability?
        return this;
    };

    return this.init();
}
})(jQuery);



// globals

_ = {
    myPlugin: null,
    myPluginTwo: null,
    myPluginFoo: null
}


// Button Event handlers

$("#btnLoadPlugs").click(function(e) {
    _.myPlugin = $('#single').myPlugin({
        initialText: "Custom initial text" 
    });
    _.myPluginTwo = $('#anotherSingle').myPlugin();
    _.myPluginFoo  = $('.foo').myPlugin();
});

$("#btnGoSingle").click(function(e) {
    _.myPlugin.changeText(" Worked on single ID ");
});

$("#btnGoAnotherSingle").click(function(e) {
    _.myPluginTwo.changeText(" Worked again here ");
});

$("#btnGoFoo").click(function(e) {
    // THIS FALLS OVER ???????????
    _.myPluginFoo.changeText(" foos get this ");
});
这里的问题很容易理解。

TLDR

\uuu0.mypluginfo
使用
changeText
方法释放对jQuery对象的引用

// support multiple elements
if (this.length > 1){
    this.each(function() { $(this).myPlugin(options) });

    // Send the collection back.
    return this;
}
只是为了让它发挥作用

// This will work, but this is not exactly what you have intended.
_.myPluginFoo.each(function(key, value) {
    $(value).myPlugin().changeText('Hello');
});
为什么?

这是Sizzle选择器引擎的预期行为,
$(“#unique”)
调用将返回带有单个HtmleElement的jQuery集合实例,可由
$(“#unique”)[0]
访问

通过在
$.fn.myPlugin
中将
$('#unique')
修改为
this
,您将获得一个带有
changeThext
属性的结果对象

this.length>1//true

通过调试以下代码,您将很容易注意到差异:

$("#btnLoadPlugs").click(function(e) {
    // ...

    console.log(_.myPluginTwo); // Single object.
    console.log(_.myPluginFoo); // A collection, without changeText method.
});
$。您正在使用的数据保护不是很有效

更好的方法

如果有意义的话,您还可以实现类似于
$('.foo').myPlugin('changeText','newtext')
的东西


看一看,这是jQuery插件最好的地方之一。

您返回
这个
而没有其他东西运行
if(this.length>1){this.each(function(){$(this.myPlugin(options)});返回this;}
Yea!!!所以我们从上面删除
并返回此
,它将按预期工作!唯一的障碍是在这种情况下它会破坏链式能力,对吧-但是。。。我猜你不能既有蛋糕又吃!谢谢你,谢谢你。回答得真不错。上面链接的JQuery样板文件也提供了一些很好的解决方案。