I just started writing Plugins for jQuery. I found a good tutorial how to start with it, but one point I missed. I want register a independent plugin-object for each element and I need them events.
Here the code I got atm:
(function($){
var MyPlugin = function(pElement, pOptions)
{
var element = $(pElement);
var object = pElement;
var settings = $.extend({
param: 'defaultValue'
}, pOptions || {});
this.onfocus = function() {
element.val('Focus');
};
this.onblur = function() {
element.val('Blur');
}
// DO I NEED THIS?
object.onfocus = this.onfocus;
object.onblur = this.onblur;
};
$.fn.myplugin = function(options)
{
return this.each(function()
{
var element = $(this);
if (element.data('myplugin')) { return };
var myplugin = new MyPlugin(this, options);
element.data('myplugin', myplugin);
});
};
})(jQuery);
Do I need to copy my public methods "onfocus" and "onblur" from "this" to "object"? Is there a better way?
The best guide for writing jQuery plugins is probably jQuery's own.
jQuery's event system is the best way of handling events for your plugin. If you're using jQuery 1.7+ (which I recommend, if it's possible), .on() and .off() are your workhorses. Not only can you bind browser events like focus and blur, you can create completely custom events like 'iamasuperstar' and trigger them manually with this.trigger( 'iamasuperstar' ).
So you'd do something like this for your plugin:
element.on( 'focus', function() {} )
element.on( 'blur', function() {} )
...and whatever else you need.
Why not:
object.onfocus = function() {
element.val('Focus');
};
object.onblur = function() {
element.val('Blur');
}
Related
I have an Object and I want to bind a function to a button when Object was initialized.
var MyClass = {
Click: function() {
var a = MyClass; // <---------------------- look here
a.Start();
},
Bind: function() {
var a = document.getElementById('MyButton');
a.addEventListener('click', this.Click, false); //<---------- and here
},
Init: function() {
this.Bind();
}
}
So, I'm new at using it and I don't know if object can be declared like this (inside Click() function that should be done after clicking a button):
Is it a bad practise? Which could be the best way in this case when adding an event here?
Edit: fiddle
Firstly you have a syntax error. getElementsById() should be getElementById() - no s. Once you fix that, what you have will work, however note that it's not really a class but an object.
If you did want to create this as a class to maintain scope of the contained methods and variables, and also create new instances, you can do it like this:
var MyClass = function() {
var _this = this;
_this.click = function() {
_this.start();
};
_this.start = function() {
console.log('Start...');
}
_this.bind = function() {
var a = document.getElementById('MyButton');
a.addEventListener('click', this.click, false);
};
_this.init = function() {
_this.bind();
};
return _this;
}
new MyClass().init();
<button id="MyButton">Click me</button>
For event listeners it's easiest and best to use jQuery, for example if you want to have some .js code executed when user clicks on a button, you could use:
https://api.jquery.com/click/
I don't know how new you are to .js, but you should look up to codecademy tutorials on JavaScript and jQuery.
.click() demo:
https://www.w3schools.com/jquery/tryit.asp?filename=tryjquery_event_click
Many jQuery plugins do something like this:
$('#selector').myPlugin({option:"value"});
However, inside myPlugin I want to use jQuery .on(), so I need another selector:
// my-plugin.js
(function($){
$.fn.myPlugin = function(options) {
// Help!! I need a container here!
$(?????).on("click", this.selector, function(){
alert('success!');
});
};
})(jQuery);
How do I pass another selector for use in the .on statement inside my plugin? (I realize that a selector is only text and I could pass it with my options I'm passing, but is that the standard approach?)
EDIT:
Found this later and it also provides good clarification on dealing with this issue: jQuery plugin to apply also on dynamically created elements
You obviously have no need for the selected element, therefore i suggest instead creating your plugin on $ directly rather than $.fn so that you don't waste time selecting elements that you'll never use. Pass in the context and selector through the options object parameter as an object.
$.myPlugin = function (options) {
$(options.context).on("click", options.selector, function(){
alert("Hello World!");
});
}
$.myPlugin({
context: "#container",
selector: ".targetel"
});
An alternative would be:
$.fn.myPlugin = function (selector) {
return this.on("click", selector, function(){
alert("Hello World!");
});
}
$("#container").myPlugin(".targetel");
Try this (edit)
(function($){
$.fn.myPlugin = function(options) {
settings = {
container : null
};
var options = $.extend({}, settings, options);
// Help!! I need another selector here!
return $(options.container).on("click", function(){
alert('success!');
});
};
})(jQuery);
$('html').myPlugin({container:"body"})
jsfiddle http://jsfiddle.net/guest271314/vpu33/
hi see this fiddle:
http://jsfiddle.net/jFIT/4cNRC/
$.fn.myPlugin = function(options) {
$("#container").on("click", '#'+$(this).attr('id'), function(){
alert('success!');
});
//OR if container is dynamic..
$(this).parent().on("click", '#'+$(this).attr('id'), function(){
alert('Dynamic success!');
});
};
$('#someDiv').myPlugin({option:"value"});
I know, there are quite a few examples on the Web, but finding real one out of them all is tough for beginner. So I want to create jQuery plugin with public methods. Example code:
(function($) {
$.fn.peel = function(options) {
var defaults = {
};
var settings = $.extend({},defaults, options);
this.public = function() {
alert("public");
};
var private = function() {
alert("private");
}
return this.each(function() {
//this.public();
private();
});
};
})(jQuery);
As I found, this is the way to make public function, which could be called like this :
var peel = $('img').peel();
peel.public();
So far it works as expected - public() can be called. But what if i want to call that function within my plugin? I commented out in this.each() because it does not work. How can i achieve that?
One way to create publicly accessible methods within your plugins is to use the jQuery UI widget factory. This is the framework that jQuery UI uses for all of it's supported UI widgets. A quick example would look like this:
(function( $ ) {
$.widget( "something.mywidget", {
// Set up the widget
_create: function() {
},
publicFunction: function(){
//...
}
});
}( jQuery ) );
var $w = $('#someelement').mywidget();
$w.mywidget('publicFunction');
I wonder if selector "$cacheA" will be cached on page load in the example below?
// MY JQUERY FUNCTION/PLUGIN
(function( $ ){
$.fn.myFunction = function() {
var $cacheA = this,
$cacheB = $cacheA.children(),
$cacheC = $cacheB.eq(0);
$cacheD = $cacheA.parent();
$cacheD.click(function(){
$cacheA.toggle();
$cacheB.fadeIn();
$cacheC.slideUp();
});
};
})( jQuery );
// END JQUERY FUNCTION/PLUGIN
$(window).load(function(){
$('#mySelector').myFunction();
});
Would it be any reason to do this:
$(window).load(function(){
var $mySelector = $('#mySelector');
$mySelector.myFunction();
});
If, inside your "load" handler, you were to do many jQuery operations with "$mySelector", then saving that in a variable would be a good idea. However, in your example, you only use the value once, so it really makes no difference at all.
Firstable, $cacheA and others inside click function will be undefined.
$cacheD.click(function(){
$cacheA.toggle();
$cacheB.fadeIn();
$cacheC.slideUp();
});
Second,
$.fn.myFunction = function() {
var $cacheA = this,
$cacheB = $cacheA.children(),
$cacheC = $cacheB.eq(0);
$cacheD = $cacheA.parent();
}
So, after $('selector').myFunction() how can I use $cacheB, $cacheC and $cacheD? Where they are will store?
I have a widget defined like so:
$.widget("ui.mywidget", {
_init: function() {
this.element.bind("keyup", function(event) {
alert(this.options);
alert(this.options.timeout);
});
}
});
And trying to call it like so:
$("input.mywidget").mywidget({timeout: 5});
I also redefined the bind method using the this.element.keyup(function(event) { ... }) style: no difference.
But, in the keyup bind, this.options (and referencing it just as options) both yield undefined. I thought the UI widget framework allowed this type of abstraction; am I doing something wrong?
When inside bind(), this changes to refer to the object that the event is raised on. Try:
$.widget("ui.mywidget", {
_init: function(options) {
var opts = this.options;
this.element.bind("keyup", function(event) {
alert(opts);
alert(opts.timeout);
});
}
});
What #Dave said is right. You can also set "this" to a variable rather than using options as an argument to the init function. Here is how I see it implemented often:
$.widget("ui.mywidget", {
options: {
timeout: 100
},
_init: function() {
var self = this;
self.element.bind("keyup", function(event) {
alert(self.options);
alert(self.options.timeout);
});
}
});
Why stop there? Check out $.proxy and write better code
$.widget("ui.mywidget", {
_create: function() {
//Under this syntax, _omgAlertsRule must be a method of 'this'
this.element.bind("keyup", $.proxy( this, '_omgAlertsRule' ) );
},
_omgAlertsRule: function( event ){
alert(this.options);
alert(this.options.timeout);
}
});