rytm-webflow 2.2.3 → 2.2.5

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/CLAUDE.md ADDED
@@ -0,0 +1,363 @@
1
+ # rytm-webflow
2
+
3
+ AJAX view-swapping engine and scroll-triggered animation framework for tuki CMS projects.
4
+ Built on GSAP + ScrollMagic. Transforms server-rendered pages into pseudo-SPAs.
5
+
6
+ **Version**: 2.2.4 | **Entry**: `scripts/index.js` | **Deps**: gsap, imagesloaded, scrollmagic
7
+
8
+ ## Exports
9
+
10
+ ```javascript
11
+ import RytmWebflow from 'rytm-webflow'
12
+ ```
13
+
14
+ | Export | Type | Purpose |
15
+ |---|---|---|
16
+ | `aswap` | Singleton | AJAX page swap engine |
17
+ | `Controller` | Class | Base controller — view lifecycle & event management |
18
+ | `ControllerImgLoad` | Class | Controller that waits for images before showing view |
19
+ | `View` | Class | Base view — animation hooks |
20
+ | `WebflowView` | Class | View with declarative animations via data attributes |
21
+ | `WebflowListView` | Class | Staggered list animations with scroll triggers |
22
+ | `bootsrap5` | Object | Bootstrap 5 modal/offcanvas close helpers |
23
+ | `scrollController` | Singleton | ScrollMagic controller manager |
24
+ | `showUp` | Singleton | Standalone scroll-triggered animations (no ASwap needed) |
25
+ | `getWebflowProps(str)` | Function | Parse webflow show/hide syntax |
26
+ | `getWebflowAnimationProps(str)` | Function | Parse single animation string |
27
+ | `getParallaxProps(str)` | Function | Parse parallax syntax |
28
+ | `parseProps(str)` | Function | Parse `key:value` comma-separated pairs |
29
+ | `getScrollMagicSceneProps(el, setup)` | Function | Generate ScrollMagic scene config |
30
+ | `elementIsVisibleInViewport(el, partial)` | Function | Viewport visibility check |
31
+ | `CLASS_NAME_WEBSCROLL_FIRED` | Constant | `'webflow-scroll-fired'` |
32
+
33
+ ---
34
+
35
+ ## ASwap — AJAX page swap engine
36
+
37
+ ### Init
38
+
39
+ ```javascript
40
+ RytmWebflow.aswap.init(params, events)
41
+ ```
42
+
43
+ **params** (all optional, shown with defaults):
44
+
45
+ | Param | Default | Description |
46
+ |---|---|---|
47
+ | `animationTimeHide` | `800` | Hide transition duration (ms) |
48
+ | `animationTimeShow` | `800` | Show transition duration (ms) |
49
+ | `routes` | `{}` | Route definitions — `{ viewName: { controller, view } }` |
50
+ | `swapSelector` | `'#stage'` | Container selector for swapped content |
51
+ | `cacheOn` | `true` | Cache AJAX responses |
52
+ | `noCacheClassName` | `'no-as-cache'` | Link class to skip cache |
53
+ | `noSwapClassName` | `'no-as'` | Link class to skip ASwap entirely |
54
+ | `noScrollClassName` | `'no-as-scroll'` | Link class to keep scroll position |
55
+ | `resetScrollOn` | `true` | Reset scroll on navigation |
56
+ | `preloadOnHover` | `false` | Preload pages on link hover |
57
+ | `formsEnabled` | `true` | AJAX form submission |
58
+ | `formsSelector` | `'form'` | Form selector |
59
+ | `swipeEnabled` | `true` | Swipe navigation on mobile |
60
+ | `historyEnabled` | `true` | Use History API |
61
+ | `refreshOnSameUrl` | `true` | Reload on same-URL click |
62
+ | `defaultDocumentScrollBehavior` | `'smooth'` | Scroll animation |
63
+ | `trace` | `() => {}` | Debug logging function |
64
+
65
+ **events** (all optional):
66
+
67
+ | Event | When |
68
+ |---|---|
69
+ | `onInited` | ASwap initialized |
70
+ | `onRequestUrl` | URL navigation started |
71
+ | `onRequestLoad` | AJAX loading started |
72
+ | `onRequestLoaded` | Response received |
73
+ | `onRequestSameUrl` | Same URL re-requested |
74
+ | `onViewHide` | Hide animation starting |
75
+ | `onViewHidden` | Hide animation complete |
76
+ | `onViewSwapStart` | Before DOM swap |
77
+ | `onViewSwapComplete` | After DOM swap |
78
+ | `onViewShow` | Show animation starting |
79
+ | `onViewShown` | Show animation complete |
80
+
81
+ ### Methods
82
+
83
+ ```javascript
84
+ RytmWebflow.aswap.openURL(url, noHistory?, useCache?) // Navigate programmatically
85
+ RytmWebflow.aswap.clearCache(url?) // Clear all or specific cache
86
+ RytmWebflow.aswap.formSubmit(formElement) // Submit form via AJAX
87
+ ```
88
+
89
+ ### HTML requirements
90
+
91
+ ```html
92
+ <body data-html-classes="optional-classes">
93
+ <div id="stage">
94
+ <div data-as-view="viewname" data-as-id="unique-id">
95
+ <!-- swapped content -->
96
+ </div>
97
+ </div>
98
+ </body>
99
+ ```
100
+
101
+ ### Link classes
102
+
103
+ | Class | Effect |
104
+ |---|---|
105
+ | `no-as` | Skip ASwap — regular navigation |
106
+ | `no-as-cache` | Skip response cache |
107
+ | `no-as-scroll` | Don't reset scroll position |
108
+
109
+ ### Swipe navigation
110
+
111
+ ```html
112
+ <div data-as-swipe-left="/next" data-as-swipe-right="/prev">
113
+ ```
114
+
115
+ ---
116
+
117
+ ## Controller
118
+
119
+ Base class for view lifecycle management. One instance per `data-as-id`.
120
+
121
+ ### Key properties
122
+
123
+ | Property | Type | Description |
124
+ |---|---|---|
125
+ | `id` | string | Unique identifier from `data-as-id` |
126
+ | `name` | string | Route name from `data-as-view` |
127
+ | `active` | boolean | Whether view is currently visible |
128
+ | `view` | View\|false | Associated View instance |
129
+
130
+ ### Lifecycle (override in subclass)
131
+
132
+ ```javascript
133
+ class MyController extends RytmWebflow.Controller {
134
+ addEventListeners() {
135
+ super.addEventListeners()
136
+ // Add DOM listeners — called when view becomes visible
137
+ }
138
+
139
+ removeEventListeners() {
140
+ super.removeEventListeners()
141
+ // Remove DOM listeners — called when view hides
142
+ }
143
+ }
144
+ ```
145
+
146
+ ### Event handler sequence
147
+
148
+ ```
149
+ Click link → onRequestUrl → onRequestLoad → onRequestLoaded
150
+ → onViewHide (removeEventListeners + view.hide)
151
+ → onViewHidden
152
+ → DOM swap (onViewSwapStart → onViewSwapComplete)
153
+ → onViewShow (view.show)
154
+ → onViewShown (addEventListeners + view.shown)
155
+ ```
156
+
157
+ ### Utility methods
158
+
159
+ ```javascript
160
+ controller.getViewContainer(wrapper) // Find this controller's DOM container
161
+ controller.getContainerSelector() // Returns '[data-as-id="..."]'
162
+ controller.isActive() // Check if visible
163
+ ```
164
+
165
+ ---
166
+
167
+ ## ControllerImgLoad
168
+
169
+ Extends `Controller`. Delays show animation until all images in container are loaded.
170
+
171
+ ```javascript
172
+ class GalleryCtrl extends RytmWebflow.ControllerImgLoad {
173
+ loadImagesComplete() {
174
+ super.loadImagesComplete()
175
+ // All images loaded — safe for layout-dependent operations
176
+ }
177
+ }
178
+ ```
179
+
180
+ CSS class `as-images-loading` is on container while images load.
181
+
182
+ ---
183
+
184
+ ## View
185
+
186
+ Base class for show/hide animations.
187
+
188
+ ### Lifecycle methods (override in subclass)
189
+
190
+ ```javascript
191
+ class MyView extends RytmWebflow.View {
192
+ prepare(container) { super.prepare(container) } // Before show, set initial state
193
+ show(container) { super.show(container) } // Animate in
194
+ shown(container) { } // Show complete
195
+ hide(container) { super.hide(container) } // Animate out
196
+ hidden(container) { } // Hide complete
197
+
198
+ // Only with ControllerImgLoad:
199
+ loadImagesStart(container) { }
200
+ loadImagesComplete(container) { }
201
+ }
202
+ ```
203
+
204
+ ### Utility
205
+
206
+ ```javascript
207
+ // Filter elements to exclude nested views
208
+ const items = [...container.querySelectorAll('.item')].filter(this.elementBelongsToView)
209
+ ```
210
+
211
+ ---
212
+
213
+ ## WebflowView — declarative animations
214
+
215
+ Extends `View`. Reads animation config from data attributes — no manual animation code needed.
216
+
217
+ ### ASwap view animations (show/hide on page transition)
218
+
219
+ ```html
220
+ <div data-webview-initial="o:0"
221
+ data-webview-show="o:1,t:.5,e:power3.out"
222
+ data-webview-hide="o:0,t:.3">
223
+ ```
224
+
225
+ ### Scroll-triggered animations
226
+
227
+ ```html
228
+ <div data-webscroll-initial="o:0,y:100"
229
+ data-webscroll-show="o:1,y:0,t:.5,e:power3.out"
230
+ data-webscroll-hide="o:0,t:.3">
231
+ ```
232
+
233
+ ### Stagger animations (lists)
234
+
235
+ ```html
236
+ <ul data-stagger-initial="o:0,y:20"
237
+ data-stagger-show="o:1,y:0,t:.5,stagger:.08"
238
+ data-stagger-hide="o:0,t:.3,stagger:.04"
239
+ data-webset="selector:li">
240
+ <li>Item 1</li>
241
+ <li>Item 2</li>
242
+ </ul>
243
+ ```
244
+
245
+ ### Webflow syntax reference
246
+
247
+ | Code | CSS Property | Example |
248
+ |---|---|---|
249
+ | `o` | opacity | `o:0` → `o:1` |
250
+ | `x` | translateX | `x:100` (px, supports `vw`/`vh`) |
251
+ | `y` | translateY | `y:-50` |
252
+ | `s` | scale | `s:1.2` |
253
+ | `r` | rotation | `r:90` (degrees) |
254
+ | `w` | width | `w:500` (px) |
255
+ | `h` | height | `h:300` (px) |
256
+ | `t` | duration | `t:.5` (seconds) |
257
+ | `d` | delay | `d:.2` (seconds) |
258
+ | `e` | ease | `e:power3.out` (GSAP v3 syntax) |
259
+ | `stagger` | item delay | `stagger:.1` (seconds, for lists) |
260
+
261
+ ### data-webset options
262
+
263
+ ```html
264
+ <div data-webset="trigger:parent,offset:center,fireOnce:false,duration:100%">
265
+ ```
266
+
267
+ | Option | Values | Default | Description |
268
+ |---|---|---|---|
269
+ | `trigger` | `parent`, CSS selector | element itself | What triggers the animation |
270
+ | `offset` | `top`, `center`, px value | bottom of viewport | Viewport trigger position |
271
+ | `fireOnce` | `true`, `false` | `true` | Animate only once |
272
+ | `duration` | `%`, `vh` | — | Parallax-style animation over scroll distance |
273
+ | `selector` | CSS selector | — | Required for stagger: selects list items |
274
+ | `stagger` | seconds | `0.05` | Delay between stagger items |
275
+
276
+ ---
277
+
278
+ ## WebflowListView
279
+
280
+ Extends `View`. Applies scroll-triggered stagger animations to list items.
281
+
282
+ ```html
283
+ <div data-as-view="list" data-as-id="products" data-webset="selector:.item,stagger:.15">
284
+ <div class="item">
285
+ <div data-webscroll-initial="o:0" data-webscroll-show="o:1,t:.5">Content</div>
286
+ </div>
287
+ <!-- more items... -->
288
+ </div>
289
+ ```
290
+
291
+ Each item's delay = `index × stagger + original delay`.
292
+
293
+ ---
294
+
295
+ ## ShowUp — standalone scroll animations
296
+
297
+ Works without ASwap. For elements that animate on scroll across all pages.
298
+
299
+ ```javascript
300
+ RytmWebflow.showUp.init() // Build all scroll scenes from DOM
301
+ RytmWebflow.showUp.rebuild() // Destroy and reinit (call after DOM changes)
302
+ RytmWebflow.showUp.hide() // Trigger all hide animations
303
+ RytmWebflow.showUp.destroy() // Clean up all scenes
304
+ ```
305
+
306
+ ### HTML syntax
307
+
308
+ ```html
309
+ <!-- Show;Hide separated by semicolon -->
310
+ <div data-webflow="o:0,t:.5,e:power3.out;o:0,y:-50,t:.3">
311
+ Animate on scroll
312
+ </div>
313
+
314
+ <!-- Parallax -->
315
+ <div data-webpara="y:-100" data-webset="duration:100%,trigger:parent">
316
+ Parallax effect
317
+ </div>
318
+ ```
319
+
320
+ ### ASwap integration (required)
321
+
322
+ ```javascript
323
+ const aswapEvents = {
324
+ onViewSwapComplete: () => RytmWebflow.showUp.rebuild(),
325
+ onViewHide: () => RytmWebflow.showUp.hide()
326
+ }
327
+ ```
328
+
329
+ ---
330
+
331
+ ## Bootstrap 5 helpers
332
+
333
+ ```javascript
334
+ RytmWebflow.bootsrap5.hideFlyovers() // Close all modals + offcanvases
335
+ RytmWebflow.bootsrap5.hideModals() // Close modals only
336
+ RytmWebflow.bootsrap5.hideOffcanvases() // Close offcanvases only
337
+ ```
338
+
339
+ Note: the export name has a typo (`bootsrap5`, not `bootstrap5`).
340
+
341
+ ---
342
+
343
+ ## scrollController
344
+
345
+ ```javascript
346
+ RytmWebflow.scrollController.get() // Get/create ScrollMagic.Controller
347
+ RytmWebflow.scrollController.refresh() // Update all scenes
348
+ RytmWebflow.scrollController.destroy() // Clean up
349
+ ```
350
+
351
+ ---
352
+
353
+ ## Common pitfalls
354
+
355
+ 1. **ShowUp not updating after page swap** — call `showUp.rebuild()` in `onViewSwapComplete`
356
+ 2. **Layout shifts from images** — use `ControllerImgLoad` for image-heavy pages
357
+ 3. **Nested view element leaks** — filter with `elementBelongsToView()` when querying elements
358
+ 4. **ScrollMagic memory leaks** — WebflowView handles cleanup automatically; manual scenes need explicit `destroy()`
359
+ 5. **Bootstrap modals persist on navigation** — call `bootsrap5.hideFlyovers()` in `onViewHide`
360
+ 6. **Event listener accumulation** — always clean up in `removeEventListeners()`
361
+ 7. **Stagger not working** — requires `data-webset="selector:..."` attribute
362
+ 8. **Easing not applied** — use GSAP v3 syntax: `e:power3.out` (not `e:Power3.easeOut`)
363
+ 9. **Cache causes stale content** — add `no-as-cache` class to forms or dynamic links
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rytm-webflow",
3
- "version": "2.2.3",
3
+ "version": "2.2.5",
4
4
  "description": "rytm webflow pack - ASwap, ShowUp",
