@glitchr/stickyjs 1.2.1 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Sticky JS library
2
2
 
3
+ ## The address follows the reading
4
+
5
+ With `replacehash` on (the default), the page's address carries the `#id` of
6
+ the headline being read: `.sticky-headlines[id]`, any `[id]` inside a
7
+ `.sticky-headlines`, or a `.sticky-magnet[id]` (`.sticky-headlines-skip` left
8
+ out). A headline is being read once it has reached where its own link would
9
+ land it - the scroller's `scroll-padding-top` plus the headline's
10
+ `scroll-margin-top` - and until it has scrolled out of sight. At the top, with
11
+ none reached, the address has no hash. The change is a `history.replaceState`:
12
+ it adds nothing to the history.
13
+
14
+ ```html
15
+ <section id="menus" class="sticky-headlines" style="scroll-margin-top: 4rem">…</section>
16
+ ```
17
+
3
18
  ## Scroll stops
4
19
 
5
20
  `src/js/stops.js` - places on the page a scroll settles on, once it has come
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glitchr/stickyjs",
3
- "version": "1.2.1",
3
+ "version": "1.2.2",
4
4
  "description": "Sticky scroll library",
5
5
  "main": "src/index.js",
6
6
  "repository": {
package/src/js/sticky.js CHANGED
@@ -1173,7 +1173,13 @@ $.fn.serializeObject = function () {
1173
1173
 
1174
1174
  var elAll = $(ids).filter(function() {
1175
1175
  if(this === $(Settings.identifier)) return false;
1176
- return this.getBoundingClientRect().top < scrollPaddingTop;
1176
+ // Reached where an anchor jump would land it: the scroller's
1177
+ // scroll-padding-top plus the headline's own scroll-margin-top
1178
+ // (a section that lands under a fixed header, a band lower
1179
+ // than the rest). Without the margin, a headline landed on
1180
+ // by its own link was not the current one yet.
1181
+ var margin = parseFloat(getComputedStyle(this).scrollMarginTop) || 0;
1182
+ return this.getBoundingClientRect().top - margin < scrollPaddingTop;
1177
1183
  }).toArray().sort(function (el1, el2) {
1178
1184
  return el1.offsetTop > el2.offsetTop ? -1
1179
1185
  : (el1.offsetTop < el2.offsetTop ? 1 : 0);
package/src/js/stops.js CHANGED
@@ -19,7 +19,8 @@
19
19
  //
20
20
  // A band never reaches past halfway to the neighbouring stop, so every stop
21
21
  // stays reachable however the bands are set. Two stops at the same place are
22
- // one stop.
22
+ // one stop. A stop past the end of the scroll (a footer shorter than the
23
+ // screen) is at the end of the scroll.
23
24
  //
24
25
  // Nothing happens during the scroll. Acting at the first movement fights
25
26
  // trackpad momentum, which keeps pushing during and after the glide; and the
@@ -178,6 +179,13 @@
178
179
  return this.isWindow ? (window.scrollY || window.pageYOffset || 0) : this.scroller.scrollTop;
179
180
  };
180
181
 
182
+ /** The furthest the scroller can scroll. */
183
+ Stops.prototype.max = function () {
184
+ return Math.max(0, this.isWindow
185
+ ? document.documentElement.scrollHeight - window.innerHeight
186
+ : this.scroller.scrollHeight - this.scroller.clientHeight);
187
+ };
188
+
181
189
  /** The scroller's scroll-padding-top: where a stop should rest below its edge. */
182
190
  Stops.prototype.padding = function () {
183
191
  var value = parseFloat(getComputedStyle(this.root).scrollPaddingTop);
@@ -193,6 +201,7 @@
193
201
  Stops.prototype.measure = function () {
194
202
  var options = this.options;
195
203
  var elements = this.root.querySelectorAll(options.selector);
204
+ var max = this.max();
196
205
  var stops = [];
197
206
  var i;
198
207
 
@@ -201,7 +210,11 @@
201
210
  if (!el.getClientRects().length) continue; // display: none
202
211
  stops.push({
203
212
  element: el,
204
- top: Math.round(this.position(el)),
213
+ // A stop the scroll cannot bring to the top (a footer shorter
214
+ // than the screen) rests where the scroll ends. Taken as out
215
+ // of reach, it made every scroll up from the very bottom -
216
+ // Safari's bounce included - glide away to the stop above.
217
+ top: Math.min(Math.round(this.position(el)), max),
205
218
  bandUp: Math.max(0, toPixels(el.dataset.stickyBandUp, el, options.bandUp)),
206
219
  bandDown: Math.max(0, toPixels(el.dataset.stickyBandDown, el, options.bandDown))
207
220
  });