Using jqueryui widgets to write plug-ins has some advantages over the basic jquery plug-ins:
* Easy inheritance,CodeReuse
* The default is Singleton.
* Widgets have provided you with some common methods, such as destroy
The benefits also bring about thorns and traps. The purpose of this article is to sort out these thorns and identify where there are traps.
Basic knowledge: naming conventions, public, private, this, this. Element
How do I start writing a widget? The template is as follows:
(Function($ ){// Utility functions (won't be inherited)FunctionFoo () {}$. widget ('Namespace. Plug-In name', $. Inherit the namespace of the plug-in. Plug-in name ,{/* Snip */}) ;}) (Jquery );
The namespace is optional. Do you want to inherit other widgets. The big head is the part of the snip, which is also described below.
In general, it is more appropriate to write tool functions outside the widget, but if you want these tool functions to inherit from the quilt class, you need to write them in the widget.
The public and private fields are written in the widget. The rules are as follows:
The first character of the public method is not _
The first character of the private method is _
When calling a method, the system first determines whether to start with "_". If yes, the system does not execute the call.
If I have to call the private method outside, what should I do? There is no way either:
VaRInstance = $ ('<Div>'); Instance. mywidget ('Publicfunction');// WorkInstance. mywidget ('_ Privatefunction');// Silently failInstance. Data ('Mywidget'). _ Privatefunction ();// Work$. Mynamespace. mywidget. Prototype. _ privatefunction ();// Work
In a widget, what does this mean? We can use console. Log (this) in a public function of the widget to figure it out:
The log shows that this is a $. widget. $. (anonymous function). (anonymous function)
This. element is the jquery object that becomes a widget. If you want to use the jquery method, you must first obtain the jquery object.
This. options is the plug-in option.
This. _ PROTO _ contains all the public and private functions defined in the plug-in and the inherited methods.
Here, we will briefly introduce _ PROTO __: each object will Initialize an attribute inside it, that is, _ PROTO __. when we access the attribute of an object, if this attribute does not exist in the object, the object will search for this attribute in _ PROTO _. The _ PROTO _ has its own _ PROTO __, as a result, we keep looking for the concept of prototype chain.
_ Create _ init destroy
Widget factory implements a singleton mode, that is, it cannot be instantiated multiple times on the same jquery object.
When $ (XX). widgetname () is called for initialization, the following code is executed (the source code is truncated from jquery. UI. widget. JS ):
VaRInstance = $. Data (This, Name );// Retrieve the data named name from the widget itselfIf(Instance) {instance. Option (options | |{}). _ Init ();// If the data already exists, only _ init is called.}Else{$. Data (This, Name,New Object(Options,This));// If no data exists, create a new instance and save the instance}
When you call $ (XX). widgetname ('deststroy') to destroy the object, run the following code (the source code is truncated from jquery. UI. widget. JS ):
This. Element. Unbind ("."+This. Widgetname). removedata (This. Widgetname );// Delete the data saved during create
There is a removedata operation, so the next call $ (XX). widgetname () will be re-instantiated.
Note that the destroy method is implemented by default in jquery. UI. widget. JS, while _ create and _ init are not implemented. ThereforeIf you use your own method to override destroy, do not forget to call the default:
Destory:Function() {Console. Log ('Destory');// Call the original destroy method since we overwrote it$. Widget. Prototype. Destroy. Call (This);}
The following code verifies the difference between _ create and _ init and the role of destroy:
var Mw = $ ( '# test' ). mywidget (); // _ create _ init MW =$ ( '# test' ). mywidget (); // _ init mW. mywidget ( 'destory ' ); mw = $ ( '# test' ). mywidget (); // _ create _ init
What should we do in _ create, _ init, and destroy:
_ Create: Generate HTML and bind events.
_ Init: Execute the default initialization action, such as changing the page to the initial state.
Destory: Call $. widget. Prototype. Destroy. Call (This) To delete HTML.
Note: To bind an event, add the namespace suffix to the event name, for example,. BIND ('mouseenter. Mywidget', This. _ hover)
Options
Option. The definition in the widget is options, and the call is option. Note that S is used for definition and S is not used for call.
Definition:
Option
S
: {Field1:'Default', Function1:Function() {Console. Log ('Default option function1');}},
Call:
$ ('# Test'). Mywidget ('Option','Field1', 2 );
By default, Widgets implement two functions: _ setoptions and _ setoption. _ setoptions calls _ setoption for each option to be modified, that is, the actually modified action is in _ setoption. Therefore, if you wantDo not forget to write the _ setoption function.:
$. Widget. Prototype. _ setoption. Apply (This, Arguments );
When will the _ setoptions and _ setoption functions be called? Use the following example to describe.
For example, there are _ setoption and _ setoptions:
_ Setoption:Function(Key, value) {console. Log ('_ Setoption: Key = % s value = % s', Key, value); $. widget. Prototype. _ setoption. Apply (This, Arguments) ;}, _ setoptions:Function(Options ){VaRKey; console. Group ('_ Setoptions');For(KeyInOptions ){This. _ Setoption (Key, options [Key]);} console. groupend ();Return This;},
And a printoptions function that prints the options value:
Printoptions:Function() {Console. Group ('Options'); Console. Log ('Field1: % s',This. Options. field1); console. Log ('Function1: % s',This. Options. function1); console. groupend ();},
We call it as follows:
VaR Instance = $ ( '<Div>' ); // Create widget with default options Console. Group (); instance. mywidget (); instance. mywidget ( 'Printoptions' ); Console. groupend (); // Create widget with specified options Instance. mywidget ( 'Deststroy' ); Console. Group ();VaR Opts = {field1: 'Specified' , Function1: Function () {Console. Log ( 'Specified option function1' ) ;},}; Instance. mywidget (OPTs); instance. mywidget ( 'Printoptions' ); Console. Log ( '-------------' ); Instance. mywidget (OPTs); console. groupend (); // Modify options Console. Group (); instance. mywidget ( 'Option' , 'Field1' , 2); instance. mywidget ( 'Printoptions' ); Console. groupend ();
The output log is as follows:
Logs are divided into three parts.
The first block does not use options for initialization. You can see that the default options in the definition are directly used, and _ setoption is not called.
The second is to use options for initialization. This one is used for two experiments (-------- is used to separate the two in the log). The first experiment is completely rebuilt (_ create, _ init ), the log shows that _ setoption is not called. The second experiment Only reinitializes (_ init) and uses the same options. The log shows that _ setoption is called, and called before _ init.
The third part is not initialization, but only modifying the option value. It is clear that _ setoption is called.
When Will _ setoption be called? conclusion:
1. Like instance. mywidget ('Option','Field1', 2); this explicitly sets the option.
2. When initializing with options:
If the instance does not exist and _ create needs to be called, _ setoption is not called;
If the instance already exists and you only need to call _ init, _ setoption is called before _ init.
_ Trigger
Note that this _ trigger is in jqueryui widget factory, and the trigger function in $. FN namespace in jquery is not a thing (the latter is not underlined ).
_ Trigger is generally used to call back the callback of options passed in by the user.
Calling _ trigger ('myevent') within the plug-in is equivalent to calling the myevent callback function in options.
How should I change the event handler in options? Instead of using bind/unbind, modify options:
// BIND (overwrite, not add event handler)MW. mywidget ('Option','Myevent',Function(Event, UI) {console. Log ('New implement');});// UnbindMW. mywidget ('Option','Myevent',Null);
Summary:
This. _ trigger ('eventname') is unique to widgets and is used to call callback defined in options.
This. element. Trigger ('eventname') is of jquery. For details, refer to the usage of jquery events. (This. element indicates the jquery object of the plug-in)
Example of a _ trigger:
// Template
This. _ Trigger ("Callbackname", [Eventobject], [uiobject])
Callbackname
The name of the event you want to dispatchEventobject
(Optional) An (mocked) event object._ Trigger
Wraps this object and stores it inEvent. originalevent
The user defined es an object with event. type =This. widgeteventprefix + "eventname"
Uiobject
(Optional) an object containing useful properties the user may need to access. protip:Use a method like. _ UI
To generate objects with a consistent schema.
// Call exampleThis. _ Trigger ("Hover", E/* E. type = "mouseenter "*/, {Hovered: Paths (e.tar get )});// The user can subscribe using an init Option$ ("# ELEM"). Filterable ({hover:Function(E, UI ){}});// Or with traditional event binding/Delegation$ ("# ELEM"). BIND ("Filterablehover",Function(E, UI ){});