Digital time-limited growth effect achieved: numbergrow.js

Source: Internet
Author: User
Tags setinterval

This is a function written last week, the approximate effect is that there are several numbers on the page, the statistics of some of the company's business information, the need for the first time, to do a start from 0 to grow, about 2 seconds automatically grow to the real value, and stop the effect of growth. The focus of this issue is to resolve how to ensure that numbers of different sizes are automatically increased over a period of 2 seconds, as well as the processing of deferred initialization considerations. This is to ensure that only when the number first enters the viewable area of the browser, you will see the effect, because these numbers may not be in the content of the first screen, you must ensure that the user scrolling operation will show the number of the moment to see the effect. This article shares my own idea of implementation, if you have a better way, welcome to the guidance and correction:)

Demo Address:

Http://liuyunzhuge.github.io/blog/numerGrow/dist/html/demo.html

Code Address:

Https://github.com/liuyunzhuge/blog/tree/master/numerGrow

The code run instructions are shown in the Git project readme.md.

1. Realization of Ideas

First look at how to ensure that the size of the different numbers in the specified time can be increased to complete.

This problem can be analogous to some of the previous physics lesson knowledge, is the speed distance and time relationship. In this problem, the final number size represents the distance, and the value of each digit growth in the unit time represents the speed. Because the distance is different, the time to go is the same, so the growth rate of each number will not be the same. To solve this problem, only the speed is required, because time and distance are known.

But in physics, the basic unit of speed is in seconds or hours of units, such as 3m/s,30km/h, in the program is obviously not in seconds or hours, because these units are too large, and to solve our problem, it is obvious to use the timer, the unit of the timer is milliseconds, so at the time of calculation speed , you want to use MS as the unit. For example, if the value to be displayed is 100, the specified time is 2s, that is 2000ms, then the value to be increased per MS is 100/2000, according to this assumption, can be derived from the following program implementation:

functionNumbergrow (element, options) {Options= Options | | {}; var$ This=$ (Element), time= Options.time | | $ This. Data (' time '),//Total Timenum = Options.num | | $ This. Data (' value '),//the true value to displayStep = num/(time * 1000),//Value Added per 1msStart = 0,//counterInterval//TimerOld = 0; //step for each 1ms value addedinterval= SetInterval (function() {Start= Start +step; if(Start >=num)            {clearinterval (interval); Interval=undefined; Start=num; }        vart =Math.floor (start); //if the T has not changed, return directly        //avoid invoking the text function to improve DOM performance        if(T = =Old ) {            return; } Old=T; $ This. Text (old); }, 1);}

Although this implementation is theoretically feasible, but the actual operation, it will be found that the effect of the increase will be far more than the specified time, the reason may be that the function in the setinterval is also time-consuming, and not necessarily in the interval of the timer to complete, Therefore, these additional execution times are cumulative over each execution interval and exceed the specified time. To solve this problem, I came up with an article that mentions the frame rate problem:

Http://www.ruanyifeng.com/blog/2015/09/web-page-performance-in-depth.html

If the page animation can be 60 frames per second, it will be synchronized with the monitor refresh, to achieve the best visual effect. This means that 60 re-renders within one second and no more than 16.66 milliseconds per re-render.

We can consider each execution of setinterval as a frame, and then change the execution interval of the setinterval to 16, as long as its callback function execution time is not more than 16ms, then this timer cumulative run time is only related to the interval time, It has nothing to do with the execution time of the callback function, because the callback function is executed within the callback interval! This is the key to solving the previous problem:

1) Change the timer interval to 16ms

2) Change the speed from the value added per MS to the value added per 16ms