5
5
  "main": "scripts/index.js",
6
6
  "scripts": {
@@ -50,7 +50,19 @@ class View {
50
50
  * fired only if ControllerImgLoad is used
51
51
  */
52
52
  loadImagesComplete(container) {
53
- }
53
+ }
54
+ /**
55
+ * check if DOM element belongs to view
56
+ * exclude elements belonging to nested views
57
+ */
58
+ elementBelongsToView = (el) => {
59
+ let result = false;
60
+ const elContainer = el.closest('[data-as-view]');
61
+ if (elContainer && elContainer.dataset.asId === this.id) {
62
+ result = true;
63
+ }
64
+ return result;
65
+ }
54
66
  }
55
67
 
56
68
  export default View;
@@ -6,6 +6,7 @@ import { CLASS_NAME_WEBSCROLL_FIRED } from './WebflowView';
6
6
  // data-webscroll-... (scroll magic)
7
7
  const DATA_ATTR_WEBSCROLL_INIT = "webscroll-initial";
8
8
  const DATA_ATTR_WEBSCROLL_SHOW = "webscroll-show";
9
+ const DATA_ATTR_WEBSCROLL_HIDE = "webscroll-hide";
9
10
  const DATA_ATTR_SETUP = "webset";
10
11
  const DEFAULT_STAGGER = .05;
