如何从元素附加插件数据方法中获取附加元素?
How do I get the attached element from the elements attached plugin data method?
我正在编写一个 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();
我这样调用 example() 插件方法:
$('#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>
然后是代码:
$(".a").myplugin({option: 1});
$(".b").myplugin({option: 2});
$(".c").data("myplugin").example();
作者显然打算在所有匹配 .c
的元素上使用您的 example
函数,但是 data
函数只会 return 您的数据对象 第一个 个元素,用 option: 1
初始化(这就是 jQuery 访问器的一般工作方式:在集合中的所有元素上设置集合,获取只获取从集合中的第一个元素开始)。创建数据对象时,您无能为力。
相反,插件应该假设它会被各种不同的集合调用,并在每种情况下处理该集合中每个元素的特定信息。
要做到这一点,请遵循既定的模式使您的插件函数既是初始化程序(接受带有选项的对象)又是方法分派(接受带有命令名称):
$(".a").myplugin({option: 1});
$(".b").myplugin({option: 2});
$(".c").myplugin("example");
现在,在 myplugin
中,您可以愉快地遍历 ".c"
集并使用存储在其中每个元素上的选项,这些选项会有所不同(有些会是 option: 1
,其他人将是 option: 2
).
这是执行上述操作的一个简单但完整的示例(请参阅评论):
(function($) {
// A map of our methods
var methods = Object.create(null);
// Default options
var defaultOptions = {
color: "red",
fontSize: "16px"
};
// Methods
methods.color = function color(set, args) {
// Loop over the elements, using the options specific to each element
// Return the set for chaining
return set.each(function() {
var info = methodEntry(this);
info.$element.css("color", info.options.color);
});
};
methods.fontSize = function fontSize(set, args) {
return set.each(function() {
var info = methodEntry(this);
info.$element.css("font-size", info.options.fontSize);
});
};
methods.getColor = function getColor(set, args) {
// Getters only access the first element...
var info = methodEntry(set[0]);
// ...and return something other than the set
return info.options.color;
}
// init
function init(set, args) {
return set.data("myplugin", $.extend({}, defaultOptions, args[0]));
}
// plumbing
function methodEntry(element) {
var $element = $(element);
var options = $element.data("myplugin");
if (!options) {
throw new Error("myplugin not initialized for element");
}
return {$element: $element, options: options};
}
// Plugin function
$.fn.myplugin = function(methodName) {
var isMethodCall = typeof methodName === "string";
var args = Array.prototype.slice.call(arguments, isMethodCall ? 1 : 0);
var method = isMethodCall ? methods[methodName] : init;
if (!method) {
throw new Error("myplugin has no method called '" + arg + "'");
}
return method(this, args);
};
})(jQuery);
// Using it
$(".a").myplugin({color: "green"});
$(".b").myplugin({color: "blue", fontSize: "20px"});
$(".c").myplugin("color").myplugin("fontSize"); // Note chainging works
console.log($(".c").myplugin("getColor")); // "green" because the *first* element's setting is green
<div id="first" class="a c">first</div>
<div id="second" class="b c">second</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
或者,您可以使用 myplugin()
本身代替您的 data("myplugin")
:
来做同样的事情
$(".a").myplugin({option: 1});
$(".b").myplugin({option: 2});
$(".c").myplugin().example();
您可以 myplugin
通过 return 使用您的方法和对集合的引用来响应没有选项的调用:
return {
elements: this,
example: ...
}
然后,这些方法将使用 this.elements
来获取要执行的元素。我不会做一个完整的例子,但如果你喜欢那种语法,改编它是相当简单的。
我正在编写一个 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();
我这样调用 example() 插件方法:
$('#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>
然后是代码:
$(".a").myplugin({option: 1});
$(".b").myplugin({option: 2});
$(".c").data("myplugin").example();
作者显然打算在所有匹配 .c
的元素上使用您的 example
函数,但是 data
函数只会 return 您的数据对象 第一个 个元素,用 option: 1
初始化(这就是 jQuery 访问器的一般工作方式:在集合中的所有元素上设置集合,获取只获取从集合中的第一个元素开始)。创建数据对象时,您无能为力。
相反,插件应该假设它会被各种不同的集合调用,并在每种情况下处理该集合中每个元素的特定信息。
要做到这一点,请遵循既定的模式使您的插件函数既是初始化程序(接受带有选项的对象)又是方法分派(接受带有命令名称):
$(".a").myplugin({option: 1});
$(".b").myplugin({option: 2});
$(".c").myplugin("example");
现在,在 myplugin
中,您可以愉快地遍历 ".c"
集并使用存储在其中每个元素上的选项,这些选项会有所不同(有些会是 option: 1
,其他人将是 option: 2
).
这是执行上述操作的一个简单但完整的示例(请参阅评论):
(function($) {
// A map of our methods
var methods = Object.create(null);
// Default options
var defaultOptions = {
color: "red",
fontSize: "16px"
};
// Methods
methods.color = function color(set, args) {
// Loop over the elements, using the options specific to each element
// Return the set for chaining
return set.each(function() {
var info = methodEntry(this);
info.$element.css("color", info.options.color);
});
};
methods.fontSize = function fontSize(set, args) {
return set.each(function() {
var info = methodEntry(this);
info.$element.css("font-size", info.options.fontSize);
});
};
methods.getColor = function getColor(set, args) {
// Getters only access the first element...
var info = methodEntry(set[0]);
// ...and return something other than the set
return info.options.color;
}
// init
function init(set, args) {
return set.data("myplugin", $.extend({}, defaultOptions, args[0]));
}
// plumbing
function methodEntry(element) {
var $element = $(element);
var options = $element.data("myplugin");
if (!options) {
throw new Error("myplugin not initialized for element");
}
return {$element: $element, options: options};
}
// Plugin function
$.fn.myplugin = function(methodName) {
var isMethodCall = typeof methodName === "string";
var args = Array.prototype.slice.call(arguments, isMethodCall ? 1 : 0);
var method = isMethodCall ? methods[methodName] : init;
if (!method) {
throw new Error("myplugin has no method called '" + arg + "'");
}
return method(this, args);
};
})(jQuery);
// Using it
$(".a").myplugin({color: "green"});
$(".b").myplugin({color: "blue", fontSize: "20px"});
$(".c").myplugin("color").myplugin("fontSize"); // Note chainging works
console.log($(".c").myplugin("getColor")); // "green" because the *first* element's setting is green
<div id="first" class="a c">first</div>
<div id="second" class="b c">second</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
或者,您可以使用 myplugin()
本身代替您的 data("myplugin")
:
$(".a").myplugin({option: 1});
$(".b").myplugin({option: 2});
$(".c").myplugin().example();
您可以 myplugin
通过 return 使用您的方法和对集合的引用来响应没有选项的调用:
return {
elements: this,
example: ...
}
然后,这些方法将使用 this.elements
来获取要执行的元素。我不会做一个完整的例子,但如果你喜欢那种语法,改编它是相当简单的。