Javascript 如何以面向对象的方式编写jquery插件
我已经编写了以下jquery插件。我试图做的是,当用户单击一个链接时,根据数据属性使相关的div显示:block base。但是这个插件不起作用。在过去的两天里,我一直在努力解决这个问题。但我失败了 我的HTMLJavascript 如何以面向对象的方式编写jquery插件,javascript,jquery,jquery-plugins,Javascript,Jquery,Jquery Plugins,我已经编写了以下jquery插件。我试图做的是,当用户单击一个链接时,根据数据属性使相关的div显示:block base。但是这个插件不起作用。在过去的两天里,我一直在努力解决这个问题。但我失败了 我的HTML <div class="container1"> <a href="#" class="link1" data-link="a">asd</a> <div class="window1" data-window="a">
<div class="container1">
<a href="#" class="link1" data-link="a">asd</a>
<div class="window1" data-window="a">
asd
</div>
</div>
<hr>
<div class="container2">
<a href="#" class="link2" data-link="b">asdf1</a>
<a href="#" class="link2" data-link="c">asdf2</a>
<a href="#" class="link2" data-link="d">asdf3</a>
<div class="window2" data-window="b">
asdf1
</div>
<div class="window2" data-window="c">
asdf2
</div>
<div class="window2" data-window="d">
asdf3
</div>
</div>
<script src="jquery-1.11.0.min.js"></script>
<script src="script.js"></script>
<script>
$('.container1').myPlugin({
link: $('.link1'),
container : $('.window1')
});
$('.container2').myPlugin({
link: $('.link2'),
container : $('.window2')
});
</script>
CSS
您需要使用
var
来确保您的变量都是局部变量,而不是全局变量
var MyPlugin = {
// ...
};
另外,在init
函数中,您正在执行以下操作:
$.fn.myPlugin.config = $.extend({}, $.fn.myPlugin.config, options);
这将覆盖默认选项$.fn.myPlugin.config
。这意味着所有调用myPlugin()
的元素将使用相同的配置。您只需要在一个实例上设置配置
this.config = $.extend({}, $.fn.myPlugin.config, options);
secondFunc: function (rezG) {
return function(){
var dataLinkId = $(this).data('link'),
container = $(rezG.config.container).filter(function(){
return $(this).data('window') == dataLinkId;
});
container.show();
};
}
您的secondFunc
没有对对象(rezG
)实例的引用,因此无法访问配置。您需要将其传递到secondFunc()
。一种方法是使用闭包捕获实例
this.config = $.extend({}, $.fn.myPlugin.config, options);
secondFunc: function (rezG) {
return function(){
var dataLinkId = $(this).data('link'),
container = $(rezG.config.container).filter(function(){
return $(this).data('window') == dataLinkId;
});
container.show();
};
}
然后你就这样把它绑起来:
link.on('click', this.secondFunc(this));
请注意,在secondFunc
中,您需要使用config.container
(不仅仅是对象config
),而且您的属性是data window
,而不是data section
更新的演示:您需要使用
var
来确保您的变量都是局部变量,而不是全局变量
var MyPlugin = {
// ...
};
另外,在init
函数中,您正在执行以下操作:
$.fn.myPlugin.config = $.extend({}, $.fn.myPlugin.config, options);
这将覆盖默认选项$.fn.myPlugin.config
。这意味着所有调用myPlugin()
的元素将使用相同的配置。您只需要在一个实例上设置配置
this.config = $.extend({}, $.fn.myPlugin.config, options);
secondFunc: function (rezG) {
return function(){
var dataLinkId = $(this).data('link'),
container = $(rezG.config.container).filter(function(){
return $(this).data('window') == dataLinkId;
});
container.show();
};
}
您的secondFunc
没有对对象(rezG
)实例的引用,因此无法访问配置。您需要将其传递到secondFunc()
。一种方法是使用闭包捕获实例
this.config = $.extend({}, $.fn.myPlugin.config, options);
secondFunc: function (rezG) {
return function(){
var dataLinkId = $(this).data('link'),
container = $(rezG.config.container).filter(function(){
return $(this).data('window') == dataLinkId;
});
container.show();
};
}
然后你就这样把它绑起来:
link.on('click', this.secondFunc(this));
请注意,在secondFunc
中,您需要使用config.container
(不仅仅是对象config
),而且您的属性是data window
,而不是data section
更新的演示:您需要使用
var
来确保您的变量都是局部变量,而不是全局变量
var MyPlugin = {
// ...
};
另外,在init
函数中,您正在执行以下操作:
$.fn.myPlugin.config = $.extend({}, $.fn.myPlugin.config, options);
这将覆盖默认选项$.fn.myPlugin.config
。这意味着所有调用myPlugin()
的元素将使用相同的配置。您只需要在一个实例上设置配置
this.config = $.extend({}, $.fn.myPlugin.config, options);
secondFunc: function (rezG) {
return function(){
var dataLinkId = $(this).data('link'),
container = $(rezG.config.container).filter(function(){
return $(this).data('window') == dataLinkId;
});
container.show();
};
}
您的secondFunc
没有对对象(rezG
)实例的引用,因此无法访问配置。您需要将其传递到secondFunc()
。一种方法是使用闭包捕获实例
this.config = $.extend({}, $.fn.myPlugin.config, options);
secondFunc: function (rezG) {
return function(){
var dataLinkId = $(this).data('link'),
container = $(rezG.config.container).filter(function(){
return $(this).data('window') == dataLinkId;
});
container.show();
};
}
然后你就这样把它绑起来:
link.on('click', this.secondFunc(this));
请注意,在secondFunc
中,您需要使用config.container
(不仅仅是对象config
),而且您的属性是data window
,而不是data section
更新的演示:您需要使用
var
来确保您的变量都是局部变量,而不是全局变量
var MyPlugin = {
// ...
};
另外,在init
函数中,您正在执行以下操作:
$.fn.myPlugin.config = $.extend({}, $.fn.myPlugin.config, options);
这将覆盖默认选项$.fn.myPlugin.config
。这意味着所有调用myPlugin()
的元素将使用相同的配置。您只需要在一个实例上设置配置
this.config = $.extend({}, $.fn.myPlugin.config, options);
secondFunc: function (rezG) {
return function(){
var dataLinkId = $(this).data('link'),
container = $(rezG.config.container).filter(function(){
return $(this).data('window') == dataLinkId;
});
container.show();
};
}
您的secondFunc
没有对对象(rezG
)实例的引用,因此无法访问配置。您需要将其传递到secondFunc()
。一种方法是使用闭包捕获实例
this.config = $.extend({}, $.fn.myPlugin.config, options);
secondFunc: function (rezG) {
return function(){
var dataLinkId = $(this).data('link'),
container = $(rezG.config.container).filter(function(){
return $(this).data('window') == dataLinkId;
});
container.show();
};
}
然后你就这样把它绑起来:
link.on('click', this.secondFunc(this));
请注意,在secondFunc
中,您需要使用config.container
(不仅仅是对象config
),而且您的属性是data window
,而不是data section
更新的演示:您的插件可以像
(function ($, window, document, undefind) {
$.fn.myPlugin = function(options) {
// When $(stuff).myPlugin(...) is called
// this keyword inside of myPlugin function is referencing a set
// of elements plugin was called upon
// e.g. for call like $('.container1').myPlugin();
// this keyword will reference all elements selected by
// $('.container1') not jquery wrapped,
// in general it can be a any number.
return this.each(function pluginImplementation () {
// Here we iterate over the set, and for each element in the set
// we do some pretty standard click
var container = $(this);
// I use 'click.myPlugin' event instead just 'click' ale to later on
// do $(..).off('click.myPlugin') to remove only handlers that were
// attached by plugin (a good practice)
container.on('click.myPlugin', options.linkSelector, function(){
var dataLinkId = $(this).data('link');
container.find('[data-window="' + dataLinkId + '"]').toggle();
})
});
};
})(jQuery, window, document);
见
然而,上面的代码可能有一个问题luginImplementation()
函数是在每次迭代中创建的,如果该函数的主体更复杂,那么它将是一团混乱。这就是为什么最好在外部创建pluginImplementation()
(function ($, window, document, undefind) {
// Notice that pluginImplementation () now accepts parameters
// They make it possible for pluginImplementation to know which
// elements it's working with
function pluginImplementation (container, options) {
container.on('click.myPlugin', options.linkSelector, function(){
var dataLinkId = $(this).data('link');
container.find('[data-window="' + dataLinkId + '"]').toggle();
})
}
$.fn.myPlugin = function(options) {
return this.each(function () {
pluginImplementation($(this), options);
});
};
})(jQuery, window, document);
这种分离可能还不够好。你可能希望你的插件更加面向对象,而不是什么。因此,你可以像这样做:
(function ($, window, document, undefind) {
// For that purpose we create a class
// That describes behavior that our plugin provides
//
function MyPlugin(container, options) {
this.container = container;
this.options = options;
// To the topic of maintainability
// This could be parametrised as an option at plugin instantiation
this.eventName = 'click.myPlugin';
}
MyPlugin.prototype.attachClickHandlers = function() {
var self = this;
// This gets a little messy with all the thises vs selfs and a
// noname function wrapping the handler.
// The point is to preserve this keyword reference
// inside of clickHandler method.
// If I would have just self.clickHandler as a handler there
// this keyword inside of self.clickHandler would reference to
// whatever $(...).on binds handlers to i.e. triggering element.
// I need this keyword inside of self.clickHandler to point to
// "current" instance of MyPlugin, that's why I have wrapping
// function. It just lets me call clickHandler in the right context.
// clickHandler method also needs to know what link is being clicked
// so we pass that in as parameter.
self.container.on(self.eventName,
self.options.linkSelector,
function() {
self.clickHandler($(this));
})
}
MyPlugin.prototype.clickHandler = function(clickedLink) {
var dataLinkId = clickedLink.data('link');
this.container.find('[data-window="' + dataLinkId + '"]').toggle();
}
$.fn.myPlugin = function(options) {
return this.each(function () {
var pluginInstance = new MyPlugin($(this), options);
pluginInstance.attachClickHandlers();
});
};
})(jQuery, window, document);
在这个实现中,MyPlugin是一个类(在javascript意义上是单词class),它使您能够以其行为方式处理每个特定点。并介绍各种面向对象的特性
你的插件可以简单到
(function ($, window, document, undefind) {
$.fn.myPlugin = function(options) {
// When $(stuff).myPlugin(...) is called
// this keyword inside of myPlugin function is referencing a set
// of elements plugin was called upon
// e.g. for call like $('.container1').myPlugin();
// this keyword will reference all elements selected by
// $('.container1') not jquery wrapped,
// in general it can be a any number.
return this.each(function pluginImplementation () {
// Here we iterate over the set, and for each element in the set
// we do some pretty standard click
var container = $(this);
// I use 'click.myPlugin' event instead just 'click' ale to later on
// do $(..).off('click.myPlugin') to remove only handlers that were
// attached by plugin (a good practice)
container.on('click.myPlugin', options.linkSelector, function(){
var dataLinkId = $(this).data('link');
container.find('[data-window="' + dataLinkId + '"]').toggle();
})
});
};
})(jQuery, window, document);
见
然而,上面的代码可能有一个问题luginImplementation()
函数是在每次迭代中创建的,如果该函数的主体更复杂,那么它将是一团混乱。这就是为什么最好在外部创建pluginImplementation()
(function ($, window, document, undefind) {
// Notice that pluginImplementation () now accepts parameters
// They make it possible for pluginImplementation to know which
// elements it's working with
function pluginImplementation (container, options) {
container.on('click.myPlugin', options.linkSelector, function(){
var dataLinkId = $(this).data('link');
container.find('[data-window="' + dataLinkId + '"]').toggle();
})
}
$.fn.myPlugin = function(options) {
return this.each(function () {
pluginImplementation($(this), options);
});
};
})(jQuery, window, document);
这种分离可能还不够好。你可能希望你的插件更加面向对象,而不是什么。因此,你可以像这样做:
(function ($, window, document, undefind) {
// For that purpose we create a class
// That describes behavior that our plugin provides
//
function MyPlugin(container, options) {
this.container = container;
this.options = options;
// To the topic of maintainability
// This could be parametrised as an option at plugin instantiation
this.eventName = 'click.myPlugin';
}
MyPlugin.prototype.attachClickHandlers = function() {
var self = this;
// This gets a little messy with all the thises vs selfs and a
// noname function wrapping the handler.
// The point is to preserve this keyword reference
// inside of clickHandler method.
// If I would have just self.clickHandler as a handler there
// this keyword inside of self.clickHandler would reference to
// whatever $(...).on binds handlers to i.e. triggering element.
// I need this keyword inside of self.clickHandler to point to
// "current" instance of MyPlugin, that's why I have wrapping
// function. It just lets me call clickHandler in the right context.
// clickHandler method also needs to know what link is being clicked
// so we pass that in as parameter.
self.container.on(self.eventName,
self.options.linkSelector,
function() {
self.clickHandler($(this));
})
}
MyPlugin.prototype.clickHandler = function(clickedLink) {
var dataLinkId = clickedLink.data('link');
this.container.find('[data-window="' + dataLinkId + '"]').toggle();
}
$.fn.myPlugin = function(options) {
return this.each(function () {
var pluginInstance = new MyPlugin($(this), options);
pluginInstance.attachClickHandlers();
});
};
})(jQuery, window, document);
在这个实现中,MyPlugin是一个类(在javascript意义上是单词class),它使您能够以其行为方式处理每个特定点。并介绍各种面向对象的特性
你的插件可以简单到
(function ($, window, document, undefind) {
$.fn.myPlugin = function(options) {
// When $(stuff).myPlugin(...) is called
// this keyword inside of myPlugin function is referencing a set
// of elements plugin was called upon
// e.g. for call like $('.container1').myPlugin();
// this keyword will reference all elements selected by
// $('.container1') not jquery wrapped,
// in general it can be a any number.
return this.each(function pluginImplementation () {
// Here we iterate over the set, and for each element in the set
// we do some pretty standard click
var container = $(this);
// I use 'click.myPlugin' event instead just 'click' ale to later on
// do $(..).off('click.myPlugin') to remove only handlers that were
// attached by plugin (a good practice)
container.on('click.myPlugin', options.linkSelector, function(){
var dataLinkId = $(this).data('link');
container.find('[data-window="' + dataLinkId + '"]').toggle();
})
});
};
})(jQuery, window, document);
见
然而,上面的代码可能有一个问题luginImplementation()
函数是在每次迭代中创建的,如果该函数的主体更复杂,那么它将是一团混乱。这就是为什么最好在外部创建pluginImplementation()
(function ($, window, document, undefind) {
// Notice that pluginImplementation () now accepts parameters
// They make it possible for pluginImplementation to know which
// elements it's working with
function pluginImplementation (container, options) {
container.on('click.myPlugin', options.linkSelector, function(){
var dataLinkId = $(this).data('link');
container.find('[data-window="' + dataLinkId + '"]').toggle();
})
}
$.fn.myPlugin = function(options) {
return this.each(function () {
pluginImplementation($(this), options);
});
};
})(jQuery, window, document);
这种分离可能还不够好。你可能希望你的插件更加面向对象,而不是什么。因此,你可以像这样做:
(function ($, window, document, undefind) {
// For that purpose we create a class
// That describes behavior that our plugin provides
//
function MyPlugin(container, options) {
this.container = container;
this.options = options;
// To the topic of maintainability
// This could be parametrised as an option at plugin instantiation
this.eventName = 'click.myPlugin';
}
MyPlugin.prototype.attachClickHandlers = function() {
var self = this;
// This gets a little messy with all the thises vs selfs and a
// noname function wrapping the handler.
// The point is to preserve this keyword reference
// inside of clickHandler method.
// If I would have just self.clickHandler as a handler there
// this keyword inside of self.clickHandler would reference to
// whatever $(...).on binds handlers to i.e. triggering element.
// I need this keyword inside of self.clickHandler to point to
// "current" instance of MyPlugin, that's why I have wrapping
// function. It just lets me call clickHandler in the right context.
// clickHandler method also needs to know what link is being clicked
// so we pass that in as parameter.
self.container.on(self.eventName,
self.options.linkSelector,
function() {
self.clickHandler($(this));
})
}
MyPlugin.prototype.clickHandler = function(clickedLink) {
var dataLinkId = clickedLink.data('link');
this.container.find('[data-window="' + dataLinkId + '"]').toggle();
}
$.fn.myPlugin = function(options) {
return this.each(function () {
var pluginInstance = new MyPlugin($(this), options);
pluginInstance.attachClickHandlers();
});
};
})(jQuery, window, document);
在这个实现中,MyPlugin