11
12
 
@@ -24,7 +25,7 @@ class WebflowListView extends View {
24
25
  console.warn("Unknown selector for WebflowListView", this);
25
26
  return;
26
27
  }
27
- const list = [...container.querySelectorAll(this.webset.selector)];
28
+ const list = [...container.querySelectorAll(this.webset.selector)].filter(this.elementBelongsToView);
28
29
  list.forEach(this.listElementShow.bind(this));
29
30
  }
30
31
  /**
@@ -32,6 +33,13 @@ class WebflowListView extends View {
32
33
  **/
33
34
  hide(container) {
34
35
  super.hide(container);
36
+ this.webset = parseProps(container.dataset[DATA_ATTR_SETUP]);
37
+ if (!this.webset.selector) {
38
+ console.warn("Unknown selector for WebflowListView", this);
39
+ return;
40
+ }
41
+ const list = [...container.querySelectorAll(this.webset.selector)].filter(this.elementBelongsToView);
42
+ list.forEach(this.listElementHide.bind(this));
35
43
  }
36
44
  /**
37
45
  * ############
@@ -45,7 +53,7 @@ class WebflowListView extends View {
45
53
  const stagger = this.webset.stagger ? parseFloat(this.webset.stagger) : DEFAULT_STAGGER;
46
54
  const delay = index * stagger;
47
55
  // search for all webscroll elements
48
- const list = [...el.querySelectorAll('*[data-' + DATA_ATTR_WEBSCROLL_SHOW + ']')];
56
+ const list = [...el.querySelectorAll('*[data-' + DATA_ATTR_WEBSCROLL_SHOW + ']')].filter(this.elementBelongsToView);
49
57
  list.forEach((el) => {
50
58
  this.webScrollElementShow(el, delay);
51
59
  })
@@ -68,6 +76,36 @@ class WebflowListView extends View {
68
76
  });
69
77
  }
70
78
  }
79
+ /**
80
+ * ############
81
+ * ### HIDE ###
82
+ * ############
83
+ */
84
+ // show list element
85
+ listElementHide(el, index) {
86
+ // check if element is in viewport
87
+ if (!this.isElementInViewport(el)) return;
88
+ const stagger = this.webset.stagger ? parseFloat(this.webset.stagger) : DEFAULT_STAGGER;
89
+ const delay = index * stagger;
90
+ // search for all webscroll elements
91
+ const list = [...el.querySelectorAll('*[data-' + DATA_ATTR_WEBSCROLL_SHOW + ']')].filter(this.elementBelongsToView);
92
+ list.forEach((el) => {
93
+ this.webScrollElementHide(el, delay);
94
+ })
95
+ }
96
+ // show web scroll element
97
+ webScrollElementHide(el, delay) {
98
+ const propsHide = this.getTweenProps(el, DATA_ATTR_WEBSCROLL_HIDE);
99
+ if (propsHide) {
100
+ delay = delay + (propsHide.tween.delay || 0);
101
+ gsap.killTweensOf(el);
102
+ gsap.to(el, {
103
+ duration: propsHide.time,
104
+ ...propsHide.tween,
105
+ delay,
106
+ });
107
+ }
108
+ }
71
109
  /**
72
110
  * ###############
73
111
  * ### HELPERS ###
@@ -55,6 +55,7 @@ class WebflowView extends View {
55
55
  * animate out (hide)
56
56
  **/