The final correct implementation is as follows (the corresponding code is https://github.com/liuyunzhuge/blog/blob/master/numerGrow/src/js/mod/numberGrow.js):

functionNumbergrow (element, options) {Options= Options | | {}; var$ This=$ (Element), time= Options.time | | $ This. Data (' time '),//Total Timenum = Options.num | | $ This. Data (' value '),//the true value to displayStep = num * (TIME * 1000),//Value Added per 16msStart = 0,//counterInterval//TimerOld = 0; //no more than 16ms per frame, so the ideal interval interval is 16ms    //step for each 16ms value addedinterval= SetInterval (function() {Start= Start +step; if(Start >=num)            {clearinterval (interval); Interval=undefined; Start=num; }        vart =Math.floor (start); //if the T has not changed, return directly        //avoid invoking the text function to improve DOM performance        if(T = =Old ) {            return; } Old=T; $ This. Text (old); }, 16);}

Based on this implementation to test, you will find that the final result of the operation and the specified time only dozens of MS difference, basically has reached our requirements. This dozens of millisecond gap, I think from the browser for the management of setinterval, if you want to be very accurate in the specified time to complete this effect, I have not thought of a good way, I hope that the idea of friends willing to share.

In fact, the interval of the timer is not 16, with 8, 9, 10, 18, 20, 24 also can, the effect is similar to 16, because the timer callback function execution in the browser normal situation certainly does not need 8ms, inside nothing to do ... The difference between 8, 9, 10, 18, 20, 24, or 16 is that the speed of the number change looks different, the smaller the interval, the faster the interval changes, the slower the change, and the more visual experience. Use 16 because it is closer to the value of 16.66ms.

The above section is about how to ensure that the size of the different numbers can grow within the specified time to complete the instructions, below to see how to do the lazy loading when scrolling.

My thinking is relatively simple, with the help of scrolling events, listening to whether each element fully into the browser's viewable area, only when it is completely in the browser viewable area of the initialization, and only once, when a type of components are all initialized, will also do a destroy processing, To provide page performance.

This part of the implementation of the corresponding code is: Https://github.com/liuyunzhuge/blog/blob/master/numerGrow/src/js/mod/scrollLazyInit.js.

There are a few key points that can be explained in the blog:

1) Options

Scrolllazyinit provides two option, an NS, that represents the namespace, which is used to register the scroll event, because this component may not be used by only Numbergrow, and other time-consuming components of the page can use this component to do a simple lazy start, With this NS you can manage different components, and a delay is the interval between rolling callback throttling, which is not normally used.

When using Scrolllazyinit, it must be instantiated before it can be used, and the NS and delay parameters are passed when instantiated:

2) Add method

Each instance of the Srolllazy has two instance methods, one of which is the Add method, which is used to add functionality to the Scrolllazy to be managed by the deferred initialization:

The Add method has two parameters, the first is the DOM element to defer initialization, it is used to determine whether to fully enter the viewable area, and the second is the callback when the element fully enters the visual area, in which the component initialization is done, as shown in.

3) Start method

Another instance method for each Scrolllazy instance is start, which is actually adding a scrolling listener. After you add all the deferred initialization components, call this method again:

Because its implementation is not complex, but also does not belong to the focus of this article, originally this part of the function is in the Numbergrow, and then consider the separation of duties, only to write a separate component, the code only 60 lines, I believe your ability, certainly can directly see the source code.

It is also worth saying that this scrolllazy also has an optimization, that is, in judging the timing of the initialization of this piece, because it is now the judgment element completely into the visible area when the initialization, which for some highly small elements, no problem, but for the height may exceed the visible area of the element, Definitely not, so be aware of this point when using it.

2. Instructions for use

This function in use, you can directly through the Data property to register, because this effect of the function, basically no business logic, do not have to be placed in the business logic related to the JS inside, so as long as the HTML registration can:

The first data-ride= "Numbergrow" cannot be saved, because in Numbergrow.js, it is through this property to find the elements that need to be automatically registered. The value and time later represent the actual value to grow and the effective duration of the increase.

3. Summary of this paper

This article introduced oneself about a simple web page effect realization idea, because thinks that analogy physics in the speed time distance the point is more interesting, therefore shares it, hoped to have the reference value to you, thanks reads:

Digital time-limited growth effect achieved: numbergrow.js

Related Article

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.