@glitchr/stickyjs 1.0.19 → 1.0.21

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/js/sticky.js +278 -162
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glitchr/stickyjs",
3
- "version": "1.0.19",
3
+ "version": "1.0.21",
4
4
  "description": "Sticky scroll library",
5
5
  "main": "src/index.js",
6
6
  "repository": {
package/src/js/sticky.js CHANGED
@@ -12,8 +12,8 @@
12
12
  var fallback = $(newHash).length === 0;
13
13
 
14
14
  var hashElement = $(newHash)[0] ?? undefined;
15
- if (hashElement !== undefined) // Update hash only if element is displayed
16
- fallback |= window.getComputedStyle(hashElement)["display"] == "none";
15
+ // if (hashElement !== undefined) // Update hash only if element is displayed
16
+ // fallback |= window.getComputedStyle(hashElement)["display"] == "none";
17
17
 
18
18
  if((skipIfEmptyIdentifier && !newHash) || fallback){
19
19
 
@@ -196,7 +196,7 @@ $.fn.serializeObject = function () {
196
196
  "scrollcatch": false,
197
197
  "scrolllock" : true,
198
198
  "scrollhide" : true,
199
- "scrollhint" : 0.5,
199
+ "scrollhint" : 0.25,
200
200
 
201
201
  //
202
202
  // Manual overscroll detection (browser compatibility, e.g. scroll event missing with Firefox)
@@ -207,6 +207,8 @@ $.fn.serializeObject = function () {
207
207
  "right":false ,
208
208
  },
209
209
 
210
+ "scrollpercent" : true ,
211
+
210
212
  "scrollsnap" : true ,
211
213
  "scrollsnap_start" : "start", //start, center, end
212
214
  "scrollsnap_proximity" : 0.01 ,
@@ -249,12 +251,12 @@ $.fn.serializeObject = function () {
249
251
  Sticky.parseDuration = function(str) {
250
252
 
251
253
  var array = String(str).split(", ");
252
- array = array.map(function(t) {
254
+ array = array.map(function(t) {
253
255
 
254
- if(String(t).endsWith("ms")) return parseFloat(String(t))/1000;
256
+ if(String(t).endsWith("ms")) return parseFloat(String(t))/1000;
255
257
 
256
- return parseFloat(String(t));
257
- });
258
+ return parseFloat(String(t));
259
+ });
258
260
 
259
261
  return Math.max(...array);
260
262
  }
@@ -267,13 +269,13 @@ $.fn.serializeObject = function () {
267
269
  if(str === undefined) return undefined;
268
270
 
269
271
  var array = String(str).split(", ");
270
- array = array.map(function(s) {
272
+ array = array.map(function(s) {
271
273
 
272
- if(s.endsWith("rem")) return Sticky.remToPixel (s);
273
- else if(s.endsWith("em") ) return Sticky.emToPixel (s, el);
274
- else if(s.endsWith("%") ) return Sticky.percentToPixel(s, el);
275
- return parseFloat(s);
276
- });
274
+ if(s.endsWith("rem")) return Sticky.remToPixel (s);
275
+ else if(s.endsWith("em") ) return Sticky.emToPixel (s, el);
276
+ else if(s.endsWith("%") ) return Sticky.percentToPixel(s, el);
277
+ return parseFloat(s);
278
+ });
277
279
 
278
280
  return Math.max(...array);
279
281
  }
@@ -281,13 +283,13 @@ $.fn.serializeObject = function () {
281
283
  Sticky.getScrollPadding = function(el = document.documentElement) {
282
284
 
283
285
  var scroller = $(el).closestScrollable()[0];
284
- var style = window.getComputedStyle(scroller);
286
+ var style = scroller instanceof Element ? window.getComputedStyle(scroller) : {};
285
287
 
286
288
  var dict = {};
287
- dict["top" ] = Sticky.parseToPixel(style["scroll-padding-top" ] || 0, scroller);
288
- dict["left" ] = Sticky.parseToPixel(style["scroll-padding-left" ] || 0, scroller);
289
- dict["right" ] = Sticky.parseToPixel(style["scroll-padding-right" ] || 0, scroller);
290
- dict["bottom"] = Sticky.parseToPixel(style["scroll-padding-bottom"] || 0, scroller);
289
+ dict["top" ] = Sticky.parseToPixel(style["scroll-padding-top" ] || 0, scroller);
290
+ dict["left" ] = Sticky.parseToPixel(style["scroll-padding-left" ] || 0, scroller);
291
+ dict["right" ] = Sticky.parseToPixel(style["scroll-padding-right" ] || 0, scroller);
292
+ dict["bottom"] = Sticky.parseToPixel(style["scroll-padding-bottom"] || 0, scroller);
291
293
 
292
294
  if(isNaN(dict["top" ])) dict["top"] = 0;
293
295
  if(isNaN(dict["left" ])) dict["left"] = 0;
@@ -303,8 +305,8 @@ $.fn.serializeObject = function () {
303
305
  el = el === window ? document.documentElement : el;
304
306
  el = $(el).length ? $(el)[0] : undefined;
305
307
 
306
- var targetData = jQuery.data(el || document.documentElement);
307
- Object.keys(targetData).forEach((key) => delete targetData[key]);
308
+ var data = jQuery.data(el || document.documentElement);
309
+ Object.keys(data).forEach((key) => delete data[key]);
308
310
 
309
311
  return this;
310
312
  }
@@ -396,6 +398,8 @@ $.fn.serializeObject = function () {
396
398
  return this;
397
399
  }
398
400
 
401
+ var previousData = {};
402
+ var previousDataTimestamp = undefined;
399
403
  Sticky.compute = function(event) {
400
404
 
401
405
  if (event.target === undefined )
@@ -412,29 +416,36 @@ $.fn.serializeObject = function () {
412
416
  if ($(event.target).prop("user-scroll") === undefined)
413
417
  $(event.target).prop("user-scroll", true);
414
418
 
415
- var targetData = jQuery.data(event.target);
416
- var first = (Object.keys(targetData).length === 0);
419
+ var target = event.target[0];
420
+ var targetData = jQuery.data(target);
421
+ if (previousDataTimestamp != event.timeStamp) {
422
+ previousData[target] = Object.assign({}, targetData);
423
+ previousDataTimestamp = event.timeStamp;
424
+ }
417
425
 
418
- var top = targetData.top || 0;
419
- var left = targetData.left || 0;
420
- var bottom = targetData.bottom || 0;
421
- var right = targetData.right || 0;
426
+ var first = (Object.keys(targetData).length === 0);
427
+ var top = targetData.scrollableY ? previousData[target].top : 0;
428
+ var left = targetData.scrollableX ? previousData[target].left : 0;
429
+ var bottom = targetData.scrollableY ? previousData[target].bottom : 0;
430
+ var right = targetData.scrollableX ? previousData[target].right : 0;
422
431
 
423
432
  // Screen & viewport positioning
424
433
  targetData.first = first;
425
434
  targetData.elastic = targetData.elastic || false;
426
435
  targetData.vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);
427
436
  targetData.vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0);
428
- targetData.sw = event.target[0].scrollWidth || 0;
429
- targetData.sh = event.target[0].scrollHeight || 0;
430
- targetData.width = event.target[0].clientWidth || 0;
431
- targetData.height = event.target[0].clientHeight || 0;
437
+ targetData.sw = target.scrollWidth || 0;
438
+ targetData.sh = target.scrollHeight || 0;
439
+ targetData.width = target.clientWidth || 0;
440
+ targetData.height = target.clientHeight || 0;
441
+ targetData.scrollableX = target.scrollWidth > target.clientWidth;
442
+ targetData.scrollableY = target.scrollHeight > target.clientHeight;
432
443
 
433
444
  // Scrolling information
434
- targetData.top = event.target.scrollTop();
435
- targetData.bottom = Math.round(targetData.sh - event.target.scrollTop() - targetData.height);
436
- targetData.left = event.target.scrollLeft();
437
- targetData.right = Math.round(targetData.sw - event.target.scrollLeft() - targetData.width);
445
+ targetData.top = targetData.scrollableY ? event.target.scrollTop() : 0;
446
+ targetData.bottom = targetData.scrollableY ? Math.round(targetData.sh - event.target.scrollTop() - targetData.height) : 0;
447
+ targetData.left = targetData.scrollableX ? event.target.scrollLeft() : 0;
448
+ targetData.right = targetData.scrollableX ? Math.round(targetData.sw - event.target.scrollLeft() - targetData.width) : 0;
438
449
 
439
450
  if(first) {
440
451
 
@@ -460,25 +471,25 @@ $.fn.serializeObject = function () {
460
471
  if (targetData.right == 0 && targetData.right < right)
461
472
  targetData.rightCounter = (targetData.right == 0 && right > 0 ? targetData.rightCounter + 1 : targetData.rightCounter ) || 0;
462
473
 
463
- targetData.bottomElastic = targetData.bottom < 0;
474
+ targetData.bottomElastic = targetData.bottom < 0 && targetData.scrollableY;
464
475
  if(Sticky.get("overscroll").bottom) {
465
476
  targetData.bottomElastic = true;
466
477
  targetData.bottom = -1;
467
478
  }
468
479
 
469
- targetData.topElastic = targetData.top < 0;
480
+ targetData.topElastic = targetData.top < 0 && targetData.scrollableY;
470
481
  if(Sticky.get("overscroll").top) {
471
482
  targetData.topElastic = true;
472
483
  targetData.top = -1;
473
484
  }
474
485
 
475
- targetData.leftElastic = targetData.left < 0;
486
+ targetData.leftElastic = targetData.left < 0 && targetData.scrollableX;
476
487
  if(Sticky.get("overscroll").left) {
477
488
  targetData.leftElastic = true;
478
489
  targetData.left = -1;
479
490
  }
480
491
 
481
- targetData.rightElastic = targetData.right < 0;
492
+ targetData.rightElastic = targetData.right < 0 && targetData.scrollableX;
482
493
  if(Sticky.get("overscroll").right) {
483
494
  targetData.rightElastic = true;
484
495
  targetData.right = -1;
@@ -488,47 +499,62 @@ $.fn.serializeObject = function () {
488
499
 
489
500
  // Timing information
490
501
  if (targetData.time0 === undefined || !targetData.elastic || targetData.first) {
502
+ previousData[target].time0 = {};
503
+ previousData[target].time = {};
491
504
  targetData.time0 = {};
492
505
  targetData.time = {};
493
506
  }
494
507
 
495
508
  if(!targetData.topElastic ) {
509
+ previousData[target].time0.top = null;
510
+ previousData[target].time .top = null;
496
511
  targetData.time0.top = null;
497
512
  targetData.time .top = null;
498
513
  }
499
514
 
500
515
  if(!targetData.bottomElastic) {
516
+ previousData[target].time0.bottom = null;
517
+ previousData[target].time .bottom = null;
501
518
  targetData.time0.bottom = null;
502
519
  targetData.time .bottom = null;
503
520
  }
504
521
 
505
522
  if(!targetData.leftElastic ) {
523
+ previousData[target].time0.left = null;
524
+ previousData[target].time .left = null;
506
525
  targetData.time0.left = null;
507
526
  targetData.time .left = null;
508
527
  }
509
528
 
510
529
  if(!targetData.rightElastic ) {
530
+ previousData[target].time0.right = null;
531
+ previousData[target].time .right = null;
511
532
  targetData.time0.right = null;
512
533
  targetData.time .right = null;
513
534
  }
514
535
 
515
- if(targetData.topElastic ) targetData.time0.top = targetData.time0.top || new Date().getTime();
516
- if(targetData.bottomElastic) targetData.time0.bottom = targetData.time0.bottom || new Date().getTime();
517
- if(targetData.leftElastic ) targetData.time0.left = targetData.time0.left || new Date().getTime();
518
- if(targetData.rightElastic ) targetData.time0.right = targetData.time0.right || new Date().getTime();
536
+ if(targetData.topElastic ) previousData[target].time0.top = previousData[target].time0.top ?? new Date().getTime();
537
+ if(targetData.bottomElastic) previousData[target].time0.bottom = previousData[target].time0.bottom ?? new Date().getTime();
538
+ if(targetData.leftElastic ) previousData[target].time0.left = previousData[target].time0.left ?? new Date().getTime();
539
+ if(targetData.rightElastic ) previousData[target].time0.right = previousData[target].time0.right ?? new Date().getTime();
540
+
541
+ if(targetData.topElastic ) targetData.time0.top = previousData[target].time0.top ;
542
+ if(targetData.bottomElastic) targetData.time0.bottom = previousData[target].time0.bottom;
543
+ if(targetData.leftElastic ) targetData.time0.left = previousData[target].time0.left ;
544
+ if(targetData.rightElastic ) targetData.time0.right = previousData[target].time0.right ;
519
545
 
520
546
  if(targetData.topElastic ) targetData.time.top = new Date().getTime();
521
547
  if(targetData.bottomElastic) targetData.time.bottom = new Date().getTime();
522
548
  if(targetData.leftElastic ) targetData.time.left = new Date().getTime();
523
549
  if(targetData.rightElastic ) targetData.time.right = new Date().getTime();
524
550
 
525
- var dX = targetData.left - left;
526
- var dY = targetData.top - top;
551
+ var dX = targetData.scrollableX ? targetData.left - left : 0;
552
+ var dY = targetData.scrollableY ? targetData.top - top : 0;
527
553
  var dT = {
528
- top: Math.abs(targetData.time0.top - targetData.time.top),
529
- bottom: Math.abs(targetData.time0.bottom - targetData.time.bottom),
530
- left: Math.abs(targetData.time0.left - targetData.time.left),
531
- right: Math.abs(targetData.time0.right - targetData.time.right)
554
+ top: Math.abs(targetData.time.top - targetData.time0.top ),
555
+ bottom: Math.abs(targetData.time.bottom - targetData.time0.bottom),
556
+ left: Math.abs(targetData.time.left - targetData.time0.left ),
557
+ right: Math.abs(targetData.time.right - targetData.time0.right )
532
558
  };
533
559
 
534
560
  // Event summary information
@@ -561,6 +587,8 @@ $.fn.serializeObject = function () {
561
587
 
562
588
  event.scrollX = {
563
589
  "delta" : dX,
590
+ "percent" : Math.round(100 * target.scrollLeft / (target.scrollWidth-target.clientWidth)),
591
+ "direction" : targetData.scrollableX ? (dX > 0 ? "right" : (dX < 0 ? "left" : undefined)) : undefined,
564
592
  "left" : targetData.left,
565
593
  "leftCounter" : targetData.leftCounter,
566
594
  "leftElastic" : targetData.leftElastic,
@@ -571,6 +599,8 @@ $.fn.serializeObject = function () {
571
599
 
572
600
  event.scrollY = {
573
601
  "delta" : dY,
602
+ "percent" : Math.round(100 * target.scrollTop / (target.scrollHeight-target.clientHeight)),
603
+ "direction" : targetData.scrollableY ? dY > 0 ? "down" : (dY < 0 ? "up" : undefined) : undefined,
574
604
  "top" : targetData.top,
575
605
  "topCounter" : targetData.topCounter,
576
606
  "topElastic" : targetData.topElastic,
@@ -785,9 +815,9 @@ $.fn.serializeObject = function () {
785
815
  // modern Chrome requires { passive: false } when adding event
786
816
  var supportsPassive = false;
787
817
  try {
788
- window.addEventListener("test", null, Object.defineProperty({}, 'passive', {
789
- get: function () { supportsPassive = true; }
790
- }));
818
+ window.addEventListener("test", null, Object.defineProperty({}, 'passive', {
819
+ get: function () { supportsPassive = true; }
820
+ }));
791
821
  } catch(e) {}
792
822
 
793
823
  var wheelOpt = supportsPassive ? { passive: false } : false;
@@ -817,9 +847,9 @@ $.fn.serializeObject = function () {
817
847
  // modern Chrome requires { passive: false } when adding event
818
848
  var supportsPassive = false;
819
849
  try {
820
- window.addEventListener("test", null, Object.defineProperty({}, 'passive', {
821
- get: function () { supportsPassive = true; }
822
- }));
850
+ window.addEventListener("test", null, Object.defineProperty({}, 'passive', {
851
+ get: function () { supportsPassive = true; }
852
+ }));
823
853
  } catch(e) {}
824
854
 
825
855
  var wheelOpt = supportsPassive ? { passive: false } : false;
@@ -842,6 +872,64 @@ $.fn.serializeObject = function () {
842
872
  return current < magnets.length-1 ? magnets[current+1] : magnets[current];
843
873
  }
844
874
 
875
+ var trigger = {};
876
+ Sticky.onScrollPercent = function(e)
877
+ {
878
+ if(e.target == undefined) return;
879
+
880
+ var classList = e.target[0].classList || "";
881
+ classList.forEach(function(className) {
882
+
883
+ if(!(e.target[0] in trigger)) trigger[e.target[0]] = {};
884
+
885
+ var regex = /scrollpercent(?:-(from|every|once)){0,1}-(\d+)(udlr){0,1}/gi;
886
+ if( (match = regex.exec(className)) ) {
887
+
888
+ var scrollTrigger = match[1] || "every";
889
+
890
+ var scrollDir = match[3] || "d";
891
+ if(scrollDir == "u") scrollDir = "up";
892
+ if(scrollDir == "d") scrollDir = "down";
893
+ if(scrollDir == "l") scrollDir = "left";
894
+ if(scrollDir == "r") scrollDir = "right";
895
+
896
+ var scrollPercent = parseInt(match[2]);
897
+ if(scrollDir == "up" || scrollDir == "left") scrollPercent = 100-scrollPercent;
898
+
899
+ if(e.scrollX.direction !== undefined && e.scrollX.delta) {
900
+
901
+ if(!(className in trigger[e.target[0]])) trigger[e.target[0]][className] = true;
902
+ if(scrollTrigger == "from" && e.scrollX.percent >= scrollPercent)
903
+ e.target[0].dispatchEvent(new CustomEvent("scrollpercent", {detail: {scroll:e, trigger:0, dir:scrollDir, percent:scrollPercent}}));
904
+ if(scrollTrigger == "once" && e.scrollX.percent >= scrollPercent && trigger[e.target[0]][className])
905
+ e.target[0].dispatchEvent(new CustomEvent("scrollpercent", {detail: {scroll:e, trigger:1, dir:scrollDir, percent:scrollPercent}}));
906
+
907
+ if(scrollTrigger == "every" && e.scrollX.percent < scrollPercent )
908
+ trigger[e.target[0]][className] = true;
909
+ if(scrollTrigger == "every" && e.scrollX.percent >= scrollPercent && trigger[e.target[0]][className])
910
+ e.target[0].dispatchEvent(new CustomEvent("scrollpercent", {detail: {scroll:e, trigger:2, dir:scrollDir, percent:scrollPercent}}));
911
+
912
+ trigger[e.target[0]][className] = (scrollTrigger == "every" && e.scrollX.percent < scrollPercent);
913
+ }
914
+
915
+ if(e.scrollY.direction !== undefined && e.scrollY.delta) {
916
+
917
+ if(!className in trigger[e.target[0]]) trigger[e.target[0]][className] = true;
918
+ if(scrollTrigger == "from" && e.scrollY.percent >= scrollPercent)
919
+ e.target[0].dispatchEvent(new CustomEvent("scrollpercent", {detail: {scroll:e, trigger:0, dir:scrollDir, percent:scrollPercent}}));
920
+ if(scrollTrigger == "once" && e.scrollY.percent >= scrollPercent && trigger[e.target[0]][className])
921
+ e.target[0].dispatchEvent(new CustomEvent("scrollpercent", {detail: {scroll:e, trigger:1, dir:scrollDir, percent:scrollPercent}}));
922
+
923
+ if(scrollTrigger == "every" && e.scrollY.percent >= scrollPercent && trigger[e.target[0]][className])
924
+ e.target[0].dispatchEvent(new CustomEvent("scrollpercent", {detail: {scroll:e, trigger:2, dir:scrollDir, percent:scrollPercent}}));
925
+
926
+ trigger[e.target[0]][className] = (scrollTrigger == "every" && e.scrollY.percent < scrollPercent);
927
+ }
928
+ }
929
+
930
+ }.bind(e.target[0]));
931
+ }
932
+
845
933
  var lastScrollTop = window.pageYOffset;
846
934
  var scrollSnapDebounce = false;
847
935
  Sticky.onScrollSnap = function (e)
@@ -894,14 +982,14 @@ $.fn.serializeObject = function () {
894
982
  duration: Settings["smoothscroll_duration"],
895
983
  speed: Settings["smoothscroll_speed"]
896
984
 
897
- }, Sticky.debounce(function() {
985
+ }, Sticky.debounce(function() {
898
986
 
899
- scrollSnapDebounce = false;
900
- $(scroller).removeClass("sticky-prevent-scroll");
901
- if (Sticky.get("scrolllock"))
902
- Sticky.enableScroll();
987
+ scrollSnapDebounce = false;
988
+ $(scroller).removeClass("sticky-prevent-scroll");
989
+ if (Sticky.get("scrolllock"))
990
+ Sticky.enableScroll();
903
991
 
904
- }, 1000*Sticky.parseDuration(Sticky.get("debounce"))), scroller);
992
+ }, 1000*Sticky.parseDuration(Sticky.get("debounce"))), scroller);
905
993
 
906
994
  $(magnets).each((e) => $(magnets[e].element).removeClass("magnet closest"));
907
995
  $(magnet.element).addClass("magnet");
@@ -945,6 +1033,7 @@ $.fn.serializeObject = function () {
945
1033
  });
946
1034
  }
947
1035
 
1036
+ var first = true;
948
1037
  var hasReset = false;
949
1038
  Sticky.onScrollDelta = function (e) {
950
1039
 
@@ -1021,6 +1110,11 @@ $.fn.serializeObject = function () {
1021
1110
 
1022
1111
  if(Sticky.userScroll(el) || $(el).hasClass("sticky-magnet") || (hash == null && elAll.length == 0)) {
1023
1112
 
1113
+ if(first) {
1114
+ first = false;
1115
+ return;
1116
+ }
1117
+
1024
1118
  window.replaceHash(hash, false, false);
1025
1119
  dispatchEvent(new HashChangeEvent("hashchange"))
1026
1120
  }
@@ -1035,7 +1129,7 @@ $.fn.serializeObject = function () {
1035
1129
  $(e.target).find(".sticky-top").each(function() {
1036
1130
 
1037
1131
  var scrollhide = $(this).attr("aria-scrollhide") || Sticky.get("scrollhide");
1038
- scrollhide = scrollhide === "false" ? false : scrollhide;
1132
+ scrollhide = scrollhide === "false" ? false : scrollhide;
1039
1133
 
1040
1134
  var that = this;
1041
1135
  if(scrollhide) {
@@ -1063,7 +1157,7 @@ $.fn.serializeObject = function () {
1063
1157
  } else if(e.scrollY.delta > 0){
1064
1158
 
1065
1159
  var borderThickness = parseInt($(this).css("border-bottom-width"))
1066
- + parseInt($(this).css("border-top-width"));
1160
+ + parseInt($(this).css("border-top-width"));
1067
1161
 
1068
1162
  $(this).removeClass("show");
1069
1163
  $(this).css("top", -this.clientHeight-borderThickness);
@@ -1091,12 +1185,12 @@ $.fn.serializeObject = function () {
1091
1185
  if(style["position"] !== "fixed" && !scrollcatchClone) {
1092
1186
 
1093
1187
  var scrollcatch = $(this).attr("aria-scrollcatch") || Sticky.get("scrollcatch");
1094
- scrollcatch = scrollcatch === true ? style["z-index"] : scrollcatch;
1188
+ scrollcatch = scrollcatch === true ? style["z-index"] : scrollcatch;
1095
1189
 
1096
- if (scrollcatch !== false && this.offsetTop <= scroller.scrollTop) {
1190
+ if (scrollcatch !== false && this.offsetTop <= scroller.scrollTop) {
1097
1191
 
1098
1192
  var that = $(this).clone().removeAttr("id")
1099
- .attr("aria-scrollcatch-clone", true);
1193
+ .attr("aria-scrollcatch-clone", true);
1100
1194
 
1101
1195
  $(this).addClass("caught")
1102
1196
  .attr("aria-scrollcatch-pos", scroller.scrollTop+1)
@@ -1126,7 +1220,7 @@ $.fn.serializeObject = function () {
1126
1220
  if(e.reset) hasReset = true;
1127
1221
  if(scrollHint) {
1128
1222
 
1129
- if(e.scrollY.delta < 0) {
1223
+ if(!e.scrollY.bottomElastic) {
1130
1224
  $(this).removeClass("hint");
1131
1225
  $(this).off("click.hint");
1132
1226
  hasReset = false;
@@ -1186,7 +1280,7 @@ $.fn.serializeObject = function () {
1186
1280
 
1187
1281
  var firstChild = this.firstElementChild;
1188
1282
  var offsetTop = Math.max(parseInt($(this).css("margin-top")), parseInt($(firstChild).css("margin-top")));
1189
- offsetTop += extraOffsetTop;
1283
+ offsetTop += extraOffsetTop;
1190
1284
 
1191
1285
  $(this).css("top", offsetTop);
1192
1286
  $(this).css("margin-top", offsetTop - extraOffsetTop);
@@ -1194,7 +1288,7 @@ $.fn.serializeObject = function () {
1194
1288
 
1195
1289
  var lastChild = this.lastElementChild;
1196
1290
  var offsetBottom = Math.max(parseInt($(this).css("margin-bottom")), parseInt($(lastChild).css("margin-bottom")));
1197
- offsetBottom -= extraOffsetBottom;
1291
+ offsetBottom -= extraOffsetBottom;
1198
1292
 
1199
1293
  if(firstChild !== lastChild) {
1200
1294
 
@@ -1220,8 +1314,8 @@ $.fn.serializeObject = function () {
1220
1314
  if (opacityIndex < 0) opacityIndex = transitionProperty.indexOf("all");
1221
1315
 
1222
1316
  var opacityIndex = (opacityIndex < 0 ? transitionDuration.length : opacityIndex);
1223
- opacityDuration = (opacityIndex < 0 ? 0 : Sticky.parseDuration(transitionDuration[opacityIndex]));
1224
- opacityDelay = (opacityIndex < 0 ? 0 : Sticky.parseDuration(transitionDelay[opacityIndex]));
1317
+ opacityDuration = (opacityIndex < 0 ? 0 : Sticky.parseDuration(transitionDuration[opacityIndex]));
1318
+ opacityDelay = (opacityIndex < 0 ? 0 : Sticky.parseDuration(transitionDelay[opacityIndex]));
1225
1319
 
1226
1320
  transitionDuration[opacityIndex] = (extraEaseTime < 0 ? opacityDuration : extraEaseTime);
1227
1321
  transitionDelay [opacityIndex] = (extraEaseDelay < 0 ? opacityDelay : extraEaseDelay) + i*Sticky.parseDuration(Sticky.get("easethrottle"));
@@ -1229,8 +1323,8 @@ $.fn.serializeObject = function () {
1229
1323
  var transition = [];
1230
1324
  for (var i = 0; i < transitionProperty.length; i++)
1231
1325
  transition[i] = transitionProperty[i] + " " +
1232
- Sticky.parseDuration(transitionDuration[i])+"s "+
1233
- Sticky.parseDuration(transitionDelay[i])+"s";
1326
+ Sticky.parseDuration(transitionDuration[i])+"s "+
1327
+ Sticky.parseDuration(transitionDelay[i])+"s";
1234
1328
 
1235
1329
  $(this).css("transition", transition.join(","));
1236
1330
  }
@@ -1283,9 +1377,9 @@ $.fn.serializeObject = function () {
1283
1377
  var isBelow = bottom + extraEaseIn < 0;
1284
1378
  var isBetween = isBiggerThanViewport
1285
1379
  ? !isAbove && (top + this.clientHeight + extraEaseIn > 0) &&
1286
- !isBelow && (bottom - this.clientHeight - extraEaseIn < 0)
1380
+ !isBelow && (bottom - this.clientHeight - extraEaseIn < 0)
1287
1381
  : !isAbove && (top + this.clientHeight + extraEaseIn < 0) &&
1288
- !isBelow && (bottom - this.clientHeight - extraEaseIn > 0);
1382
+ !isBelow && (bottom - this.clientHeight - extraEaseIn > 0);
1289
1383
 
1290
1384
  if(Settings.debug) console.log(show,"Sticky ease-in:",isAbove,isBelow,isBetween);
1291
1385
  show = (!isAbove && !isBelow);
@@ -1298,9 +1392,9 @@ $.fn.serializeObject = function () {
1298
1392
  var isBelow = bottom + extraEaseOut < 0;
1299
1393
  var isBetween = isBiggerThanViewport
1300
1394
  ? !isAbove && (top + this.clientHeight + extraEaseOut > 0) &&
1301
- !isBelow && (bottom - this.clientHeight - extraEaseOut < 0)
1395
+ !isBelow && (bottom - this.clientHeight - extraEaseOut < 0)
1302
1396
  : !isAbove && (top + this.clientHeight + extraEaseOut < 0) &&
1303
- !isBelow && (bottom - this.clientHeight - extraEaseOut > 0);
1397
+ !isBelow && (bottom - this.clientHeight - extraEaseOut > 0);
1304
1398
 
1305
1399
  if(Settings.debug) console.log(show,"Sticky ease-out:",isAbove,isBelow,isBetween);
1306
1400
  show = !isAbove && !isBelow;
@@ -1321,10 +1415,10 @@ $.fn.serializeObject = function () {
1321
1415
 
1322
1416
  // Overscroll detection
1323
1417
  var overscroll = {top:false, right:false, bottom:false, left:false};
1324
- overscroll.top = Sticky.overscrollTop(e);
1325
- overscroll.bottom = Sticky.overscrollBottom(e);
1326
- overscroll.left = Sticky.overscrollLeft(e);
1327
- overscroll.right = Sticky.overscrollRight(e);
1418
+ overscroll.top = Sticky.overscrollTop(e);
1419
+ overscroll.bottom = Sticky.overscrollBottom(e);
1420
+ overscroll.left = Sticky.overscrollLeft(e);
1421
+ overscroll.right = Sticky.overscrollRight(e);
1328
1422
 
1329
1423
  Sticky.set("overscroll", overscroll);
1330
1424
  if(overscroll.top || overscroll.bottom || overscroll.left || overscroll.right)
@@ -1333,8 +1427,16 @@ $.fn.serializeObject = function () {
1333
1427
  return this;
1334
1428
  }
1335
1429
 
1430
+
1336
1431
  Sticky.onAutoscroll = function() {
1337
1432
 
1433
+ var container = this;
1434
+ var scroller = $(container); //.closestScrollable();
1435
+
1436
+ function parseBoolean(str) {
1437
+ return /true/i.test(str);
1438
+ }
1439
+
1338
1440
  if ($(this).data("autoscroll-prevent")) {
1339
1441
 
1340
1442
  $(this).closestScrollableWindow().off("scrolldelta.autoscroll");
@@ -1359,8 +1461,11 @@ $.fn.serializeObject = function () {
1359
1461
 
1360
1462
  var autoscrollX = $(this).data("autoscroll-x");
1361
1463
  if(autoscrollX == undefined) autoscrollX = Sticky.get("autoscroll");
1464
+ autoscrollX = parseBoolean(autoscrollX);
1465
+
1362
1466
  var autoscrollY = $(this).data("autoscroll-y");
1363
1467
  if(autoscrollY == undefined) autoscrollY = Sticky.get("autoscroll");
1468
+ autoscrollY = parseBoolean(autoscrollY);
1364
1469
 
1365
1470
  var thresholdMinX = $(this).data("autoscroll-minwidth");
1366
1471
  if(thresholdMinX == undefined) thresholdMinX = Sticky.get("autoscroll_minwidth");
@@ -1408,18 +1513,18 @@ $.fn.serializeObject = function () {
1408
1513
 
1409
1514
  Sticky.scrollTo(scrollOptions, function() {
1410
1515
 
1411
- if( !bouncing || $(this).data("autoscroll-prevent") ) return;
1516
+ if( !bouncing || $(container).data("autoscroll-prevent") ) return;
1412
1517
 
1413
- $(this).prop("user-scroll", true);
1518
+ $(scroller).prop("user-scroll", true);
1414
1519
  Sticky.scrollTo(scrollBackOptions, function() {
1415
1520
 
1416
- Sticky.onAutoscroll.call(this);
1417
- if(reverse) $(this).removeData("autoscroll-reverse");
1418
- else $(this).data("autoscroll-reverse", true);
1521
+ Sticky.onAutoscroll.call(container);
1522
+ if(reverse) $(container).removeData("autoscroll-reverse");
1523
+ else $(container).data("autoscroll-reverse", true);
1419
1524
 
1420
- }.bind(this), this)
1525
+ }.bind(this), scroller)
1421
1526
 
1422
- }.bind(this), this);
1527
+ }.bind(this), scroller);
1423
1528
 
1424
1529
  return this;
1425
1530
 
@@ -1447,7 +1552,7 @@ $.fn.serializeObject = function () {
1447
1552
 
1448
1553
  var split = this.href.split("#");
1449
1554
  var anchorElem = $(split[1] == "" ? "body" : "#"+split[1]);
1450
- anchorY = anchorElem.length ? anchorElem[0].offsetTop - Sticky.getScrollPadding().top : 0;
1555
+ anchorY = anchorElem.length ? anchorElem[0].offsetTop - Sticky.getScrollPadding().top : 0;
1451
1556
  });
1452
1557
 
1453
1558
  if(Sticky.get("swipehint"))
@@ -1455,10 +1560,10 @@ $.fn.serializeObject = function () {
1455
1560
  $(".sticky-swipehint-container").each(function() {
1456
1561
 
1457
1562
  var image = document.createElement("img");
1458
- image.src = $(this).data("image");
1563
+ image.src = $(this).data("image");
1459
1564
 
1460
1565
  var span = document.createElement("span");
1461
- span.append(image);
1566
+ span.append(image);
1462
1567
 
1463
1568
  $(this).append(span);
1464
1569
  });
@@ -1493,113 +1598,124 @@ $.fn.serializeObject = function () {
1493
1598
  $(el).on('scrolldelta.sticky.snap', Sticky.onScrollSnap);
1494
1599
  }
1495
1600
 
1601
+ // Sticky percent scroll
1602
+ if(Sticky.get("scrollpercent"))
1603
+ {
1604
+ $(el).on('scrolldelta.sticky.percent', Sticky.onScrollPercent);
1605
+ }
1606
+
1496
1607
  // Sticky autoscroll
1497
1608
  if(Sticky.get("autoscroll"))
1498
1609
 
1499
1610
  $(".sticky-autoscroll").each(function() {
1500
1611
 
1501
- var scroller = $(this).closestScrollable();
1612
+ var container = this;
1613
+ var scroller = $(container); //.closestScrollable();
1502
1614
 
1503
- var reverseDelay = $(scroller).data("autoscroll-delay-reverse");
1504
- if (reverseDelay == undefined) reverseDelay = Sticky.get("autoscroll_delay_reverse");
1505
- var reverseSpeed = $(scroller).data("autoscroll-speed-reverse");
1506
- if (reverseSpeed == undefined) reverseSpeed = Sticky.get("autoscroll_speed_reverse");
1507
- var reverseDuration = $(scroller).data("autoscroll-duration-reverse");
1508
- if (reverseDuration == undefined) reverseDuration = Sticky.get("autoscroll_duration_reverse");
1615
+ var reverseDelay = $(scroller).data("autoscroll-delay-reverse");
1616
+ if (reverseDelay == undefined) reverseDelay = Sticky.get("autoscroll_delay_reverse");
1617
+ var reverseSpeed = $(scroller).data("autoscroll-speed-reverse");
1618
+ if (reverseSpeed == undefined) reverseSpeed = Sticky.get("autoscroll_speed_reverse");
1619
+ var reverseDuration = $(scroller).data("autoscroll-duration-reverse");
1620
+ if (reverseDuration == undefined) reverseDuration = Sticky.get("autoscroll_duration_reverse");
1509
1621
 
1510
- var startOver = $(scroller).data("autoscroll-startover");
1511
- if (startOver == undefined) startOver = Sticky.get("autoscroll_startover");
1622
+ var startOver = $(scroller).data("autoscroll-startover");
1623
+ if (startOver == undefined) startOver = Sticky.get("autoscroll_startover");
1512
1624
 
1513
- var delay = $(scroller).data("autoscroll-delay");
1514
- if (delay == undefined) delay = Sticky.get("autoscroll_delay");
1625
+ var delay = $(scroller).data("autoscroll-delay");
1626
+ if (delay == undefined) delay = Sticky.get("autoscroll_delay");
1515
1627
 
1516
- var thresholdMinX = $(scroller).data("autoscroll-minwidth");
1517
- if(thresholdMinX == undefined) thresholdMinX = Sticky.get("autoscroll_minwidth");
1518
- var thresholdMinY = $(scroller).data("autoscroll-minheight");
1519
- if(thresholdMinY == undefined) thresholdMinY = Sticky.get("autoscroll_minheight");
1628
+ var thresholdMinX = $(scroller).data("autoscroll-minwidth");
1629
+ if(thresholdMinX == undefined) thresholdMinX = Sticky.get("autoscroll_minwidth");
1630
+ var thresholdMinY = $(scroller).data("autoscroll-minheight");
1631
+ if(thresholdMinY == undefined) thresholdMinY = Sticky.get("autoscroll_minheight");
1520
1632
 
1521
- var scrollHeight = $(scroller).prop('scrollHeight') - $(scroller).innerHeight();
1522
- var atTop = $(scroller).scrollTop() < 1;
1523
- var atBottom = Math.abs($(scroller).scrollTop() - scrollHeight) < 1;
1633
+ var scrollHeight = $(scroller).prop('scrollHeight') - $(scroller).innerHeight();
1634
+ var atTop = $(scroller).scrollTop() < 1;
1635
+ var atBottom = Math.abs($(scroller).scrollTop() - scrollHeight) < 1;
1524
1636
 
1525
- var scrollWidth = $(scroller).prop('scrollWidth') - $(scroller).innerWidth();
1526
- var atLeft = $(scroller).scrollLeft() < 1;
1527
- var atRight = Math.abs($(scroller).scrollLeft() - scrollWidth) < 1;
1637
+ var scrollWidth = $(scroller).prop('scrollWidth') - $(scroller).innerWidth();
1638
+ var atLeft = $(scroller).scrollLeft() < 1;
1639
+ var atRight = Math.abs($(scroller).scrollLeft() - scrollWidth) < 1;
1528
1640
 
1529
- var mouseAction = $(scroller).data("autoscroll-mouse-action");
1530
- if (mouseAction == undefined) mouseAction = Sticky.get("autoscroll_mouse_action");
1641
+ var mouseAction = $(scroller).data("autoscroll-mouse-action");
1642
+ if (mouseAction == undefined) mouseAction = Sticky.get("autoscroll_mouse_action");
1531
1643
 
1532
- var noScrollY = (atTop && atBottom) || scrollHeight < thresholdMinY;
1533
- var noScrollX = (atLeft && atRight) || scrollWidth < thresholdMinX;
1644
+ var noScrollY = (atTop && atBottom) || scrollHeight < thresholdMinY;
1645
+ var noScrollX = (atLeft && atRight) || scrollWidth < thresholdMinX;
1534
1646
 
1535
- $(scroller).data("autoscroll-prevent", false);
1647
+ $(scroller).data("autoscroll-prevent", false);
1536
1648
 
1537
- var autoscrollTimeout = undefined;
1538
- var payloadAutoscroll = function() {
1649
+ var autoscrollTimeout = undefined;
1650
+ var payloadAutoscroll = function() {
1539
1651
 
1540
- if(autoscrollTimeout != undefined) clearTimeout(autoscrollTimeout);
1541
- autoscrollTimeout = setTimeout(() => Sticky.onAutoscroll.call(scroller), 1000*Sticky.parseDuration(delay) + 1);
1542
- };
1652
+ if(autoscrollTimeout != undefined) clearTimeout(autoscrollTimeout);
1653
+ autoscrollTimeout = setTimeout(() => Sticky.onAutoscroll.call(container), 1000*Sticky.parseDuration(delay) + 1);
1654
+ };
1543
1655
 
1544
- //
1545
- // Mouse events
1546
- if (mouseAction) {
1656
+ //
1657
+ // Mouse events
1658
+ if (mouseAction) {
1547
1659
 
1548
- $(scroller).on("mouseenter.autoscroll touchstart.autoscroll", function() {
1660
+ $(scroller).off("mouseenter.autoscroll touchstart.autoscroll");
1661
+ $(scroller).on("mouseenter.autoscroll touchstart.autoscroll", function() {
1549
1662
 
1550
- if(autoscrollTimeout != undefined) clearTimeout(autoscrollTimeout);
1551
- $(scroller).prop("user-scroll", true);
1552
- $(scroller).stop();
1553
- });
1663
+ if(autoscrollTimeout != undefined) clearTimeout(autoscrollTimeout);
1664
+ $(scroller).prop("user-scroll", true);
1665
+ $(scroller).stop();
1666
+ });
1554
1667
 
1555
- $(scroller).on("mouseleave.autoscroll touchend.autoscroll", function() {
1668
+ $(scroller).on("mouseleave.autoscroll touchend.autoscroll");
1669
+ $(scroller).on("mouseleave.autoscroll touchend.autoscroll", function() {
1556
1670
 
1557
- if(startOver) payloadAutoscroll();
1558
- else {
1671
+ if(startOver) payloadAutoscroll();
1672
+ else {
1559
1673
 
1560
- $(scroller).data("autoscroll-prevent", "true");
1561
- $(scroller).off("mouseleave.autoscroll touchend.autoscroll");
1562
- }
1563
- });
1674
+ $(scroller).data("autoscroll-prevent", "true");
1675
+ $(scroller).off("mouseleave.autoscroll touchend.autoscroll");
1676
+ }
1677
+ });
1564
1678
 
1565
- $(scroller).on("onbeforeunload.autoscroll", function() {
1679
+ $(scroller).on("onbeforeunload.autoscroll");
1680
+ $(scroller).on("onbeforeunload.autoscroll", function() {
1566
1681
 
1567
- $(this).off("mousewheel.autoscroll touchstart.autoscroll");
1568
- $(this).off("mouseenter.autoscroll touchstart.autoscroll");
1569
- $(this).off("mouseleave.autoscroll touchend.autoscroll");
1570
- $(this).off("scroll.autoscroll");
1571
- $(this).off("onbeforeunload.autoscroll");
1682
+ $(this).off("mousewheel.autoscroll touchstart.autoscroll");
1683
+ $(this).off("mouseenter.autoscroll touchstart.autoscroll");
1684
+ $(this).off("mouseleave.autoscroll touchend.autoscroll");
1685
+ $(this).off("scroll.autoscroll");
1686
+ $(this).off("onbeforeunload.autoscroll");
1572
1687
 
1573
- var scrollerWindow = $(this).closestScrollableWindow();
1574
- $(scrollerWindow).off("scroll.autoscroll");
1575
- });
1576
- }
1688
+ var scrollerWindow = $(this).closestScrollableWindow();
1689
+ $(scrollerWindow).off("scroll.autoscroll");
1690
+ });
1691
+ }
1577
1692
 
1578
- //
1579
- // Call action
1580
- if(noScrollY && noScrollX) payloadAutoscroll();
1581
- else if($(scroller).data("autoscroll-reverse")) {
1693
+ //
1694
+ // Call action
1695
+ if(noScrollY && noScrollX) payloadAutoscroll();
1696
+ else if($(scroller).data("autoscroll-reverse")) {
1582
1697
 
1583
- var scrollWidth = $(scroller).prop('scrollWidth') - scroller.innerWidth();
1584
- var scrollHeight = $(scroller).prop('scrollHeight') - scroller.innerHeight();
1698
+ var scrollWidth = $(scroller).prop('scrollWidth') - scroller.innerWidth();
1699
+ var scrollHeight = $(scroller).prop('scrollHeight') - scroller.innerHeight();
1585
1700
 
1586
- $(scroller).on("wheel.autoscroll DOMMouseScroll.autoscroll mousewheel.autoscroll touchstart.autoscroll", function(e) {
1701
+ $(scroller).off("wheel.autoscroll DOMMouseScroll.autoscroll mousewheel.autoscroll touchstart.autoscroll");
1702
+ $(scroller).on("wheel.autoscroll DOMMouseScroll.autoscroll mousewheel.autoscroll touchstart.autoscroll", function(e) {
1587
1703
 
1588
- $(this).prop("user-scroll", true);
1589
- $(this).stop();
1590
- });
1704
+ $(this).prop("user-scroll", true);
1705
+ $(this).stop();
1706
+ });
1591
1707
 
1592
- if (Settings.debug) console.log("Autoscroll reverse delay applied is \"" + reverseDelay + "\".");
1593
- setTimeout(() => Sticky.scrollTo({
1708
+ if (Settings.debug) console.log("Autoscroll reverse delay applied is \"" + reverseDelay + "\".");
1709
+ setTimeout(() => Sticky.scrollTo({
1594
1710
  left:scrollWidth,
1595
1711
  top:scrollHeight,
1596
1712
  duration:reverseDuration,
1597
1713
  speed:reverseSpeed
1598
- }, payloadAutoscroll, scroller), 1000*Sticky.parseDuration(reverseDelay + 1));
1714
+ }, payloadAutoscroll, scroller), 1000*Sticky.parseDuration(reverseDelay + 1));
1599
1715
 
1600
- } else payloadAutoscroll();
1601
- }
1602
- );
1716
+ } else payloadAutoscroll();
1717
+ }
1718
+ );
1603
1719
 
1604
1720
  Settings.ready = true;
1605
1721