rytm-webflow 1.1.3 → 2.0.0

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
@@ -11,7 +11,6 @@ $ npm install rytm-webflow --save
11
11
  ## Dependencies
12
12
  - gsap
13
13
  - imagesloaded
14
- - jquery
15
14
  - scrollmagic
16
15
  - scrollmagic-plugin-gsap
17
16
 
@@ -154,6 +153,7 @@ RytmWebflow.aswap.init({
154
153
  | ```refreshOnSameUrl``` | ```true``` | When ```true``` each request on same URL will refresh browser's window |
155
154
  | ```routes``` | ```{}``` | The routes object where you can define controllers and views |
156
155
  | ```swapSelector``` | ```'#stage'``` | ASwap wrapper selector |
156
+ | ```defaultDocumentScrollBehavior``` | ```'smooth'``` | Default document scroll behaviour |
157
157
  | ```trace``` | ```(message) => {}``` | A function to log stuff, eg in console |
158
158
 
159
159
  ### Controller class
@@ -204,6 +204,20 @@ RytmWebflow.aswap.init(params, {
204
204
  | ```onViewShow()``` | fired when the new scene is loaded and the show transition is being started |
205
205
  | ```onViewShown()``` | fired within ```animationTimeShow``` ms from show transition start |
206
206
 
207
+ ### Bootstrap integration ###
208
+ #### Bootstrap v5 ####
209
+ A common situation is to hide all Bootstrap offcanvases or modals when an ASwap page transition is in made. To do so just call the `RytmWebflow.bootsrap5.hideFlyovers()` method. You can also hide offcanvases or modals separatly by calling the `RytmWebflow.bootsrap5.hideOffcanvases()` or `RytmWebflow.bootsrap5.hideModals()` methods.
210
+ A basic usage example:
211
+ ```js
212
+ import RytmWebflow from 'rytm-webflow'
213
+
214
+ RytmWebflow.aswap.init(params, {
215
+ onViewHide: () => {
216
+ RytmWebflow.bootsrap5.hideFlyovers()
217
+ },
218
+ })
219
+ ```
220
+
207
221
  ## ShowUp ##
208
222
  ShowUp makes creating gsap scroll-triggered-animations much faster. It can be used to show content while user scrolls down the page. It can also be used for parallax like animations. ShowUp comes with the **Webflow syntax** - a minified way to describe an animation, it's duration (time), easing, delay or the trigger. Eg. `y:100,o:0` will animate an element from: `y:100px` and `opacity: 0` to it's current state. Go to [Webflow syntax](#markdown-header-webflow-syntax) for more.
209
223
  ### Webflow usage example
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rytm-webflow",
3
- "version": "1.1.3",
3
+ "version": "2.0.0",
4
4
  "description": "rytm webflow pack - ASwap, ShowUp",
5
5
  "main": "scripts/index.js",
6
6
  "scripts": {
@@ -18,7 +18,6 @@
18
18
  "dependencies": {
19
19
  "gsap": "^3.5.1",
20
20
  "imagesloaded": "^4.1.4",
21
- "jquery": "^3.1.1",
22
21
  "scrollmagic": "^2.0.7",
23
22
  "scrollmagic-plugin-gsap": "^1.0.4"
24
23
  }
@@ -1,4 +1,3 @@
1
- import $ from "jquery"
2
1
 
3
2
  import ASwapDispatcher from "./ASwapDispatcher";
4
3
  import Events from "./Events";
@@ -25,6 +24,7 @@ class ASwap {
25
24
  refreshOnSameUrl: true, // refresh window if same URL is requested
26
25
  routes: {},
27
26
  swapSelector: '#stage', // swap wrapper selector
27
+ defaultDocumentScrollBehavior: 'smooth',
28
28
  trace: () => {}, // a function to trace progress in console
29
29
  }
30
30
  // public events
@@ -102,7 +102,7 @@ class ASwap {
102
102
  this.events.onRequestLoad()
103
103
  }
104
104
  onRequestLoaded(e) {
105
- this.getControllersFromContainer(e.target.$freshContent).forEach( (c, index)=> {
105
+ this.getControllersFromContainer(e.target.freshContent).forEach( (c, index)=> {
106
106
  c.onRequestLoaded(e);
107
107
  });
108
108
  document.documentElement.classList.remove("as-request-loading");
@@ -112,7 +112,7 @@ class ASwap {
112
112
  document.documentElement.classList.add('as-hide');
113
113
  this.getActiveControlles().forEach( (c, index)=> {
114
114
  // if view is not present in fresh content then call controller hide
115
- if (!c.getViewContainer(e.target.$freshContent).length) {
115
+ if (!c.getViewContainer(e.target.freshContent)) {
116
116
  c.onViewHide(e);
117
117
  }
118
118
  });
@@ -122,34 +122,34 @@ class ASwap {
122
122
  document.documentElement.classList.remove('as-hide');
123
123
  this.getActiveControlles().forEach( (c, index)=> {
124
124
  // if view is not present in fresh content then call controller hidden
125
- if (!c.getViewContainer(e.target.$freshContent).length) {
125
+ if (!c.getViewContainer(e.target.freshContent)) {
126
126
  c.onViewHidden(e);
127
127
  }
128
128
  });
129
129
  this.events.onViewHidden()
130
130
  }
131
131
  onViewSwapStart(e) {
132
- this.getControllersFromContainer(e.target.$freshContent).forEach( (c, index)=> {
132
+ this.getControllersFromContainer(e.target.freshContent).forEach( (c, index)=> {
133
133
  c.onViewSwapStart(e);
134
134
  });
135
135
  this.events.onViewSwapStart()
136
136
  }
137
137
  onViewSwapComplete(e) {
138
- this.getControllersFromContainer(e.target.$freshContent).forEach( (c, index)=> {
138
+ this.getControllersFromContainer(e.target.freshContent).forEach( (c, index)=> {
139
139
  c.onViewSwapComplete(e);
140
140
  });
141
141
  this.events.onViewSwapComplete()
142
142
  }
143
143
  onViewShow(e) {
144
144
  document.documentElement.classList.add('as-show');
145
- this.getControllersFromContainer(e.target.$freshContent).forEach( (c, index)=> {
145
+ this.getControllersFromContainer(e.target.freshContent).forEach( (c, index)=> {
146
146
  c.onViewShow(e);
147
147
  });
148
148
  this.events.onViewShow()
149
149
  }
150
150
  onViewShown(e) {
151
151
  document.documentElement.classList.add('as-show');
152
- this.getControllersFromContainer(e.target.$freshContent).forEach( (c, index)=> {
152
+ this.getControllersFromContainer(e.target.freshContent).forEach( (c, index)=> {
153
153
  c.onViewShown(e);
154
154
  });
155
155
  document.documentElement.classList.remove('as-in-progress');
@@ -172,22 +172,20 @@ class ASwap {
172
172
  }
173
173
  /**
174
174
  * get controllers from container based on view's included in the container
175
- * @param {jQuery} $container
175
+ * @param container
176
176
  * @returns {Array}
177
177
  **/
178
- getControllersFromContainer($container) {
178
+ getControllersFromContainer(container) {
179
179
  let arr = [];
180
- $container.find("*[data-as-view]").each( (index, el)=> {
181
- let name = $(el).data("as-view");
182
- let id = $(el).data("as-id");
183
- if (!id) {
184
- id = name;
185
- }
186
- let c = this.getController(name, id);
180
+ const list = [...container.querySelectorAll("*[data-as-view]")]
181
+ list.forEach((el, index) => {
182
+ const name = el.dataset.asView
183
+ const id = el.dataset.asId ? el.dataset.asId : name
184
+ const c = this.getController(name, id)
187
185
  if (c) {
188
- arr.push(c);
186
+ arr.push(c)
189
187
  }
190
- });
188
+ })
191
189
  return arr;
192
190
  }
193
191
  /**
@@ -1,4 +1,3 @@
1
- import $ from "jquery"
2
1
  import Events from "./Events"
3
2
  import EventDispatcher from "./EventDispatcher"
4
3
 
@@ -24,7 +23,7 @@ class ASwapDispatcher extends EventDispatcher {
24
23
  this.prevUrl = null;
25
24
  this.ajaxStore = [];
26
25
  this.asHistory = [];
27
- this.$freshContent = $(this.swapSelector);
26
+ this.freshContent = document.querySelector(this.swapSelector);
28
27
 
29
28
  }
30
29
 
@@ -65,48 +64,61 @@ class ASwapDispatcher extends EventDispatcher {
65
64
  * @param tag {String} the tag name, eg. body
66
65
  * @returns {String|Boolean}
67
66
  **/
68
- getTagFromResult(result, tag) {
67
+ getTagFromResult(result, tag, index = 0) {
69
68
  let regex = new RegExp('<' + tag + '[^>]*>((.|[\n\r])*)<\/' + tag + '>');
70
69
  let body = regex.exec(result);
71
- if (body) {
72
- return body[0];
70
+ if (body && body[index]) {
71
+ return body[index];
73
72
  } else {
74
- this.warning("AS problem - " + tag + " could not be extracted");
73
+ this.warning("AS problem - " + tag + " could not be extracted, index:", idnex);
75
74
  return false;
76
75
  }
77
76
  }
77
+ /**
78
+ * ###
79
+ */
80
+ getElementFromResult(result, tagName) {
81
+ let htmlStr = this.getTagFromResult(result, tagName, 1)
82
+ let el = document.createElement(tagName)
83
+ el.innerHTML = htmlStr.trim()
84
+ return el
85
+ }
78
86
 
79
87
  /**
80
88
  * swap the meta and title tags in document's <head>
81
89
  * @param result {String} the ajax request result
82
90
  **/
83
91
  swapHeadMeta(result) {
84
- let head = this.getTagFromResult(result, "head");
85
- if (!head) {
92
+ const freshHead = this.getElementFromResult(result, "head")
93
+ if (!freshHead) {
86
94
  this.warning("AS problem - head was not found in result");
87
95
  return false;
88
96
  }
89
- let $head = $(head);
90
- $head.each( (index, el)=>{
91
- // swap only meta and title
92
- if ($(el).is('title')) {
93
- document.title = $(el).html();
94
- }
95
- if ($(el).is('meta')) {
96
- let name = $(el).attr("name");
97
- if (name) {
98
- $("html head meta[name='" + name + "']").attr("content", $(el).attr("content"));
99
- }
100
- let itemprop = $(el).attr("name");
101
- if (itemprop) {
102
- $("html head meta[itemprop='" + itemprop + "']").attr("content", $(el).attr("content"));
103
- }
104
- let property = $(el).attr("property");
105
- if (property) {
106
- $("html head meta[property='" + property + "']").attr("content", $(el).attr("content"));
107
- }
97
+ const list = [...freshHead.querySelectorAll("*")]
98
+ list.forEach((el, index) => {
99
+ // swap if TITLE or META
100
+ switch (el.nodeName.toLowerCase()) {
101
+ case "title":
102
+ document.title = el.innerHTML
103
+ break;
104
+ case "meta":
105
+ const name = el.getAttribute("name")
106
+ const property = el.getAttribute("property")
107
+ const itemprop = el.getAttribute("itemprop")
108
+ const content = el.getAttribute("content")
109
+ // get the meta query string
110
+ let query = 'html head meta'
111
+ query += (name ? '[name="' + name + '"' : '')
112
+ query += (property ? '[property="' + property + '"' : '')
113
+ query += (itemprop ? '[itemprop="' + itemprop + '"' : '')
114
+ let metaEl = document.querySelector(query)
115
+ if (metaEl && content) {
116
+ metaEl.setAttribute("content", content)
117
+ }
118
+ break;
108
119
  }
109
- });
120
+ })
121
+
110
122
  }
111
123
  /**
112
124
  * swap the HTML class names
@@ -134,8 +146,7 @@ class ASwapDispatcher extends EventDispatcher {
134
146
  }
135
147
  let html = document.createElement('html');
136
148
  html.innerHTML = body;
137
- let $resultBody = $(html).find('body');
138
- return $resultBody.find(this.swapSelector);
149
+ return html.querySelector(this.swapSelector)
139
150
  }
140
151
 
141
152
  /**
@@ -144,8 +155,8 @@ class ASwapDispatcher extends EventDispatcher {
144
155
  **/
145
156
  handleResult(result) {
146
157
  // store fresh content in public variable
147
- this.$freshContent = this.getFreshContentFromResult(result);
148
- let $swap = $(this.swapSelector);
158
+ this.freshContent = this.getFreshContentFromResult(result);
159
+ const swap = document.querySelector(this.swapSelector)
149
160
  // dispatch event
150
161
  this.dispatch(Events.NAV_REQUEST_LOADED);
151
162
  this.dispatch(Events.NAV_VIEW_HIDE);
@@ -155,17 +166,17 @@ class ASwapDispatcher extends EventDispatcher {
155
166
  this.asAnimTimeout1 = setTimeout(()=> {
156
167
  this.dispatch(Events.NAV_VIEW_HIDDEN);
157
168
  this.dispatch(Events.NAV_SWAP_START);
158
- if (this.$freshContent.length) {
159
- $swap.attr("class", this.$freshContent.attr("class")); // stage class
160
- $swap.html(this.$freshContent.html());
169
+ if (this.freshContent) {
170
+ // swap stage classes
171
+ swap.setAttribute("class", this.freshContent.getAttribute("class"))
172
+ // swap content
173
+ swap.innerHTML = this.freshContent.innerHTML
161
174
  }
162
175
  // swap head (meta)
163
176
  this.swapHeadMeta(result);
164
177
  setTimeout(() => {
165
178
  this.swapBodyToHtmlClasses(result);
166
179
  }, 10)
167
-
168
-
169
180
  // scroll up
170
181
  if (!this.currentTrigger || !this.currentTrigger.classList.contains(this.noScrollClassName)) {
171
182
  this.resetScrollPosition();
@@ -179,6 +190,7 @@ class ASwapDispatcher extends EventDispatcher {
179
190
  this.dispatch(Events.NAV_VIEW_SHOWN);
180
191
  }, this.animationTimeShow);
181
192
  }, this.animationTimeHide);
193
+
182
194
  }
183
195
  /**
184
196
  * get current URL
@@ -231,9 +243,18 @@ class ASwapDispatcher extends EventDispatcher {
231
243
  * scroll back up
232
244
  **/
233
245
  resetScrollPosition() {
234
- // $("html, body").animate({ scrollTop: "0" }, 300);
235
- $("html, body").scrollTop(0);
246
+ // set scrollBehavior to auto
247
+ document.documentElement.style.scrollBehavior = 'auto';
248
+ // scroll without animation
249
+ setTimeout(() => {
250
+ window.scrollTo(0, 0)
251
+ }, 5)
252
+ // set scrollBehavior to it's default value
253
+ setTimeout(() => {
254
+ document.documentElement.style.scrollBehavior = this.defaultDocumentScrollBehavior ? this.defaultDocumentScrollBehavior : 'smooth';
255
+ }, 5)
236
256
  }
257
+
237
258
  /**
238
259
  * Preload URL
239
260
  * @param url {String}
@@ -246,12 +267,15 @@ class ASwapDispatcher extends EventDispatcher {
246
267
  if (result) {
247
268
  return false
248
269
  }
249
- $.get(url, {}, (result)=> {
250
- if (result) {
251
- this.trace('URL was preloaded', url)
252
- this.storeResult(url, result);
270
+ let xhr = new XMLHttpRequest();
271
+ xhr.onreadystatechange = () => {
272
+ if (xhr.readyState === 4) {
273
+ // this.trace('URL was preloaded', url, xhr.responseText)
274
+ this.storeResult(url, xhr.responseText);
253
275
  }
254
- });
276
+ };
277
+ xhr.open('GET', url);
278
+ xhr.send();
255
279
 
256
280
  }
257
281
  /**
@@ -301,22 +325,21 @@ class ASwapDispatcher extends EventDispatcher {
301
325
  loadURL(url, data = {}, method = 'get', useCache = true) {
302
326
  // dispatch event
303
327
  this.dispatch(Events.NAV_REQUEST_LOAD);
304
- this.trace("ASwap load: ", url);
305
- $.ajax({
306
- type: method,
307
- url,
308
- data,
309
- success: (result) => {
310
- if (result) {
311
- if (useCache) {
312
- this.storeResult(url, result);
313
- }
314
- this.handleResult(result);
315
- } else {
316
- this.warning("AS problem - GET", url, "returned no result");
317
- }
318
- }
319
- });
328
+ this.trace("ASwap load: ", url);
329
+
330
+ let xhr = new XMLHttpRequest();
331
+ xhr.onreadystatechange = () => {
332
+ if (xhr.readyState === 4) {
333
+ if (useCache) {
334
+ this.storeResult(url, xhr.responseText);
335
+ }
336
+ this.handleResult(xhr.responseText);
337
+ } else {
338
+ this.warning("AS problem - GET", url, "returned no result");
339
+ }
340
+ };
341
+ xhr.open(method, url);
342
+ xhr.send(data);
320
343
  }
321
344
  /**
322
345
  * history pushState (URL)
@@ -337,7 +360,9 @@ class ASwapDispatcher extends EventDispatcher {
337
360
  * @param e {Event}
338
361
  **/
339
362
  onHistoryBack(e) {
363
+ e.preventDefault();
340
364
  let url = window.location.pathname + window.location.search;
365
+ console.log("HISTORY BACK", url)
341
366
  this.openURL(url, true);
342
367
  }
343
368
  /**
@@ -349,76 +374,94 @@ class ASwapDispatcher extends EventDispatcher {
349
374
  this.storeResult(url, result);
350
375
  this.currentUrl = url;
351
376
  }
352
- isLinkElementValid($a) {
377
+ isLinkElementValid(a) {
353
378
  let result = false
354
- if ($a.length) {
355
- if (!$a.hasClass(this.noSwapClassName) && $a.attr("target") != "_blank") {
379
+ if (a) {
380
+ if (!a.classList.contains(this.noSwapClassName) && a.getAttribute("target") != "_blank") {
356
381
  result = true
357
382
  }
358
383
  }
359
384
  return result
360
385
  }
361
- isFormElementValid($f) {
386
+ isFormElementValid(f) {
362
387
  let result = false
363
- if ($f.length) {
364
- if (!$f.hasClass(this.noSwapClassName)) {
388
+ if (f) {
389
+ if (!f.classList.contains(this.noSwapClassName)) {
365
390
  result = true
366
391
  }
367
392
  }
368
393
  return result
369
394
  }
395
+
396
+ /**
397
+ * ### Event handlers ###
398
+ */
399
+ onDocumentClick(e) {
400
+ if (e.target.tagName !== 'A') {
401
+ return;
402
+ }
403
+ const a = e.target
404
+ if (this.isLinkElementValid(a) && !e.metaKey & !e.ctrlKey) {
405
+ const useCache = !a.classList.contains(this.noCacheClassName);
406
+ const url = a.getAttribute("href");
407
+ if (url.indexOf('://') < 0) {
408
+ e.preventDefault()
409
+ this.currentTrigger = a
410
+ this.openURL(url, false, useCache);
411
+ }
412
+ }
413
+ }
414
+
415
+ onDocumentMouseover(e) {
416
+ if (e.target.tagName !== 'A') {
417
+ return;
418
+ }
419
+ const a = e.target
420
+ if (this.isLinkElementValid(a)) {
421
+ const useCache = !a.classList.contains(this.noCacheClassName);
422
+ if (useCache) {
423
+ const url = a.getAttribute("href");
424
+ this.preloadURL(url)
425
+ }
426
+ }
427
+ }
428
+ onDocumentSubmit(e) {
429
+ e.preventDefault();
430
+ if (e.target.tagName !== 'FORM') {
431
+ return;
432
+ }
433
+ const f = e.target
434
+ if (this.isFormElementValid(f)) {
435
+ const useCache = !f.classList.contains(this.noCacheClassName);
436
+ const url = f.getAttribute("action");
437
+ if (url.indexOf('://') < 0) {
438
+ e.preventDefault()
439
+ this.currentTrigger = f
440
+ const method = f.getAttribute('method') ? f.getAttribute('method') : 'get'
441
+ const dataStr = new URLSearchParams(new FormData(f)).toString()
442
+ const requestUrl = method == 'get' ? (url + '?' + dataStr) : url
443
+ this.submit(requestUrl, dataStr, method, false, useCache)
444
+ }
445
+
446
+ }
447
+
448
+ }
370
449
  /**
371
450
  * add event listeners
372
451
  **/
373
452
  addEventListeners() {
374
453
  // catch all a click events
375
- $("body").on("click", "a", (e)=> {
376
- let $a = $(e.currentTarget);
377
- // check black list, target _blank and if ctrl or cmd is not pressed
378
- if (this.isLinkElementValid($a) && !e.metaKey & !e.ctrlKey) {
379
- let useCache = !$a.hasClass(this.noCacheClassName);
380
- let url = $a.attr("href");
381
- if (url.indexOf('://') < 0) {
382
- e.preventDefault();
383
- this.currentTrigger = e.currentTarget
384
- this.openURL(url, false, useCache);
385
- }
386
- }
387
- });
454
+ document.addEventListener('click', this.onDocumentClick.bind(this), false)
388
455
  // preload on hover
389
456
  if (this.preloadOnHover) {
390
- $("body").on("mouseover", "a", (e)=> {
391
- let $a = $(e.currentTarget);
392
- if (this.isLinkElementValid($a)) {
393
- let useCache = !$a.hasClass(this.noCacheClassName);
394
- let url = $a.attr("href");
395
- if (useCache) {
396
- this.preloadURL(url)
397
- }
398
- }
399
- })
457
+ document.addEventListener('mouseover', this.onDocumentMouseover.bind(this), false)
400
458
  }
401
459
  // forms?
402
460
  if (this.formsEnabled) {
403
- $("body").on("submit", this.formsSelector, (e) => {
404
- let $f = $(e.currentTarget)
405
- if (this.isFormElementValid($f)) {
406
- let useCache = !$f.hasClass(this.noCacheClassName)
407
- let url = $f.attr('action')
408
- if (url.indexOf('://') < 0) {
409
- e.preventDefault()
410
- this.currentTrigger = e.currentTarget
411
- const data = $f.serialize()
412
- const method = $f.attr('method') ? $f.attr('method') : 'get'
413
- const requestUrl = method == 'get' ? (url + '?' + data) : url
414
- this.submit(requestUrl, data, method, false, useCache)
415
- }
416
- }
417
-
418
- })
461
+ document.addEventListener('submit', this.onDocumentSubmit.bind(this), false)
419
462
  }
420
- // window back button support
421
- $(window).on("popstate", this.onHistoryBack.bind(this));
463
+ // browser back button
464
+ window.addEventListener('popstate', this.onHistoryBack.bind(this), false)
422
465
  }
423
466
 
424
467
  initialDispatch() {
@@ -479,8 +522,8 @@ class ASwapDispatcher extends EventDispatcher {
479
522
  * init
480
523
  **/
481
524
  init() {
482
- let $swap = $(this.swapSelector);
483
- if (!$swap.length) {
525
+ const swap = document.querySelector(this.swapSelector)
526
+ if (!swap) {
484
527
  this.warning("AS problem - swap container not found!", this.swapSelector);
485
528
  return false;
486
529
  }
@@ -29,12 +29,10 @@ class Controller {
29
29
  return this.active;
30
30
  }
31
31
  /**
32
- * find my $view container in wrapper
33
- * @param {jQuery} $wrapper - search within this element
34
- * @retunrs {jQuery|Boolean} $view | false
32
+ * find my view container in wrapper
35
33
  **/
36
- getViewContainer($wrapper) {
37
- return $wrapper.find('*[data-as-id="' + this.id + '"]');
34
+ getViewContainer(wrapper) {
35
+ return wrapper.querySelector('*[data-as-id="' + this.id + '"]');
38
36
  }
39
37
 
40
38
  getContainerSelector() {
@@ -72,13 +70,13 @@ class Controller {
72
70
  **/
73
71
  onRequestLoaded(e) {
74
72
  if (!this.active && this.view) {
75
- this.view.prepare(e.target.$freshContent.get(0));
73
+ this.view.prepare(e.target.freshContent.get(0));
76
74
  }
77
75
  }
78
76
  /**
79
77
  * on view hide - animation out / hide start
80
78
  * request is loaded and fresh content is ready to init
81
- * loaded content available <code>e.target.$freshContent</code>
79
+ * loaded content available <code>e.target.freshContent</code>
82
80
  * @param {Event} e
83
81
  **/
84
82
  onViewHide(e) {
@@ -24,7 +24,7 @@ class ControllerImgLoad extends Controller {
24
24
  container.classList.add("as-images-loading")
25
25
  this.view.loadImagesStart(container);
26
26
  }
27
- imagesLoaded(this.getContainerSelector(), $.proxy(this.loadImagesComplete, this));
27
+ imagesLoaded(this.getContainerSelector(), this.loadImagesComplete.bind(this));
28
28
  }
29
29
  /**
30
30
  * load images complete
@@ -44,7 +44,7 @@ class ControllerImgLoad extends Controller {
44
44
  /**
45
45
  * on view hide - animation out / hide start
46
46
  * request is loaded and fresh content is ready to init
47
- * loaded content available <code>e.target.$freshContent</code>
47
+ * loaded content available <code>e.target.freshContent</code>
48
48
  * @param {Event} e
49
49
  **/
50
50
  onViewHide(e) {
@@ -20,7 +20,6 @@ class View {
20
20
  }
21
21
  /**
22
22
  * prepare (before show)
23
- * @param {jQuery} $container
24
23
  **/
25
24
  prepare(container) {
26
25
  }
@@ -0,0 +1,45 @@
1
+ import { Offcanvas, Modal } from 'bootstrap'
2
+
3
+ /**
4
+ * Bootstrap v5 helpers
5
+ */
6
+ class Bootstrap5 {
7
+ /**
8
+ * @constructor
9
+ **/
10
+ constructor() {
11
+ }
12
+ // # Hide all modals, offcanvases, etc.
13
+ hideFlyovers() {
14
+ this.hideModals()
15
+ this.hideOffcanvases()
16
+ }
17
+ // # Hide all modals #
18
+ hideModals() {
19
+ const list = [...document.querySelectorAll(".modal")]
20
+ list.forEach(this.hdieModal.bind(this))
21
+ }
22
+ // # Hide offcanvas element
23
+ hdieModal(el) {
24
+ const modal = Modal.getInstance(el)
25
+ if (modal) {
26
+ modal.hide()
27
+ }
28
+ }
29
+ // # Hide all offcanvases #
30
+ hideOffcanvases() {
31
+ const list = [...document.querySelectorAll(".offcanvas")]
32
+ list.forEach(this.hdieOffcanvas.bind(this))
33
+ }
34
+ // # Hide offcanvas element
35
+ hdieOffcanvas(el) {
36
+ const offcanvas = Offcanvas.getInstance(el)
37
+ if (offcanvas) {
38
+ offcanvas.hide()
39
+ }
40
+ }
41
+
42
+ }
43
+
44
+ const bootstrap5 = new Bootstrap5();
45
+ export default bootstrap5;
package/scripts/index.js CHANGED
@@ -2,6 +2,8 @@ import aswapInstance from './aswap/ASwap'
2
2
  import Controller from './aswap/Controller'
3
3
  import ControllerImgLoad from './aswap/ControllerImgLoad'
4
4
  import View from './aswap/View'
5
+ // Bootstrap v5 helper
6
+ import bootsrap5 from './bootstrap/v5/Bootstrap5'
5
7
  // showup
6
8
  import scrollController from './showup/ScrollController'
7
9
  import showUp from './showup/ShowUp'
@@ -13,6 +15,8 @@ export default {
13
15
  Controller,
14
16
  ControllerImgLoad,
15
17
  View,
18
+ // boottstrap
19
+ bootsrap5,
16
20
  // showup
17
21
  scrollController,
18
22
  showUp,
@@ -24,21 +24,35 @@ class ShowUp {
24
24
  this.buildParallaxScenes()
25
25
  this.addEventListeners()
26
26
  }
27
+ /**
28
+ * Class event handlers
29
+ */
30
+ handleEvent(e) {
31
+ switch (e.type) {
32
+ case 'resize':
33
+ this.onWindowUpdate(e)
34
+ break;
35
+ case 'DOMContentLoaded':
36
+ this.onWindowUpdate(e)
37
+ break;
38
+ }
39
+ }
27
40
  /**
28
41
  * Add event listeners
29
42
  */
30
43
  addEventListeners() {
31
- $(document).on('DOMContentLoaded load', $.proxy(this.onWindowUpdate, this))
32
- $(window).on('resize', $.proxy(this.onWindowUpdate, this))
44
+ window.addEventListener('resize', this)
45
+ document.addEventListener('DOMContentLoaded', this)
33
46
  }
34
47
  /**
35
48
  * Remove event listeners
36
49
  */
37
50
  removeEventListeners() {
38
- $(document).off('DOMContentLoaded load', $.proxy(this.onWindowUpdate, this));
39
- $(window).off('resize', $.proxy(this.onWindowUpdate, this));
51
+ window.removeEventListener('resize', this)
52
+ document.removeEventListener('DOMContentLoaded', this)
40
53
  }
41
54
  onWindowUpdate(e) {
55
+ console.log("show up WINDOW UPDATE,", this)
42
56
  if (this.scenes.length > 0) {
43
57
  scrollController.refresh()
44
58
  }