For some jQuery plugins
it would be useful if we could expose one or more functions, so that we
can interact with it from Javascript outside the plugin. If we follow
the standard mechanism of plugin authoring, we can only interact with
the it at the moment of initialisation. This post will look at two
mechanisms that can be used to expose and access plugin functions.
This post will be based around the following mediaPlayer fictional plugin:
- (function($) {
- $.fn.mediaPlayer = function(options){
- .........
- }
- })(jQuery);
- $('.myDiv').mediaPlayer(options);
Class and Function Mechanism
With the standard mechanism of building a jQuery plugin we always ensure that the plugin function returns this (the current context of the plugin). The reason for returning the current context is that it allows the plugin call to be chained onto another plugin call. For example:- $('.myDiv')
- .mediaPlayer(options)
- .otherPlugin();
- (function($) {
- //the class
- var player = function(options){
- return createApi();
- function createApi(){
- return {
- play : play
- }
- }
- function play(url) {
- //our play code
- }
- }
- //the function
- $.fn.mediaPlayer = function(options){
- //create an instance of the class and return from the plugin
- return new player(options);
- }
- })(jQuery);
- var myMediaPlayer = $('.myDiv').mediaPlayer(options);
- myMediaPlayer.play(url1);
- myMediaPlayer.play(url2);
- $('.myDiv')
- .mediaPlayer(options)
- .otherPlugin();
- $('.myDiv')
- .mediaPlayer(options);
- $('.myDiv')
- .otherPlugin();
Execution Through apply() Mechanism
An alternative, and my preferred approach, is to execute the ‘public’ functions in the main plugin function by use of the apply() command. For this approach to work the plugin function has to be effectively overloaded, so that it can be used in two ways. It needs to retain it’s constructive form which in out case takes one argument of options, but it also needs to be able to accept an alternative call that takes a string argument (function name) and any additional arguments that this function requires.The example below shows how we might use this mechanism to build our mediaPlayer plugin.
- (function($) {
- //define the commands that can be used
- var commands = {
- play: play,
- stop: stop
- };
- $.fn.mediaPlayer = function() {
- if (typeof arguments[0] === 'string') {
- //execute string comand on mediaPlayer
- var property = arguments[1];
- //remove the command name from the arguments
- var args = Array.prototype.slice.call(arguments);
- args.splice(0, 1);
- commands[arguments[0]].apply(this, args);
- }
- else {
- //create mediaPlayer
- createMediaPlayer.apply(this, arguments);
- }
- return this;
- };
- function createMediaPlayer(options){
- //mediaPlayer initialisation code
- }
- //Exposed functions
- function play(url) {
- //code to play media
- }
- function stop() {
- //code to stop media
- }
- })(jQuery);
If the first argument is a string, then this must be the name of the function that is required to be executed. A new arguments array is prepared by stripping off the first argument (see this blog post about splice), as the called method won’t need this. Then the named function is executed by calling apply() and passing the current context and our new list of arguments. You might notice that when this named function is executed it has to retrieved from the commands object by using the bracket notation. This is required for the apply() function to be able to execute functions dynamically from string values.
This is how we would initialise this plugin and call the play() function:
- $('.myDiv')
- .mediaPlayer(options);
- $('.myDiv')
- .mediaPlayer('play', url1);
- $('.myDiv')
- .mediaPlayer(options)
- .otherPlugin();
- //chain calls to our play method...
- $('.myDiv')
- .mediaPlayer('play', url1)
- .mediaPlayer('play', url2);
Conclusion
In this post I’ve looked at two mechanisms that can be used to expose functions on jQuery plugins. The first of these is the Class and Function Mechanism that exposes ‘public’ functions by returning an instance of a class from the plugin initialisation function. Although this does allow functions to be exposed, it does break jQuery chaining and so is not ideal.The Execution Through apply() Mechanism still allows jQuery chaining as the current context is still returned from the plugin initialisation function. This mechanism allows access to functions by effectively overloading the initialisation function to allow the name of the function that is to be executed to be passed in. This function can then be executed by using the JavaScript apply() command.


7:27 PM
Unknown
Posted in: 


0 comments:
Post a Comment