Там фундаментальный вопрос здесь: Вы думаете об отдельном элементе. jQuery - все о наборах элементов. в вашем плагине - это экземпляр jQuery, который может содержать 0..n
элементов. Может быть ноль, один, 27, 342 и т. Д. Таким образом, this[0].id
на самом деле не имеет смысла в подключаемом модуле jQuery, потому что вы просто получите id
первого совпадающего элемента (если он даже имеет один, нет требование, которое оно должно), или ошибка (как вы обнаружили), когда вообще нет элементов в наборе.
Итак, если вы начинаете думать о своем подключаемом модуле, имея в виду набор совпадающих элементов, которые могут быть пустым набором, небольшим набором или большим набором, вы будете на правильном пути.
Вот конкретный пример: давайте напишем плагин, который делает глупую вещь: он превращает элемент (ы) в цвет, а затем возвращает их к исходному цвету после таймаута. Мы будем использовать его как это:
$("selector").plugin("newcolor", timeout)
Если мы думаем в терминах отдельных элементов, наш плагин не будет работать правильно:
// The "foo" plug-in thinks in terms of just one element
$.fn.foo = function(color, time) {
var self, oldColor;
self = this;
// Save the current color -- this is wrong
oldColor = self.css("color");
// Set new color
self.css("color", color);
// Restore old color after timeout
setTimeout(function() {
self.css("color", oldColor);
}, time);
};
Теперь давайте использовать его:
$("#theButton").click(function() {
$(".foo").foo("blue", 1000);
});
... с этим HTML:
<div class="foo">This is the first "foo" div</div>
<div class="foo" style="color: green">This is the second "foo" div</div>
<div class="foo" style="color: red">This is the third "foo" div</div>
<div><input type="button" id="theButton" value="Use foo"></div>
Проблема заключается в том, что, думая в терминах одного элемента, плагин неправильно сохраняет цвет только первого элемента; когда он переходит к «восстановлению» исходного цвета, он применяет цвет первого элемента ко всем остальным, что неверно. В итоге мы получаем три div с черным текстом, где два вторых не должны быть черными.Live example | Source
Вместо этого, если мы думаем, что в терминах множеств, мы будем делать это так (например, не говоря, что это самый красивый код на планете):
// The "bar" plug-in understands sets
$.fn.bar = function(color, time) {
var self;
self = this;
// Get the current color of each element
self.each(function() {
var entry = $(this);
entry.data("oldColor", entry.css("color"));
});
// Set new color
self.css("color", color);
// Restore old color after timeout
setTimeout(function() {
self.each(function() {
var entry = $(this);
entry.css("color", entry.data("oldColor")).removeData("oldColor");
});
}, time);
};
Мы будем использовать его как это (в основном то же самое):
$("#theButton").click(function() {
$(".bar").bar("blue", 1000);
});
... с этим HTML (в основном то же самое):
<div class="bar">This is the first "bar" div</div>
<div class="bar" style="color: green">This is the second "bar" div</div>
<div class="bar" style="color: red">This is the third "bar" div</div>
<div><input type="button" id="theButton" value="Use foo"></div>
Обратите внимание, как это экономит каждый цвет, а также на самом элементе через data
. При восстановлении восстанавливается цвет каждого элемента. Live example | Source
Действительно ли вы хотите 'id', или вы хотите, чтобы вся строка селектора? Что делать, если плагин был применен к набору элементов, у которых не было 'id'? –