-
Notifications
You must be signed in to change notification settings - Fork 4
/
scrollery.js
140 lines (86 loc) · 3.63 KB
/
scrollery.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*
# Scrollery
## version 0.1.1
Scrollery is a CSS reprocessor that makes the following JS values available as CSS variables for any element you tell the plugin to watch:
- `scrollWidth`
- `scrollHeight`
- `scrollLeft`
- `scrollTop`
To have scrollery watch an element, you need to give that element a unique identifier, as well as add the `data-scrollery` attribute. The plugin will use either the value of the `data-scrollery` attribute, or else the value of the `id` (if defined) for an element.
By default, Scrollery will watch 0 elements. If you add a `data-scrollery` attribute to either the `<html>` or `<body>` element it will attach an event listener for the `scroll` event on the `window`, otherwise if you add the `data-scrollery` attribute to other elements it will add a `scroll` listener to that element.
- https://github.com/tomhodgins/cssplus
Author: Tommy Hodgins
License: MIT
*/
// Uses Node, AMD or browser globals to create a module
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD: Register as an anonymous module
define([], factory)
} else if (typeof module === 'object' && module.exports) {
// Node: Does not work with strict CommonJS, but
// only CommonJS-like environments that support module.exports,
// like Node
module.exports = factory()
} else {
// Browser globals (root is window)
root.scrollery = factory()
}
}(this, function() {
const scrollery = {}
scrollery.style = ''
scrollery.load = () => {
// Find (or create) style tag to populate
const style_tag = document.querySelector('[data-scrollery-style]') || (() => {
const tag = document.createElement('style')
tag.setAttribute('data-scrollery-style', '')
document.head.appendChild(tag)
return tag
})()
scrollery.style = ''
scrollery.process()
// Populate style tag with current CSS string
style_tag.innerHTML = `:root {\n${scrollery.style.replace(/^/gm,' ')}\n}`
}
scrollery.process = () => {
let css_rules = ''
// For each [data-scrollery] element
Array.from(document.querySelectorAll('[data-scrollery]'), (tag, i) => {
// Add scroll event listeners on elements with [data-scrollery] attribute
// If we haven't added an event listener yet
if (tag.getAttribute('data-scrollery-listen') !== true) {
// If listening to <html> or <body>
if (tag === document.documentElement || tag === document.body) {
// watch `scroll` on `window`
window.addEventListener('scroll', scrollery.load)
} else {
// Otherwise listen to the `scroll` event on the element
tag.addEventListener('scroll', scrollery.load)
}
// Mark that we've added an event listener here
tag.setAttribute('data-scrollery-listen', 'true')
}
css_rules += scrollery.transform(tag, i)
})
if (css_rules.length > 0) {
scrollery.style += css_rules
}
}
scrollery.transform = tag => {
let newRule = ''
// Set the name to the value of the data-varsity="" attribute, or the id="" if there is none
let name = (tag.getAttribute('data-scrollery') || tag.id || i)
// List properties of element as variables
newRule += `\n/* ${name} */`
+ `\n--${name}-scrollWidth: ${tag.scrollWidth};`
+ `\n--${name}-scrollHeight: ${tag.scrollHeight};`
+ `\n--${name}-scrollLeft: ${tag.scrollLeft};`
+ `\n--${name}-scrollTop: ${tag.scrollTop};`
+ '\n'
return newRule
}
// Update every `load`
window.addEventListener('load', scrollery.load)
window.addEventListener('resize', scrollery.load)
return scrollery
}))