-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This is roughly based on : https://github.com/argyleink/scrollyfills So also attributed to and licensed as this original work. The original however was slightly broken and didn't implement the `once` option. It also lacked tests. --------- Co-authored-by: Simon Menke <simon.menke@gmail.com>
- Loading branch information
1 parent
4c6bc06
commit d890f46
Showing
4 changed files
with
521 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
#### Aliases | ||
aliases = [] | ||
|
||
#### Dependencies | ||
dependencies = [ | ||
"Event", | ||
"Set", | ||
"WeakMap", | ||
"smoothscroll" | ||
] | ||
|
||
#### Specification Link | ||
spec = "https://html.spec.whatwg.org/multipage/webappapis.html#handler-onscrollend" | ||
|
||
#### Documentation Link | ||
docs = "https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollend_event" | ||
|
||
#### License | ||
license = "ISC" | ||
|
||
# The polyfill code was ported to ES3 for compatibility with older browsers. | ||
repo = "https://github.com/argyleink/scrollyfills" | ||
|
||
#### Browser compatibility | ||
[browsers] | ||
android = "*" | ||
bb = "*" | ||
chrome = "<114" | ||
edge = "*" | ||
edge_mob = "*" | ||
firefox = "<109" | ||
firefox_mob = "<109" | ||
ie = "*" | ||
ie_mob = "*" | ||
opera = "<100" | ||
op_mob = "<76" | ||
op_mini = "*" | ||
safari = "*" | ||
ios_saf = "*" | ||
samsung_mob = "<23.0" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
'onscrollend' in self && (self.onscrollend == null || typeof self.onscrollend === 'function') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
(function (global) { | ||
var scrollEndEvent = new global.Event('scrollend'); | ||
var pointers = new global.Set(); | ||
|
||
// Track if any pointer is active | ||
global.document.addEventListener('touchstart', function (e) { | ||
for (var i = 0; i < e.changedTouches.length; i++) { | ||
pointers.add(e.changedTouches[i].identifier); | ||
} | ||
}, { passive: true }); | ||
|
||
global.document.addEventListener('touchend', function (e) { | ||
for (var i = 0; i < e.changedTouches.length; i++) { | ||
pointers.delete(e.changedTouches[i].identifier); | ||
} | ||
}, { passive: true }); | ||
|
||
// Map of scroll-observed elements. | ||
var observed = new global.WeakMap(); | ||
|
||
function onAddListener(originalFn, type) { | ||
var scrollPort = this; | ||
|
||
var data = observed.get(scrollPort); | ||
if (data !== undefined) { | ||
data.listeners[type]++; | ||
return; | ||
} | ||
|
||
var timeout = 0; | ||
|
||
data = { | ||
scrollListener: function scrollListener(evt) { // eslint-disable-line no-unused-vars | ||
clearTimeout(timeout); | ||
|
||
timeout = setTimeout(function () { | ||
if (pointers.size) { | ||
// if pointer(s) are down, wait longer | ||
setTimeout(data.scrollListener, 100); | ||
return; | ||
} | ||
|
||
// dispatch | ||
if (scrollPort) { | ||
scrollPort.dispatchEvent(scrollEndEvent); | ||
} | ||
}, 100); | ||
|
||
}, | ||
listeners: { | ||
scroll: 0, | ||
scrollend: 0 | ||
} | ||
}; | ||
|
||
originalFn.apply(scrollPort, ['scroll', data.scrollListener]); | ||
observed.set(scrollPort, data); | ||
} | ||
|
||
function onRemoveListener(originalFn, type) { | ||
var scrollPort = this; | ||
var data = observed.get(scrollPort); | ||
|
||
if (data === undefined) { | ||
return; | ||
} | ||
|
||
data.listeners[type] = Math.max(0, data.listeners[type] - 1); | ||
// If there are still listeners, nothing more to do. | ||
if ((data.listeners.scroll + data.listeners.scrollend) > 0) { | ||
return; | ||
} | ||
|
||
// Otherwise, remove the added listeners. | ||
originalFn.apply(scrollPort, ['scroll', data.scrollListener]); | ||
observed.delete(scrollPort); | ||
} | ||
|
||
function polyfillAddEventListener(proto) { | ||
var native = proto.addEventListener; | ||
proto.addEventListener = function addEventListener(type, callback) { // eslint-disable-line no-unused-vars | ||
var args = global.Array.prototype.slice.apply(arguments, [0]); | ||
native.apply(this, args); | ||
|
||
if (type !== 'scroll' && type !== 'scrollend') { | ||
return; | ||
} | ||
|
||
if (arguments[2] && arguments[2].once) { | ||
var removerArgs = global.Array.prototype.slice.apply(arguments, [0]); | ||
var _this = this; | ||
|
||
var remover = function () { | ||
_this.removeEventListener(type, remover); | ||
_this.removeEventListener.apply(_this, removerArgs); | ||
} | ||
|
||
_this.addEventListener(type, remover); | ||
} | ||
|
||
args.unshift(native); | ||
onAddListener.apply(this, args); | ||
} | ||
} | ||
|
||
function polyfillRemoveEventListener(proto) { | ||
var native = proto.removeEventListener; | ||
proto.removeEventListener = function removeEventListener(type, callback) { // eslint-disable-line no-unused-vars | ||
var args = global.Array.prototype.slice.apply(arguments, [0]); | ||
native.apply(this, args); | ||
|
||
if (type !== 'scroll' && type !== 'scrollend') { | ||
return; | ||
} | ||
|
||
args.unshift(native); | ||
onRemoveListener.apply(this, args); | ||
} | ||
} | ||
|
||
polyfillAddEventListener(global.Element.prototype); | ||
polyfillAddEventListener(global); | ||
polyfillAddEventListener(global.document); | ||
polyfillRemoveEventListener(global.Element.prototype); | ||
polyfillRemoveEventListener(global); | ||
polyfillRemoveEventListener(global.document); | ||
|
||
if (!('onscrollend' in self)) { | ||
// Make sure a check for 'onhashchange' in window will pass | ||
global.onscrollend = null; | ||
} | ||
}(self)); |
Oops, something went wrong.