Skip to content

Commit 0a46b29

Browse files
committed
Make readme much better and sources configurable
1 parent 976f78c commit 0a46b29

4 files changed

Lines changed: 348 additions & 108 deletions

File tree

README.md

Lines changed: 114 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,117 @@ pace
33

44
Automatic page load progress bar
55

6-
Include pace.js and pace.css on your page.
6+
Include pace.js and pace.css on your page (as early as is possible), and you're done!
7+
8+
If you use AMD or Browserify, require in pace.js and call `pace.start()` as early in
9+
the loading process as is possible.
10+
11+
Configuration
12+
-------------
13+
14+
Pace is fully automatic, no configuration is necessary. If you do need to make some tweaks, here's
15+
how:
16+
17+
You can set `Pace.options` before bringing in the file:
18+
19+
```javascript
20+
Pace = {
21+
options: {
22+
// Disable the 'elements' source
23+
elements: false
24+
}
25+
}
26+
```
27+
28+
You can also put options on the script tag:
29+
30+
```html
31+
<script data-pace-options='{ "ajax": false }' src='pace.js'></script>
32+
```
33+
34+
If you're using AMD or Browserify, you can pass your options to `start`:
35+
36+
```javascript
37+
define(['pace'], function(pace){
38+
pace.start({
39+
document: false
40+
});
41+
});
42+
```
43+
44+
Collectors
45+
----------
46+
47+
Pace includes four default collectors:
48+
49+
- Ajax
50+
51+
Monitors all ajax requests on the page
52+
53+
- Elements
54+
55+
Checks for the existance of specific elements on the page
56+
57+
- Document
58+
59+
Checks the document readyState
60+
61+
- EventLag
62+
63+
Checks for event loop lag signaling that javascript is being executed
64+
65+
They can each be configured or disabled through configuration options of the same name.
66+
67+
```javascript
68+
Pace = {
69+
options: {
70+
ajax: false, // disabled
71+
document: false, // disabled
72+
eventLag: false, // disabled
73+
elements: {
74+
sources: ['.my-page']
75+
}
76+
}
77+
}
78+
```
79+
80+
Add your own instances to `options.extraSources` to add more sources. Each source should either
81+
have a `.progress` property, or a `.elements` property which is a list of objects with
82+
`.progress` properties. Pace will automatically handle all scaling to make the progress
83+
changes look smooth to the user.
84+
85+
Restart Rules
86+
-------------
87+
88+
Most users want the progress bar to automatically restart when a pushState event occurs
89+
(generally means ajax navigation is occuring). You can disable this:
90+
91+
```javascript
92+
Pace = {
93+
options: {
94+
restartOnPushState: false
95+
}
96+
}
97+
```
98+
99+
You can always trigger a restart manually by calling `Pace.restart()`
100+
101+
See [the source](pace.coffee) for a full list of all options.
102+
103+
API
104+
---
105+
106+
Pace exposes the following methods:
107+
108+
- `Pace.start`
109+
110+
Show the progress bar and start updating. Called automatically if you don't use AMD or CommonJS.
111+
112+
- `Pace.restart`
113+
114+
Show the progress bar if it's hidden and start reporting the progress from scratch. Called automatically
115+
whenever `pushState` or `replaceState` is called by default.
116+
117+
- `Pace.stop`
118+
119+
Hide the progress bar and stop updating it.

pace.coffee

Lines changed: 53 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,6 @@ defaultOptions =
1515
# update before disappearing
1616
ghostTime: 250
1717

18-
# How frequently in ms should we check for the elements being tested for
19-
# using the element monitor?
20-
elementCheckInterval: 100
21-
2218
# Its easy for a bunch of the bar to be eaten in the first few frames
2319
# before we know how much there is to load. This limits how much of
2420
# the bar can be used per frame
@@ -27,6 +23,18 @@ defaultOptions =
2723
# This tweaks the animation easing
2824
easeFactor: 1.25
2925

26+
# Should we restart the browser when pushState or replaceState is called? (Generally
27+
# means ajax navigation has occured)
28+
restartOnPushState: true
29+
30+
elements:
31+
# How frequently in ms should we check for the elements being tested for
32+
# using the element monitor?
33+
checkInterval: 100
34+
35+
# What elements should we wait for before deciding the page is fully loaded (not required)
36+
selectors: ['body']
37+
3038
now = ->
3139
performance?.now?() ? +new Date
3240

