Jquery 如何从elements attached plugin data方法中获取附加的元素?

Jquery 如何从elements attached plugin data方法中获取附加的元素?,jquery,jquery-plugins,Jquery,Jquery Plugins,我正在编写一个jquery插件,我一直在试图弄清楚如何获取当前方法执行所调用的元素 这是我所做工作的基本版本 我有一些表单输入: <input class="myInput" id="txtInput1" type="text" /> <input class="myInput" id="txtInput2" type="text" /> <input class="myInput" id="txtInput3" type="text" /> (functi

我正在编写一个jquery插件,我一直在试图弄清楚如何获取当前方法执行所调用的元素

这是我所做工作的基本版本

我有一些表单输入:

<input class="myInput" id="txtInput1" type="text" />
<input class="myInput" id="txtInput2" type="text" />
<input class="myInput" id="txtInput3" type="text" />
(function($) {
    $.fn.myplugin=function(options) {
        options=$.extend({
            opt1: 'val1',
            etc: ''
        }, options);

        function example() {
            // 'this' in here is the data-myplugin value of the element that called this method.

            // ---------------------------------------------------------
            //
            // How do I determine which element is calling this method ?
            //
            // eg: in this example how do I know it is the $('#input2') element ?  
            //
            // ---------------------------------------------------------
        }

        this.each(function() {            

            // in this example -- loops through each of the form input elements
            // .. manipulate the DOM

        }).data('myplugin', { 
            // .. adds data-myplugin to each of the form elements in the loop with a value that is our plugin object which contains our example() method and options
            example: example,            
            options: options
        });

        return this;
    }
})(jQuery);
$('.myInput').myplugin();
$('#input2').data('myplugin').example();
// I don't want to have to do this if I don't have to:
$('#input2').data('myplugin').example('input2');
我像这样实例化插件:

<input class="myInput" id="txtInput1" type="text" />
<input class="myInput" id="txtInput2" type="text" />
<input class="myInput" id="txtInput3" type="text" />
(function($) {
    $.fn.myplugin=function(options) {
        options=$.extend({
            opt1: 'val1',
            etc: ''
        }, options);

        function example() {
            // 'this' in here is the data-myplugin value of the element that called this method.

            // ---------------------------------------------------------
            //
            // How do I determine which element is calling this method ?
            //
            // eg: in this example how do I know it is the $('#input2') element ?  
            //
            // ---------------------------------------------------------
        }

        this.each(function() {            

            // in this example -- loops through each of the form input elements
            // .. manipulate the DOM

        }).data('myplugin', { 
            // .. adds data-myplugin to each of the form elements in the loop with a value that is our plugin object which contains our example() method and options
            example: example,            
            options: options
        });

        return this;
    }
})(jQuery);
$('.myInput').myplugin();
$('#input2').data('myplugin').example();
// I don't want to have to do this if I don't have to:
$('#input2').data('myplugin').example('input2');
我这样调用example()plugin方法:

<input class="myInput" id="txtInput1" type="text" />
<input class="myInput" id="txtInput2" type="text" />
<input class="myInput" id="txtInput3" type="text" />
(function($) {
    $.fn.myplugin=function(options) {
        options=$.extend({
            opt1: 'val1',
            etc: ''
        }, options);

        function example() {
            // 'this' in here is the data-myplugin value of the element that called this method.

            // ---------------------------------------------------------
            //
            // How do I determine which element is calling this method ?
            //
            // eg: in this example how do I know it is the $('#input2') element ?  
            //
            // ---------------------------------------------------------
        }

        this.each(function() {            

            // in this example -- loops through each of the form input elements
            // .. manipulate the DOM

        }).data('myplugin', { 
            // .. adds data-myplugin to each of the form elements in the loop with a value that is our plugin object which contains our example() method and options
            example: example,            
            options: options
        });

        return this;
    }
})(jQuery);
$('.myInput').myplugin();
$('#input2').data('myplugin').example();
// I don't want to have to do this if I don't have to:
$('#input2').data('myplugin').example('input2');
我试图避免将其作为参数传入,例如:

<input class="myInput" id="txtInput1" type="text" />
<input class="myInput" id="txtInput2" type="text" />
<input class="myInput" id="txtInput3" type="text" />
(function($) {
    $.fn.myplugin=function(options) {
        options=$.extend({
            opt1: 'val1',
            etc: ''
        }, options);

        function example() {
            // 'this' in here is the data-myplugin value of the element that called this method.

            // ---------------------------------------------------------
            //
            // How do I determine which element is calling this method ?
            //
            // eg: in this example how do I know it is the $('#input2') element ?  
            //
            // ---------------------------------------------------------
        }

        this.each(function() {            

            // in this example -- loops through each of the form input elements
            // .. manipulate the DOM

        }).data('myplugin', { 
            // .. adds data-myplugin to each of the form elements in the loop with a value that is our plugin object which contains our example() method and options
            example: example,            
            options: options
        });

        return this;
    }
})(jQuery);
$('.myInput').myplugin();
$('#input2').data('myplugin').example();
// I don't want to have to do this if I don't have to:
$('#input2').data('myplugin').example('input2');

不幸的是,由于jQuery基于集合的特性,这种设计存在很大的问题,这恰恰导致了您所遇到的问题(这也是为什么您没有看到它被大量使用的原因)。考虑这一点:

<div id="first"  class="a c"></div>
<div id="second" class="b c"></div>
作者显然打算在匹配
.c
的所有元素上使用
示例
函数,但
数据
函数将仅返回这些元素中第一个元素的数据对象,并使用
选项1进行初始化(jQuery的访问器通常是这样工作的:在集合中的所有元素上设置集合,仅从集合中的第一个元素获取GET)。在创建数据对象时,无法解决这一问题

相反,插件应该假设它将被各种不同的集合调用,并在每种情况下处理该集合中每个元素的特定信息

要做到这一点,请遵循公认的模式,使插件同时起到初始化器(接受带有选项的对象)和方法分派(接受带有命令名的字符串)的作用:

现在,在
myplugin
中,您可以愉快地循环使用
“.c”
设置并使用存储在其中每个元素上的选项,这些选项会有所不同(一些是
选项:1
,另一些是
选项:2

下面是一个完成上述操作的简单但完整的示例(请参见注释):

(函数($){
//我们的方法图
var methods=Object.create(null);
//默认选项
var defaultOptions={
颜色:“红色”,
字体大小:“16px”
};
//方法
methods.color=函数颜色(set,args){
//使用特定于每个元素的选项在元素上循环
//返回要链接的集合
返回集。每个(函数(){
var info=methodEntry(本);
info.$element.css(“color”,info.options.color);
});
};
methods.fontSize=函数fontSize(集合,参数){
返回集。每个(函数(){
var info=methodEntry(本);
info.$element.css(“字体大小”,info.options.fontSize);
});
};
methods.getColor=函数getColor(set,args){
//getter仅访问第一个元素。。。
var info=methodEntry(集合[0]);
//…并返回集合以外的内容
返回info.options.color;
}
//初始化
函数init(set,args){
返回set.data(“myplugin”,$.extend({},defaultOptions,args[0]);
}
//管道
函数方法条目(元素){
变量$element=$(element);
var options=$element.data(“myplugin”);
如果(!选项){
抛出新错误(“未为元素初始化myplugin”);
}
返回{$element:$element,options:options};
}
//插件函数
$.fn.myplugin=函数(方法名){
var isMethodCall=typeof methodName==“string”;
var args=Array.prototype.slice.call(参数,isMethodCall?1:0);
var method=isMethodCall?方法[methodName]:init;
if(!方法){
抛出新错误(“myplugin没有名为“'+arg+””的方法”);
}
返回方法(this,args);
};
})(jQuery);
//使用它
$(“.a”).myplugin({color:“green”});
$(“.b”).myplugin({color:“blue”,fontSize:“20px”});
$(“.c”).myplugin(“color”).myplugin(“fontSize”);//注释链接很有效
console.log($(“.c”).myplugin(“getColor”);/“绿色”,因为*first*元素的设置是绿色的
首先
第二

“将数据myplugin添加到每个表单元素…”不,它没有。它附加到jQuery为元素维护的内部数据缓存,该缓存不是
data-*
属性。@t.J.Crowder-美元('x').data('something')=“stuff”重要吗如果你用jquery访问两者的方式都是一样的?但是我们离题了。当人们认为它设置了
数据-*
属性(很多人都这么做了),然后想知道为什么当他们与使用
数据-*
属性(而不是
数据
)的引导程序交互时,它不起作用。谢谢。互联网的问题是,你可以找到很多资源,每个资源都说它们是要使用的标准样板,就像我正在使用的模板一样。我将切换到你提供的示例。@Drew-True,我看到了几个“标准jQuery插件”模板,它们……嗯……不理想。:-)(还有一些基本上是上面提到的,这可能是我学到的。)使用上面的代码片段,在方法中,info.$element始终是一个索引对象,因此我必须使用info.$element[0].css('etc');以便示例工作。@Drew-是的,它始终是一个jQuery对象(set)。这只是为了方便起见(使用jQuery方法),集合中总是只有一个元素。不,
info.$element[0]。css('etc')
不是必需的,事实上也不起作用:DOM元素没有
css
函数。jQuery对象有。您只需像上面的实例那样使用
info.$element.css('etc')