So I have a bit of experience writing normal plugins to do whatever, but I want to move towards an object-based event-driven system that can be more dynamic and customizable for the end user. For the sake of my question I have written up a small plugin that simply highlights text on the $(selector).hover()
event.
Here is the JS/jQuery:
(function($) {
var objs = [];
var defaults = {
color: "blue",
normal: "black",
onHover: function() {},
offHover: function() {}
};
var Text = function (settings, self) {
this.self = $(self);
this.color = settings.color;
this.normal = settings.normal;
this.show = function () { this.self.css( "color", this.color); }
this.noShow = function () { this.self.css( "color", this.normal);}
this.onHover = settings.onHover;
this.offHover = settings.offHover;
};
$.fn.myPlugin = function(opts) {
this.each(function() {
var settings = $.extend({}, defaults, opts);
$(this).data('index', objs.push(new Text(settings, this)) -1);
// I feel like this should be handled differently, maybe
// attach an event to the inside of the object?
});
this.hover(
function(e) {
objs[$(e.currentTarget).data('index')].show();
objs[$(e.currentTarget).data('index')].onHover();
}, function(e) {
objs[$(e.currentTarget).data('index')].noShow();
objs[$(e.currentTarget).data('index')].offHover();
});
};
}(jQuery));
Basically, this line...
(this).data('index', objs.push(new Text(settings, this)) -1);
...could be handled much differently and more efficiently. The problem is I need a global array that holds all objects generated by the plugin. So if I call the plugin twice on two separate 'p' tags, then there should be two objects in that array, so on so forth. Right now, that aspect is 'working' but I need to store a reference to what index that object is at by attaching an 'index' data type to the DOM element. This feels like a very wrong way to have an object oriented approach. So how can I, on an event, trigger the function...
myObject.show();
...where myObject is a reference to the element in the array that I want to highlight.
I hope my question is clear, it is a weird issue to describe I feel, but also a very powerful concept if it can be applied the way I am thinking of it. Let me know if anything is unclear and I would be happy to clarify.
In doing a bit more reading and trying to understand how object oriented programming works in respect to javascript, jquery and the DOM, I stumbled upon my own answer. Here is what the code looks like for anyone that may have been as confused as I was going into plugin development:
(function($) {
var defaults = {
color: "blue",
normal: "black",
onHover: function() {},
offHover: function() {}
};
var Text = function(opts, self) {
var settings = $.extend({}, defaults, opts);
this.self = $(self);
this.color = settings.color;
this.normal = settings.normal;
this.onHover = settings.onHover;
this.offHover = settings.offHover;
this.show = function () { this.self.css( "color", this.color); };
this.noShow = function () { this.self.css( "color", this.normal); };
};
$.fn.myPlugin = function(opts) {
this.each(function() {
this.text = new Text(opts, this);
});
this.hover(
function() {
this.text.show();
this.text.onHover.call();
}, function() {
this.text.noShow();
this.text.offHover.call();
});
};
}(jQuery));
The issue I was dealing with was an appropriate understanding of name space and closure, as well as what things you can and cannot do with DOM elements. I am not sure if this is the common way or not, but it is working very well for my uses and might work for yours.