Analysis and Optimization of JavaScript code for the lucky draw (2)

Source: Internet
Author: User

Analysis and Optimization of JavaScript code for the lucky draw (2)

To write a plug-in. Plug-ins certainly have some characteristics that can meet our development needs or improve our development efficiency. What are the basic features of plug-ins? Let's summarize:

1. Some basic features of the JavaScript plug-in:Make sure that the variables defined in the simple plug-in do not pollute global variables. The same code segment can be reused in different places. Users can customize their own function parameters. They can destroy variables and parameters;

If you write the plug-in based on the above features, we can summarize a basic code structure, one by one:

1. Plug-in configuration should be as simple as possible

Configure container nodes in html

// Here node-type = "reward-area" is the container node that identifies our plug-in$ (Function () {// here test represents the class window of the container. lightRotate. init ($ ('[node-type = reward-area]') ;});
2. variables defined in the plug-in do not pollute global variables

The identifier of JavaScript with block-level scope isfunction. So how can we declare our variables so that they do not pollute global variables?
Here we needJavaScriptKnowledge points of function self-execution. The Code is as follows:

(function(){ // do something})();
3. Reuse functional code in different places

This requires the use of our object-oriented knowledge points to abstract our functional code into an object. When we need to use it, instantiate the object. Then we continue to write the second part of the code,

// (Function ($) {// CREATE function object var LightRotate = function (select) {// do something}; LightRotate. init = function (select) {var _ this = this; // instantiate different select objects based on different containers. each (function () {new _ this ($ (this) ;}) ;}; window. lightRotate = LightRotate;}) (jQuery );
4. You can customize function parameters.

First, we should have default parameter settings, such as the following

// (Function ($) {// create a function object var LightRotate = function (select) {// custom parameter this. setting = {liAutoPlay: false, // whether the surrounding lamp is automatically rotated roLiSpeed: 100, // the speed of the lamp rotation ms roPrSpeed: 200, // The prize rotation speed ms liDirection: true, // orientation: true; positive direction: false; reverse direction: randomPrize: false // random selection of spaces}; LightRotate. init = function (select) {var _ this = this; // instantiate different select objects based on different containers. each (function () {new _ this ($ (this) ;}) ;}; window. lightRotate = LightRotate;}) (jQuery );

In fact, users can modify our JavaScript file to customize it. But in order to make the price difference easy enough, for example, our users do not understand js at all? What should I do?
In this way, we can configure these parameters with custom attributes inhtml, As follows:

// (Function ($) {// create a function object var LightRotate = function (select) {// custom parameter this. setting = {liAutoPlay: false, // whether the surrounding lamp is automatically rotated roLiSpeed: 100, // the speed of the lamp rotation ms roPrSpeed: 200, // The prize rotation speed ms liDirection: true, // The rotation direction is true. The positive direction is false. The reverse direction is "randomPrize: false". // determines whether a space is randomly selected. // The method for obtaining User-Defined parameters of an object is called here, and merge the default parameters $. extend (_ this. setting, _ this. getSettingUser () ;}; LightRotate. prototype = {// extended method for getting User-Defined parameters getSettingUser: fun Ction () {var userSetting = this. LightArea. attr ('data-setting'); if (userSetting & userSetting! = '') {Return $. parseJSON (userSetting);} else {return {};}}; LightRotate. init = function (select) {var _ this = this; // instantiate different select objects based on different containers. each (function () {new _ this ($ (this) ;}) ;}; window. lightRotate = LightRotate;}) (jQuery );
5. Destroy the functions of variables and parameters;

The last one is that our plug-in should have the function of destroying its own variables and parameters. What should we do? You can continue to extend the function object calling method based on the above Code. The Code is as follows:

LightRotate. prototype = {// extended method for getting User-Defined parameters getSettingUser: function () {var userSetting = this. lightArea. attr ('data-setting'); if (userSetting & userSetting! = '') {Return $. parseJSON (userSetting) ;}else {return {}}}, // destroy object parameter destory: function () {$ (_ this. lightArea ). off (); this. closeAnimation (); this. rewardTimer = null ;}};

From the above content, we can roughly understand the basic functions that a mature plug-in should have.

2. Example of plug-in development and optimization

This project was an urgent project before the Spring Festival holiday. At that time, I did not think about my code structure in detail to catch up with the progress, which provided an opportunity for me to optimize the program.

The timer content introduced in the previous section shows that JavaScript isSingle thread. So

If the running efficiency of a piece of code is low, subsequent code execution will be affected.Therefore, code optimization is required for JavaScript.

First, let's take a look at the functions of our "marquee" plug-in:

It can control whether the lamp is automatically played, the rotation direction of the lamp can be controlled, the rotation speed of the lamp can be controlled, and the rotation speed of the prize can be controlled;

Here we will not detail the development process of these functional points, but will only introduce the optimization process. If you are interested, you can refer to the Source Code address appended to my article for download and reading.

1."Order"Get Optimization of revolving lamp code

Because I use absolute positioning to locate the lights around, I need to "order" them to get their list and then operate.

First, obtain the DOM node.

// Obtain the peripheral light. We can see that the selector I use here has a select option, which is used to obtain some elements under the current container and avoid conflict when multiple containers exist. topLight = $ ('[node-type = re-top]', select ). find ('span '); this. rightLight = $ ('[node-type = re-right]', select ). find ('span '); this. bottomLight = $ ('[node-type = re-bottom]', select ). find ('span '); this. leftLight = $ ('[node-type = re-left]', select ). find ('span ');

Then we should "sequentially" Get the DOM element list of the "lamp" node.

My first version does this:

Zepto(topLight).each(function() { lightList.push(this);});Zepto(rightLight).each(function() { lightList.push(this);});for (var j = bottomLight.length - 1; j >= 0; j--) { lightList.push(bottomLight[j]);}for (var m = leftLight.length - 1; m >= 0; m--) { lightList.push(leftLight[m]);}

Because the lights in the lower and left directions need to be in reverse order, I use two reverse for loops. In fact, when a loop appears, we should all think about whether our code has room for optimization.

The optimized code is like this. Here I have reduced the number of cycles.

function () { var lightList = []; var bottomRever; var leftRever; bottomRever = Array.from(this.bottomLight).reverse(); leftRever = Array.from(this.leftLight).reverse(); lightList = Array.from(this.topLight).concat(Array.from(this.rightLight)); lightList = lightList.concat(bottomRever); lightList = lightList.concat(leftRever); }

List in reverse order I use nativeArrayObjectreverseMethod.

2. Use closure to optimize sequential loop playback

In order to make our "Lights" run in sequence, the idea of the first version is:

ToEvery "lamp" (Note: Here is every sin... Sin ...)DefinesetTimeout(), The execution time is to add the data in the js execution queue in the order of numbers.

The Code is as follows:

 var zepto_light = Zepto(lightList); var changeTime = 100; var lightLength = zepto_light.length; var totleTime = changeTime * lightLength; function lightOpen() { for (var i = 0; i < lightLength; i++) { (function temp(i) { lightTimer = setTimeout(function() { if (stopAnimation === false) { Zepto(zepto_light).removeClass('light_open'); Zepto(zepto_light[i]).addClass("light_open"); } else { return; } }, changeTime * i); })(i); } }

The disadvantages of writing in this way are obvious:If I have 100 "Lights", 100 will be added to the current js execution queuesetTimeout()Again, I used it again.forLoop increases in time complexity. The code execution efficiency is reduced.

Later I thought about how to use the closure in JavaScript to optimize it. The code after optimization is as follows:

LightRun: function () {var _ this = this; function tempFunc () {var lightList = _ this. getLightList (); var lightLength = lightList. length; var I = 0; return function () {$ (lightList, _ this. lightArea ). removeClass ('light _ open'); $ (lightList [I], _ this. lightArea ). addClass ("light_open"); I ++; // enables the next loop to continue after the end of a loop if (I = lightLength) {I = 0 ;}};} var lightRunFunc = tempFunc (); lightRunFunc (); _ this. lightInterVal = setInterval (lightRunFunc, _ this. setting. roLiSpeed );}

The above code can clearly discover two advantages:First, it is reduced.forThe use of loops reduces the time complexity of the Code. The second is that each time I createsetInterval(). This reduces the complexity of the execution queue.

Here, the code parsing details and optimization of the "marquee" plug-in are complete. For detailed code and usage documents, click the link. If you have any questions, please feel free to send me feedback on github.

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.