我正在尝试开发我的第一个jQuery插件。基本上它将类附加到站点上的各种元素,然后在用户滚动时更改它(我正在计算偏移量等等)。而且我觉得我已经用这个打了一堵墙。
以下是我启动插件的方法:
$("div").myPlugin();
来源:
$.fn.myPlugin = function() {
return this.each(function() {
$(this).addClass("something-" + i);
i++;
});
};
有人可以解释一下如何在我的插件中使用$(window).scroll吗?
因为一旦它进入“return this.each”,它就会被连接多次在这个循环中的元素......
$.fn.myPlugin = function() {
return this.each(function() {
$(this).addClass("something-" + i);
i++;
$(window).scroll( function() { <!-- here it not only attaches itself x-times but i is always the same -->
...
$(".something-" + i).addClass("active");
...
});
});
};
在返回后放置它不会做任何事情:
$.fn.myPlugin = function() {
return this.each(function() {
$(this).addClass("something-" + i);
i++;
});
$(window).scroll( function() { <!-- doesn't seem to work -->
...
$(".something-" + i).addClass("active");
...
});
};
在没有“我”之前,我也不知道我是否可以在函数内部放置“返回”范围之外的东西(对我来说似乎没有用?):
$.fn.myPlugin = function() {
$(window).scroll( function() { <!-- there is no "i" yet -->
...
$(".something-" + i).addClass("active");
...
});
return this.each(function() {
$(this).addClass("something-" + i);
i++;
});
};
我是jQuery的新手,我不确定我是否正确理解文档,我想知道最好不要在这里使用return吗?请注意,此插件可以使用1个元素,但通常会有更多的div而不是1。
非常感谢。
答案 0 :(得分:1)
这个怎么样:
(function($, window, undefined){
$.fn.myPlugin = function() {
// bind the scroll event listener once
$(window).scroll(function(){
console.log('scroll');
});
// iterate your plugin elements
// use index passed by the .each callback:
this.each(function(i, el){
$(el).addClass('something-' + i);
});
// return your jQuery object to allow chaining on your plugin
// note that (this instanceof jQuery) === true, so there is no need
// to pass it to the jQuery function i.e. $(this)
return this;
};
})(jQuery, window);
$('div').myPlugin();
console.log($('div').map(function(){ return this.className; }).get());
答案 1 :(得分:0)
可能有几种方法可以编写插件。以下是最合适的特征:
this
- 不需要.each()
(至少,不要公开)。请注意,这些特性在编码时将采用非常非典型的插件模式。因此,这可能不是您的第一个插件选择的最佳问题。
然而,这里......
(function($, window, undefined) {
// Private vars
var pluginName = 'myPlugin',
jqCollection = $(),
events = {
scroll: 'scroll.' + pluginName
},
className = pluginName + 'active',
timeout;
// Private functions
function scroll() {
if(jqCollection.closest('body').length === 0) {
//This is advisable in case some other javascript/DOM activity has removed all elements in jqCollection.
// Thanks to selected answer at :
// http://stackoverflow.com/questions/4040715/check-if-cached-jquery-object-is-still-in-dom
jqCollection = $();
$(window).off(events.scroll);
} else {
jqCollection.addClass(className);
clearTimeout(timeout);
timeout = setTimeout(function() {
jqCollection.removeClass(className);
}, 100);
}
}
// Public methods
methods = {
add: function(jq) {
jqCollection = jqCollection.add(jq);
if(jqCollection.length > 0) {
$(window).off(events.scroll).on(events.scroll, scroll)
}
},
remove: function(jq) {
jqCollection = jqCollection.not(jq);
if(jqCollection.length === 0) {
$(window).off(events.scroll);
}
}
};
// The actual plugin
$.fn[pluginName] = function(method) {
method = method || 'add';
if(methods[method]) {
methods[method](this);
} else {
console.log('jQuery plugin ' + pluginName + 'has no method: ' + method);
};
return this;
};
})(jQuery, window);
按如下方式关联所选元素:
$(selector).myPlugin();
//or
$(selector).myPlugin('add');
如下所示取消选定的元素:
$(selector).myPlugin('remove');
<强> DEMO 强>
请注意,我已将类名更改为pluginName + 'active'
,以使其更少被其他代码使用。
正如我所说,这是一种方法。也许你可以完全考虑改进或其他方式。