@@ -62,7 +70,10 @@ result = (obj, key, args...) ->
6270
extend = (out, sources...) ->
6371
for source in sources when source
6472
for own key, val of source
65-
out[key] = val
73+
if out[key]? and typeof out[key] is 'object' and val? and typeof val is 'object'
74+
extend(out[key], val)
75+
else
76+
out[key] = val
6677
out
6778

6879
getOptionsFromDOM = ->
@@ -217,29 +228,28 @@ class RequestTracker
217228
_onreadystatechange?(arguments...)
218229

219230
class ElementMonitor
220-
constructor: (selectors...) ->
231+
constructor: (options={}) ->
221232
@elements = []
222233

223-
for set in selectors
224-
@elements.push new ElementTracker set
234+
options.selectors ?= []
235+
for selector in options.selectors
236+
@elements.push new ElementTracker selector
225237

226238
class ElementTracker
227-
constructor: (@selectors) ->
239+
constructor: (@selector) ->
228240
@progress = 0
229241

230-
if typeof @selectors is 'string'
231-
@selectors = [@selectors]
232-
233242
@check()
234243

235244
check: ->
236-
matches = document.querySelectorAll(@selectors.join(','))
237-
238-
if matches.length
239-
@progress = 100 * matches.length / @selectors.length
245+
if document.querySelector(@selector)
246+
@done()
240247
else
241248
setTimeout (=> @check()),
242-
options.elementCheckInterval
249+
options.elements.checkInterval
250+
251+
done: ->
252+
@progress = 100
243253

244254
class DocumentMonitor
245255
states:
@@ -316,10 +326,11 @@ class Scaler
316326
# know it's done.
317327
@progress += scaling * @rate * frameTime
318328

329+
@progress = Math.min(@lastProgress + options.maxProgressPerFrame, @progress)
330+
319331
@progress = Math.max(0, @progress)
320332
@progress = Math.min(100, @progress)
321333

322-
@progress = Math.min(@lastProgress + options.maxProgressPerFrame, @progress)
323334
@lastProgress = @progress
324335

325336
@progress
@@ -331,24 +342,38 @@ uniScaler = null
331342
animation = null
332343
cancelAnimation = null
333344

345+
handlePushState = ->
346+
if options.restartOnPushState
347+
Pace.restart()
348+
334349
# We reset the bar whenever it looks like an ajax navigation has occured.
335350
if window.pushState?
336351
_pushState = window.pushState
337352
window.pushState = ->
338-
handlePageChange()
353+
handlePushState()
339354

340355
_pushState arguments...
341356

342357
if window.replaceState?
343358
_replaceState = window.replaceState
344359
window.replaceState = ->
345-
handlePageChange()
360+
handlePushState()
346361

347362
_replaceState arguments...
348363

364+
SOURCE_KEYS =
365+
ajax: AjaxMonitor
366+
elements: ElementMonitor
367+
document: DocumentMonitor
368+
eventLag: EventLagMonitor
369+
349370
do init = ->
350-
sources = [new AjaxMonitor, new ElementMonitor('body'), new DocumentMonitor, new EventLagMonitor]
351-
371+
sources = options.extraSources ? []
372+
373+
for type in ['ajax', 'elements', 'document', 'eventLag']
374+
if options[type] isnt false
375+
sources.push new ELEMENT_KEYS[type](options[type])
376+
352377
bar = new Bar
353378

354379
# Each source of progress data has it's own scaler to smooth its output
@@ -358,7 +383,7 @@ do init = ->
358383
# remove sources
359384
uniScaler = new Scaler
360385

361-
Pace.reset = ->
386+
Pace.stop = ->
362387
bar.destroy()
363388

364389
# Not all browsers support cancelAnimationFrame
@@ -370,8 +395,8 @@ Pace.reset = ->
370395

371396
init()
372397

373-
handlePageChange = ->
374-
Pace.reset()
398+
Pace.restart = ->
399+
Pace.stop()
375400
Pace.go()
376401

377402
Page.go = ->
@@ -421,7 +446,9 @@ Page.go = ->
421446
else
422447
enqueueNextFrame()
423448

424-
Pace.start = ->
449+
Pace.start = (_options) ->
450+
extend options, _options
451+
425452
bar.render()
426453

427454
# It's usually possible to render a bit before the document declares itself ready

0 commit comments

Comments
 (0)