jquery Spring Plug-in Writing Foundation "See the Window Again" _jquery

Source: Internet
Author: User
Tags closure extend

This article will be an example of the development of jquery plug-ins Some of the details, first of all, the introduction of jquery plug-in development of some basic knowledge.

jquery's plug-in development is divided into two main categories:

1. Class level, which extends methods on the jquery class itself, similar to $.ajax,$.get.

2. Object level, where the so-called object is the jquery object selected through the jquery selector to add a method to the object. For example: $ (' div '). CSS (), $ (' div '). Show ().

In actual development, we usually use object-level methods to develop Plug-ins, jquery powerful selector and object operation is a big reason we choose this way.

Next we'll look at what the two ways are:

Class-Level plug-in development

$.extend ({
  foo:function () {
  //...
  },
  bar:function () {
  //...}}
)
Call
$.foo ();

Here, the name of the extension method needs to be refined so that it does not duplicate the original method in the jquery class. Even so, when we need to extend multiple methods on a class, there is still the possibility of a naming conflict, for which we can create a custom namespace:

$.myplugin = {
  foo:function () {
    //...
  },
  bar:function () {
    //...
  }
 } Call
$.mypulgin.foo ();

Object-level plug-in development

$.fn.foo = function () {
  //dosomething ...
}
Call (suppose to have an element with ID obj)
$ (' #obj '). Foo ();
One would ask, what is FN? Stick to another interception of the JQuery source is understood:
Jquery.fn = Jquery.prototype = {
  Init:function (selector, context) {
    //...
  }
}

Originally is the prototype chain AH ...

Receive configuration parameters

In the writing of a plug-in, we can allow users to use Plug-ins to set some of the properties of the plug-in, which requires plug-ins have the function of receiving parameters, and when the use of plug-ins do not pass the parameters, the plug-in inside also have their own default configuration parameters.

$.fn.foo = function (options) {
var defaults = {
color: ' #000 ',
backgroundcolor: ' Red '
};
    var opts = $.extend ({}, defaults, options); 
alert (Opts.backgroundcolor); Yellow
}
$ (' #obj '). Foo ({
  backgroundcolor: ' Yellow '  
})

The key here is the $.extend method, which is able to merge objects. For the same property, the object that follows overrides the previous object. Why is the Extend method the first argument an empty object? Because the method merges the latter into the former, the first argument is set to an empty object in order not to allow defaults to be changed.

If we allow people who use Plug-ins to set default parameters, they need to be exposed:

$.fn.foo = function (options) {
var opts = $.extend ({}, $.fn.foo.defaults, options); 
alert (Opts.backgroundcolor);
}
$.fn.foo.defaults = {
  color: ' #000 ',
  backgroundcolor: ' Red '
}

This allows you to modify the default parameters of the plug-in externally.

Appropriate exposure to some methods

$.fn.foo = function (options) {
var opts = $.extend ({}, $.fn.foo.defaults, options); 
$.fn.foo.saycolor (Opts.backgroundcolor);
}
$.fn.foo.saycolor = function (bgcolor) {
  alert (bgcolor);
}
$.fn.foo.defaults = {
  color: ' #000 ',
  backgroundcolor: ' Red '
}

Rewrite:

$.fn.foo.saycolor = function (bgcolor) {
  alert (' Background color is ' + bgcolor);
}

Exposing some of the methods in a plug-in is a great way to make it possible for others to extend and overwrite your methods. But when someone changes your parameters or methods, it's likely to affect a lot of other things. So when you think about how to expose the method, be clear and don't be exposed.

Keep the function private

Speaking of keeping private, what do you think first? Yes, that's the closure:

;(function ($) {
  $.fn.foo = function (options) {
    var opts = $.extend ({}, $.fn.foo.defaults, options); 
    Debug (Opts.backgroundcolor);
  }
  function Debug (bgcolors) {
    console.log (bgcolors);
  }
  $.fn.foo.defaults = {
    color: ' #000 ',
    backgroundcolor: ' Red '
  }
} (JQuery)

This is the way the plugin is developed by the JQuery official, and the benefits include: 1. No global dependency 2. Prevent others from destroying 3. Compatible ' $ ' and ' jQuery ' operators.

As above, the Debug method is a private method inside the plug-in that cannot be modified externally. Add in front of the closure pack; is to prevent the code from merging, if the code before the closure is missing a semicolon, resulting in a subsequent error.

Merge

;(function ($) {
  ///define plug-in
  $.fn.foo = function (options) {
    //dosomething ...
  }
  Private Functions function
  Debug () {
    //dosomething ...
  }
  Define the exposure function
  $.fn.foo.saycolor = functions () {
    //dosomething ...
  }
  Plugin default parameter
  $.fn.foo.default = {
    color: ' #000 ',
    backgroundcolor: ' Red '
  }
} (JQuery);

The above code creates a complete and canonical plugin skeleton, although it seems very simple but there are a lot of skills and considerations in the actual development, and then we look through an example.

Thought for a long time, think the window as a plug-in as an example is more appropriate. Before we develop, we'll start by thinking about the structure and function of this window plugin:

From the above figure we see three sections, headings, content, and button groups. Here we need to make it clear that we don't want to be just the default alert box with just one button in the browser, but the user can customize the number of buttons so that the pop-up box can do the same thing as the Confirm box.

Build the skeleton of the plug-in

Function subtype ($ele, options) {this
  . $ele = $ele;
  This.opts = $.extend ({}, $.fn.popwin.defaults, options);
Subtype.prototype = {
  createpopwin:function () {
  }
};
$.fn.popwin = function (options) {
  //this point to the object selected by the jquery selector
  var supertype = new Subtype (this, options);
  Supertype.createpopwin ();
};
$.fn.popwin.defaults = {};

1. We have created an object-based and named Popwin method, and the defaults default configuration parameters are exposed for use by the person to modify;

2. Here we use object-oriented methods to manage our private functions, and the Createpopwin method is our private function to create a window.

3. The JQ object and the custom parameters are passed into the constructor and instantiated when the plug-in is invoked.

Call

Imagine how we would call this plugin? We can insert a DIV element in the appropriate place in our document tree, select the Div, and invoke the Popwin method that we defined on the jquery object.

$ (' #content '). Popwin ({
  a:1,
  b:2,
  callback:function () {}
});

When the Popwin is invoked to pass in the custom configuration parameters, the selected DIV element is magically transformed into a bouncing window! Of course, this is just our idea, following the start code code.

Determining the default configuration

$.fn.popwin.defaults = {
  width: ' 600 ',///Window width
  height: ' 250 ',///Window High title
  : ' title ',//title
  desc: ' Description ',//description C11/>wincssname: ' Pop-win ',//Window CSS class name
  titlecssname: ' Pop-title ',//title area CSS class name
  desccssname: ' Pop-desc ',// Describes the CSS class name
  btnareacssname: ' Pop-btn-box ',//button area CSS class name
  btncssname: ' pop-btn ',//CSS class name for individual buttons
  Btnarr: [ ' OK ',///button group
  callback:function () {}//callback function after clicking button
}

We have defined the parameters as above, why do we have to pass in so many CSS class names? 1. To ensure that JS and CSS as far as possible decoupling. 2. Your style is very likely that others do not apply. So you need to configure a style sheet file to correspond to your default class name, and you can pass in your own style when someone needs to change the style.

The button group is an array, and our window needs to dynamically generate several buttons based on the length of the array in which it is passed in. The function of the callback function is to return the index value of the button clicked when the user clicks on it to facilitate his subsequent operation.

Pinball Window DOM creation

var popwindom,titleareadom,descareadom,btnareadom;
    Subtype.prototype = {createpopwin:function () {var _this = this; Create a pop-up window//background for the first time fill the entire window this. $ele. css ({position: ' fixed ', top:0, left:0, right:0, bo
    
    ttom:0, BackgroundColor: ' Rgba (0,0,0,0.4) ', overflow: ' Hidden '}); Window Area Popwindom = $ (' <div><div></div><div></div><div></div></div
      > '). css ({width:this.opts.width, height:this.opts.height, Position: ' absolute ', top: ' 30% ', Left: ' 50% ', marginleft: '-' + (this.opts.width.split (' px ') [0]/2) + ' px '}. attr (' class ', THIS.OPTS.WINCSS
    
    Name); Title Area Titleareadom = Popwindom.find (' div:eq (0) '). Text (This.opts.title). attr (' class ', thi
    
    S.opts.titlecssname); Describes the area Descareadom = Popwindom.find (' Div:eq (1) '). Text (THIS.OPTS.DESC). attr (' class ', this.opts . Desccssname);
    
    Button area Btnareadom = Popwindom.find (' Div:eq (2) '). attr (' class ', this.opts.btnAreaCssName);
        Insert button This.opts.btnArr.map (function (item, index) {btnareadom.append ($ (' <button></button> ')
          . Text (item). attr ({' Data-index ': Index, ' class ': _this.opts.btncssname}). On (' click ', function () {
        _this.opts.callback ($ (this). attr (' Data-index '));
      }));
    
    });
  this. $ele. Append (Popwindom); }
}

1. First named four variables to cache the four DOM we will create, and the incoming jquery object will be formed to cover the entire window semi-transparent element;

2. Create the window DOM, set the size and center according to the incoming height and width, then the window CSS class name that is passed in;

3. Create a title, description, button group area, and the incoming title, description content configuration up;

4. Dynamically add the button and add Data-index index value to the button. Register the Click event, click the incoming callback function, and return the index value.

OK, let's look at the effect first. The call is as follows:

$ (' #content '). Popwin ({
  width: '),
  height: ',
  title: ' System hint ',
  desc: ' Registered success ',
  Btnarr: [' Close '] ,
  callback:function (clickindex) {
    console.log (clickindex);
  }
);

You can see that a window's DOM has been rendered to the page, and when you click on the Close button the console prints "0" because the button group has only one value, of course, the No. 0 one.

If we need to call this window multiple times, it's going to be a lot of trouble to pass in high and wide each time. At this point we can modify the default configuration within the plugin directly at the beginning, which is the benefit of our default configuration exposure:

$.fn.popwin.defaults.width = ' more ';
$.fn.popwin.defaults.height = ' 200 ';

Of course, it is not possible to directly change the defaults reference, so as not to expose the necessary parameters. This eliminates the need to pass in the size of any subsequent calls.

Let's add a button and pass in a custom style to see how it works?

$ (' #content '). Popwin ({
  title: ' System hint ',
  desc: ' Delete current content ',
  btnarr: [' OK ', ' Cancel '],
  wincssname: ' Pop-win-red ',
  callback:function (clickindex) {
    console.log (clickindex);
  }
});

As you can see, the callback function returns 0 when you click on the "OK" button, and when you click the "Cancel" button, the callback functions return 1. The person who uses the plugin will know which button they clicked to complete the next action.

Show & Hide

The next step is to open and close the play window function development. Looking back at the concept described above, we want to allow the person using the plug-in to extend or rewrite the two methods so that they are exposed:

$.fn.popwin.show = function ($ele) {
  $ele. Show ();
$.fn.popwin.hide = function ($ele) {
  $ele. Hide ();
}

These two methods are then invoked where necessary in the Createpopwin method.

Here more emphasis, but also do the window control is inevitable: only when we click on the button and the gray background area to allow the window to close, click the other places do not allow to close the window. Because the window belongs to the whole gray area of the child nodes, it is necessary to involve the event bubbling problem.

So when you give the outermost layer a click off event, stop the event bubbling in the window area.

Popwindom = $ (' <div><div></div><div></div><div></div></div> '). CSS ({
  width:this.opts.width,
  height:this.opts.height,
  position: ' absolute ', top
  : ' 30% ',
  left : ' 50% ',
  marginleft: '-' + (this.opts.width.split (' px ') [0]/2) + ' px '
}). attr (' class ', this.opts.winCssName). On (' click ', Function (event) {
event.stoppropagation ();
});

Two times Open

All we need to do is create all the creation Dom the first time we invoke the plug-in, and only change its parameters on the second call, so add the following method before the Createpopwin method:

if (popwindom) {//window has been created
popwindom.css ({
width:this.opts.width,
height:this.opts.height
}). A  TTR (' class ', this.opts.winCssName);
Titleareadom.text (This.opts.title). attr (' class ', this.opts.titleCssName);
Descareadom.text (THIS.OPTS.DESC). attr (' class ', this.opts.descCssName);
Btnareadom.html ('). attr (' class ', this.opts.btnAreaCssName);
This.opts.btnArr.map (function (item, index) {
btnareadom.append (' <button></button> ')
. Text      (item)
. attr (' Data-index ', index)
. attr (' class ', _this.opts.btncssname)
. On (' click ', Function () {
_this.opts.callback ($ (this). attr (' Data-index '));
$.fn.popwin.hide (_this. $ele);
}));
});
$.fn.popwin.show (this. $ele);
return;
}

Merging the entire plug-in code

;(function ($) {function subtype (ele, options) {this. $ele = Ele;
  This.opts = $.extend ({}, $.fn.popwin.defaults, options);
  } var Popwindom,titleareadom,descareadom,btnareadom;
      Subtype.prototype = {createpopwin:function () {var _this = this;
        if (popwindom) {//window has been created Popwindom.css ({width:this.opts.width, height:this.opts.height
        }). attr (' class ', this.opts.winCssName);
        Titleareadom.text (This.opts.title). attr (' class ', this.opts.titleCssName);
        Descareadom.text (THIS.OPTS.DESC). attr (' class ', this.opts.descCssName);
        Btnareadom.html ('). attr (' class ', this.opts.btnAreaCssName); This.opts.btnArr.map (function (item, index) {btnareadom.append ($ (' <button></button> '). T EXT (item). attr (' Data-index ', index). attr (' class ', _this.opts.btncssname). On (' click ',
    function () {_this.opts.callback ($ (this). attr (' Data-index '));          $.fn.popwin.hide (_this. $ele);
        }));
        });
        $.fn.popwin.show (this. $ele);
      Return
        ///First create the Pinball window this. $ele. css ({position: ' fixed ', top:0, left:0, right:0, bottom:0, BackgroundColor: ' Rgba (0,0,0,0.4) ', overflow: ' Hidden ', display: ' None '}. On (
      ' Click ', Function () {$.fn.popwin.hide (_this $ele);
      }); Popwindom = $ (' <div><div></div><div></div><div></div></div> ').
        CSS ({width:this.opts.width, height:this.opts.height, Position: ' absolute ', top: ' 30% ', Left: ' 50% ', marginleft: '-' + (this.opts.width.split (' px ') [0]/2) + ' px '}. attr (' class ', this.opts
      . Wincssname). On (' click ', Function (event) {event.stoppropagation ();
      }); Titleareadom = Popwindom.find (' div:eq (0) '). Text (This.opts.title). attr (' Class', this.opts.titleCssName); Descareadom = Popwindom.find (' Div:eq (1) '). Text (THIS.OPTS.DESC). attr (' class ', this.opts.descCs
      sname);
      Btnareadom = Popwindom.find (' Div:eq (2) '). attr (' class ', this.opts.btnAreaCssName); This.opts.btnArr.map (function (item, index) {btnareadom.append ($ (' <button></button> '). Text (
            Item). attr ({' Data-index ': Index, ' class ': _this.opts.btncssname}). On (' click ', function () {
            _this.opts.callback ($ (this). attr (' Data-index '));
          $.fn.popwin.hide (_this. $ele);
      }));
      });
      this. $ele. Append (Popwindom);
    $.fn.popwin.show (this. $ele);
    } $.fn.popwin = function (options) {var supertype = new Subtype (this, options);
    Supertype.createpopwin ();
  return this;
  } $.fn.popwin.show = function ($ele) {$ele. Show ();
  } $.fn.popwin.hide = function ($ele) {$ele. Hide (); } $.fn.popwin.defaults = {WidtH: ', Height: ' desc ', title: ' title ', ' Description ', Wincssname: ' Pop-win ', Titlecssname: ' PO
    P-title ', Desccssname: ' Pop-desc ', btnareacssname: ' Pop-btn-box ', btncssname: ' Pop-btn ', Btnarr: [' OK '], Callback:function () {}}}) (JQuery);

As above, a complete window widget is here.

Next, this is the red return this is what to use, said before this here is the selected jquery object. Return it can be called after the end of our plug-in method can continue to invoke the other methods on the JQ object, that is, jquery chain operation, said Iffy point is called the cascading function.

Ok! While the iron is hot, let's see what happens when the two methods are exposed, after all, the extension and rewriting of the exposed part of the plugin is a great thing.

Imagine a situation where you use this plugin to think that the simple show and hide effects are simply too low to explode, and you decide to override this pop-up and hidden effect:

$.fn.popwin.show = function ($ele) {$ele. Children (). (). ().
css (' top ', ' -30% '). Animate ({top: ' 30% '},500);
$ele. Show ();
$.fn.popwin.hide = function ($ele) {
$ele. Children (). A (). Animate ({top: ' -30% '},500,function () {
$  Ele.hide ();
});
}

You add the above two paragraphs to your code and find that the window has a simple effect of sliding up and down into the screen without affecting the creation of our window, proving that our exposure method is reasonable.

Of course, you can also make it vertical, sideways, upside down, it depends on yourself.

Finally put on the default style sheet, in order to be anxious to stick back to try the students.

. pop-win {
  border:1px solid #fff;
  padding:10px;
  Background-color: #fff;
  -wekbit-border-radius:6px;
  border-radius:6px;
  -webkit-box-shadow:0 3px 9px Rgba (0,0,0,0.3);
  box-shadow:0 3px 9px Rgba (0,0,0,0.3);
pop-win-red {
  padding:10px;
  background-color:red;
  -wekbit-border-radius:6px;
  border-radius:6px;
  -webkit-box-shadow:0 3px 9px Rgba (0,0,0,0.3);
  box-shadow:0 3px 9px Rgba (0,0,0,0.3);
pop-title {
  width:100%;
  height:20%;
  line-height:40px;
  padding-left:10px;
  Box-sizing:border-box;
  border-bottom:1px solid #eee;
  font-size:17px;
  Font-weight:bold
}
. Pop-desc {
  width:100%;
  height:60%;
  Box-sizing:border-box;
  padding:10px 0 0 10px;
  border-bottom:1px solid #eee;
Pop-btn-box {
  width:100%;
  height:20%;
  Text-align:right
}
. pop-btn {
  margin:10px 10px 0 0;
  width:60px;
  height:30px;
}

Of course, this is only a plug-in example, if you want to take out the use of the need to carefully polished. Examples, though simple, are intended to stimulate the case.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.