57
57
  hide(container) {
58
+ this.container = container;
58
59
  super.hide(container);
59
60
  // hide Aswap webviews
60
61
  this.webViewsHide();
@@ -120,7 +121,7 @@ class WebflowView extends View {
120
121
  console.warn("Unknown container", this);
121
122
  return;
122
123
  }
123
- const list = [...this.container.querySelectorAll('*[data-' + DATA_ATTR_WEBVIEW_SHOW + ']')];
124
+ const list = [...this.container.querySelectorAll('*[data-' + DATA_ATTR_WEBVIEW_SHOW + ']')].filter(this.elementBelongsToView);
124
125
  list.forEach(this.webViewElementShow.bind(this));
125
126
  }
126
127
  // showe webview element
@@ -140,7 +141,7 @@ class WebflowView extends View {
140
141
  console.warn("Unknown container", this);
141
142
  return;
142
143
  }
143
- const list = [...this.container.querySelectorAll('*[data-' + DATA_ATTR_STAGGER_SHOW + ']')];
144
+ const list = [...this.container.querySelectorAll('*[data-' + DATA_ATTR_STAGGER_SHOW + ']')].filter(this.elementBelongsToView);
144
145
  list.forEach(this.staggerListShow.bind(this));
145
146
  }
146
147
  staggerListShow(el, index) {
@@ -149,7 +150,7 @@ class WebflowView extends View {
149
150
  console.warn("Unknown selector for webflow stagger", el);
150
151
  return;
151
152
  }
152
- const items = [...el.querySelectorAll(selector)];
153
+ const items = [...el.querySelectorAll(selector)].filter(this.elementBelongsToView);
153
154
  const propsInit = this.getTweenProps(el, DATA_ATTR_STAGGER_INIT);
154
155
  const propsShow = this.getTweenProps(el, DATA_ATTR_STAGGER_SHOW);
155
156
  if (items.length && propsInit && propsShow) {
@@ -165,7 +166,7 @@ class WebflowView extends View {
165
166
  console.warn("Unknown container", this);
166
167
  return;
167
168
  }
168
- const list = [...this.container.querySelectorAll('*[data-' + DATA_ATTR_WEBSCROLL_SHOW + ']')];
169
+ const list = [...this.container.querySelectorAll('*[data-' + DATA_ATTR_WEBSCROLL_SHOW + ']')].filter(this.elementBelongsToView);
169
170
  list.forEach(this.hideScrollElement.bind(this));
170
171
  }
171
172
  hideScrollElement(el, index) {
@@ -183,7 +184,7 @@ class WebflowView extends View {
183
184
  console.warn("Unknown container", this);
184
185
  return;
185
186
  }
186
- const list = [...this.container.querySelectorAll('*[data-' + DATA_ATTR_WEBSCROLL_SHOW + ']')];
187
+ const list = [...this.container.querySelectorAll('*[data-' + DATA_ATTR_WEBSCROLL_SHOW + ']')].filter(this.elementBelongsToView);
187
188
  list.forEach(this.buildScrollmagicScene.bind(this));
188
189
  }
189
190
  /**
@@ -248,7 +249,7 @@ class WebflowView extends View {
248
249
  console.warn("Unknown container", this);
249
250
  return;
250
251
  }
251
- const list = [...this.container.querySelectorAll('*[data-' + DATA_ATTR_WEBVIEW_HIDE + ']')];
252
+ const list = [...this.container.querySelectorAll('*[data-' + DATA_ATTR_WEBVIEW_HIDE + ']')].filter(this.elementBelongsToView);
252
253
  list.forEach(this.webViewsElementHide.bind(this));
253
254
  }
254
255
  // showe webview element
@@ -266,7 +267,7 @@ class WebflowView extends View {
266
267
  console.warn("Unknown container", this);
267
268
  return;
268
269
  }
269
- const list = [...this.container.querySelectorAll('*[data-' + DATA_ATTR_STAGGER_HIDE + ']')];
270
+ const list = [...this.container.querySelectorAll('*[data-' + DATA_ATTR_STAGGER_HIDE + ']')].filter(this.elementBelongsToView);
270
271
  list.forEach(this.staggerListHide.bind(this));
271
272
  }
272
273
  // Hide stagger element
@@ -276,7 +277,7 @@ class WebflowView extends View {
276
277
  console.warn("Unknown selector for webflow stagger", el);
277
278
  return;
278
279
  }
279
- const items = [...el.querySelectorAll(selector)];
280
+ const items = [...el.querySelectorAll(selector)].filter(this.elementBelongsToView);
280
281
  const propsHide = this.getTweenProps(el, DATA_ATTR_STAGGER_HIDE);
281
282
  if (items.length && propsHide) {
282
283
  gsap.killTweensOf(items);
@@ -292,7 +293,7 @@ class WebflowView extends View {
292
293
  console.warn("Unknown container", this);
293
294
  return;
294
295
  }
295
- const list = [...this.container.querySelectorAll('*[data-' + DATA_ATTR_WEBSCROLL_HIDE + ']')];
296
+ const list = [...this.container.querySelectorAll('*[data-' + DATA_ATTR_WEBSCROLL_HIDE + ']')].filter(this.elementBelongsToView);
296
297
  list.forEach(this.hideScrollmagicElement.bind(this));
297
298
  }
298
299
  /**