PageSourceSearch

https://che.ir/template/aroundv2/assets/plugins/jquery.simple.timer.js

js che.ir collected 2026-09-25 10:22:24 UTC 7,964 bytes, 269 lines download raw bytes

1/*
2* jQuery-Simple-Timer
3*
4* Creates a countdown timer.
5*
6* Example:
7*   $('.timer').startTimer();
8*
9*/
10
11(function (factory) {
12  // Using as a CommonJS module
13  if(typeof module === "object" && typeof module.exports === "object") {
14    // jQuery must be provided as argument when used
15    // as a CommonJS module.
16    //
17    // For example:
18    //   let $ = require("jquery");
19    //   require("jquery-simple-timer")($);
20    module.exports = function(jq) {
21      factory(jq, window, document);
22    }
23  } else {
24    // Using as script tag
25    //
26    // For example:
27    //   <script src="jquery.simple.timer.js"></script>
28    factory(jQuery, window, document);
29  }
30}(function($, window, document, undefined) {
31
32  // Polyfill new JS features for older browser
33  Number.isFinite = Number.isFinite || function(value) {
34    return typeof value === 'number' && isFinite(value);
35  }
36
37  var timer;
38
39  var Timer = function(targetElement){
40    this._options = {};
41    this.targetElement = targetElement;
42    return this;
43  };
44
45  Timer.start = function(userOptions, targetElement){
46    timer = new Timer(targetElement);
47    mergeOptions(timer, userOptions);
48    return timer.start(userOptions);
49  };
50
51  // Writes to `this._options` object so that other
52  // functions can access it without having to
53  // pass this object as argument multiple times.
54  function mergeOptions(timer, opts) {
55    opts = opts || {};
56
57    // Element that will be created for hours, minutes, and seconds.
58    timer._options.elementContainer = opts.elementContainer || 'div';
59
60    var classNames = opts.classNames || {};
61
62    timer._options.classNameSeconds       = classNames.seconds  || 'jst-seconds'
63      , timer._options.classNameMinutes   = classNames.minutes  || 'jst-minutes'
64      , timer._options.classNameHours     = classNames.hours    || 'jst-hours'
65      , timer._options.classNameClearDiv  = classNames.clearDiv || 'jst-clearDiv'
66      , timer._options.classNameTimeout   = classNames.timeout || 'jst-timeout';
67  }
68
69  Timer.prototype.start = function(options) {
70
71    var that = this;
72
73    var createSubElements = function(timerBoxElement){
74      var seconds = document.createElement(that._options.elementContainer);
75      seconds.className = that._options.classNameSeconds;
76
77      var minutes = document.createElement(that._options.elementContainer);
78      minutes.className = that._options.classNameMinutes;
79
80      var hours = document.createElement(that._options.elementContainer);
81      hours.className = that._options.classNameHours;
82
83      var clearElement = document.createElement(that._options.elementContainer);
84      clearElement.className = that._options.classNameClearDiv;
85
86      return timerBoxElement.
87        append(hours).
88        append(minutes).
89        append(seconds).
90        append(clearElement);
91    };
92
93    this.targetElement.each(function(_index, timerBox) {
94      var that = this;
95      var timerBoxElement = $(timerBox);
96      var cssClassSnapshot = timerBoxElement.attr('class');
97
98      timerBoxElement.on('complete', function() {
99        clearInterval(timerBoxElement.intervalId);
100      });
101
102      timerBoxElement.on('complete', function() {
103        timerBoxElement.onComplete(timerBoxElement);
104      });
105
106      timerBoxElement.on('complete', function(){
107        timerBoxElement.addClass(that._options.classNameTimeout);
108      });
109
110      timerBoxElement.on('complete', function(){
111        if(options && options.loop === true) {
112          timer.resetTimer(timerBoxElement, options, cssClassSnapshot);
113        }
114      });
115
116      timerBoxElement.on('pause', function() {
117        clearInterval(timerBoxElement.intervalId);
118        timerBoxElement.paused = true;
119      });
120
121      timerBoxElement.on('resume', function() {
122        timerBoxElement.paused = false;
123        const secondsLeft = timerBoxElement.data('timeLeft');
124        const onComplete = timerBoxElement.onComplete;
125        that.startCountdown(timerBoxElement, { secondsLeft, onComplete });
126      });
127
128      createSubElements(timerBoxElement);
129      return this.startCountdown(timerBoxElement, options);
130    }.bind(this));
131  };
132
133  /**
134   * Resets timer and add css class 'loop' to indicate the timer is in a loop.
135   * $timerBox {jQuery object} - The timer element
136   * options {object} - The options for the timer
137   * css - The original css of the element
138   */
139  Timer.prototype.resetTimer = function($timerBox, options, css) {
140    var interval = 0;
141    if(options.loopInterval) {
142      interval = parseInt(options.loopInterval, 10) * 1000;
143    }
144    setTimeout(function() {
145      $timerBox.trigger('reset');
146      $timerBox.attr('class', css + ' loop');
147      timer.startCountdown($timerBox, options);
148    }, interval);
149  }
150
151  Timer.prototype.fetchSecondsLeft = function(element){
152    var secondsLeft = element.data('seconds-left');
153    var minutesLeft = element.data('minutes-left');
154
155    if(Number.isFinite(secondsLeft)){
156      return parseInt(secondsLeft, 10);
157    } else if(Number.isFinite(minutesLeft)) {
158      return parseFloat(minutesLeft) * 60;
159    }else {
160      throw 'Missing time data';
161    }
162  };
163
164  Timer.prototype.startCountdown = function(element, options) {
165    options = options || {};
166
167    var intervalId = null;
168    var defaultComplete = function(){
169      clearInterval(intervalId);
170      return this.clearTimer(element);
171    }.bind(this);
172
173    element.onComplete = options.onComplete || defaultComplete;
174    element.allowPause = options.allowPause || false;
175    if(element.allowPause){
176      element.on('click', function() {
177        if(element.paused){
178          element.trigger('resume');
179        }else{
180          element.trigger('pause');
181        }
182      });
183    }
184
185    var secondsLeft = options.secondsLeft || this.fetchSecondsLeft(element);
186
187    var refreshRate = options.refreshRate || 1000;
188    var endTime = secondsLeft + this.currentTime();
189    var timeLeft = endTime - this.currentTime();
190
191    this.setFinalValue(this.formatTimeLeft(timeLeft), element);
192
193    intervalId = setInterval((function() {
194      timeLeft = endTime - this.currentTime();
195      // When timer has been idle and only resumed past timeout,
196      // then we immediatelly complete the timer.
197      if(timeLeft < 0 ){
198        timeLeft = 0;
199      }
200      element.data('timeLeft', timeLeft);
201      this.setFinalValue(this.formatTimeLeft(timeLeft), element);
202    }.bind(this)), refreshRate);
203
204    element.intervalId = intervalId;
205  };
206
207  Timer.prototype.clearTimer = function(element){
208    element.find('.jst-seconds').text('00');
209    element.find('.jst-minutes').text('00:');
210    element.find('.jst-hours').text('00:');
211  };
212
213  Timer.prototype.currentTime = function() {
214    return Math.round((new Date()).getTime() / 1000);
215  };
216
217  Timer.prototype.formatTimeLeft = function(timeLeft) {
218
219    var lpad = function(n, width) {
220      width = width || 2;
221      n = n + '';
222
223      var padded = null;
224
225      if (n.length >= width) {
226        padded = n;
227      } else {
228        padded = Array(width - n.length + 1).join(0) + n;
229      }
230
231      return padded;
232    };
233
234    var hours = Math.floor(timeLeft / 3600);
235    timeLeft -= hours * 3600;
236
237    var minutes = Math.floor(timeLeft / 60);
238    timeLeft -= minutes * 60;
239
240    var seconds = parseInt(timeLeft % 60, 10);
241
242    if (+hours === 0 && +minutes === 0 && +seconds === 0) {
243      return [];
244    } else {
245      return [lpad(hours), lpad(minutes), lpad(seconds)];
246    }
247  };
248
249  Timer.prototype.setFinalValue = function(finalValues, element) {
250
251    if(finalValues.length === 0){
252      this.clearTimer(element);
253      element.trigger('complete');
254      return false;
255    }
256
257    element.find('.' + this._options.classNameSeconds).text(finalValues.pop());
258    element.find('.' + this._options.classNameMinutes).text(finalValues.pop() + ':');
259    element.find('.' + this._options.classNameHours).text(finalValues.pop() + ':');
260  };
261
262
263  $.fn.startTimer = function(options) {
264    this.TimerObject = Timer;
265    Timer.start(options, this);
266    return this;
267  };
268
269}));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.