rytm-webflow 2.1.11 → 2.2.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 +14 -1
- package/package.json +1 -1
- package/scripts/aswap/ASwap.js +19 -2
- package/scripts/aswap/ASwapDispatcher.js +100 -19
package/README.md
CHANGED
|
@@ -142,7 +142,9 @@ RytmWebflow.aswap.init({
|
|
|
142
142
|
| ```animationTimeHide``` | ```800``` | Time (ms) for view's *hide* transition|
|
|
143
143
|
| ```animationTimeShow``` | ```800``` | Time (ms) for view's *show* transition|
|
|
144
144
|
| ```formsEnabled``` | ```true``` | Use *ASwap* on forms|
|
|
145
|
-
| ```formsSelector``` | ```'form
|
|
145
|
+
| ```formsSelector``` | ```'form'``` | *ASwap* forms selector|
|
|
146
|
+
| ```swipeEnabled``` | ```true``` | Use *ASwap* [swipe](#swipe)|
|
|
147
|
+
| ```swipeMinDistance``` | ```5``` | Minimum swipe move distance (px) for [swipe](#swipe) to fire|
|
|
146
148
|
| ```historyEnabled``` | ```true``` | Use history push state |
|
|
147
149
|
| ```historyFallback``` | ```true``` | Fallback if browser dosn't support history push state |
|
|
148
150
|
| ```cacheOn``` | ```true``` | By default all requests are being cached. Set to ```false``` to turn cache off |
|
|
@@ -218,6 +220,17 @@ RytmWebflow.aswap.init(params, {
|
|
|
218
220
|
},
|
|
219
221
|
})
|
|
220
222
|
```
|
|
223
|
+
## <a name="swipe">Swipe</a> ##
|
|
224
|
+
Add urls to `as-swipe-{direction}` data attributes, eg:
|
|
225
|
+
```html
|
|
226
|
+
<div
|
|
227
|
+
data-as-swipe-left="/path/to-next"
|
|
228
|
+
data-as-swipe-right="/path/to-prev"
|
|
229
|
+
data-as-swipe-up="/path/to-back">
|
|
230
|
+
...
|
|
231
|
+
</div>
|
|
232
|
+
```
|
|
233
|
+
|
|
221
234
|
## <a name="webflowview">WebflowView</a> ##
|
|
222
235
|
WebflowView is an universal ASwap View which can be used 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](#webflowsyntax) for more.
|
|
223
236
|
### Basic usage example
|
package/package.json
CHANGED
package/scripts/aswap/ASwap.js
CHANGED
|
@@ -12,7 +12,9 @@ class ASwap {
|
|
|
12
12
|
animationTimeHide: 800, // hide animation time
|
|
13
13
|
animationTimeShow: 800, // show animation time
|
|
14
14
|
formsEnabled: true, // use aswap on forms
|
|
15
|
-
formsSelector: 'form
|
|
15
|
+
formsSelector: 'form', // aswap forms selector
|
|
16
|
+
swipeEnabled: true, // use aswap `swipe`
|
|
17
|
+
swipeMinDistance: 5, // min swipe move distance
|
|
16
18
|
historyEnabled: true, // use history push state
|
|
17
19
|
historyFallback: true, // fallback of browser dosn't support history push state
|
|
18
20
|
cacheOn: true, // use Aswap Cache?
|
|
@@ -88,7 +90,22 @@ class ASwap {
|
|
|
88
90
|
this.dispatcher.openURL(url, noHistory, useCache);
|
|
89
91
|
}
|
|
90
92
|
}
|
|
91
|
-
|
|
93
|
+
/**
|
|
94
|
+
* clear cache
|
|
95
|
+
*/
|
|
96
|
+
clearCache(url = null) {
|
|
97
|
+
if (this.dispatcher) {
|
|
98
|
+
this.dispatcher.clearCache(url);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* submit form
|
|
103
|
+
*/
|
|
104
|
+
formSubmit(form) {
|
|
105
|
+
if (this.dispatcher) {
|
|
106
|
+
this.dispatcher.formSubmit(form);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
92
109
|
onRequestUrl(e) {
|
|
93
110
|
document.documentElement.classList.add('as-in-progress')
|
|
94
111
|
this.getActiveControlles().forEach( (c, index)=> {
|
|
@@ -58,6 +58,22 @@ class ASwapDispatcher extends EventDispatcher {
|
|
|
58
58
|
});
|
|
59
59
|
return result;
|
|
60
60
|
}
|
|
61
|
+
clearCache(url = null) {
|
|
62
|
+
if (url) {
|
|
63
|
+
this.clearCacheByUrl(url);
|
|
64
|
+
} else {
|
|
65
|
+
this.ajaxStore = [];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
clearCacheByUrl(url) {
|
|
69
|
+
let newStore = [];
|
|
70
|
+
this.ajaxStore.forEach( (r, index)=> {
|
|
71
|
+
if (r.url !== url) {
|
|
72
|
+
newStore.push(r);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
this.ajaxStore = newStore;
|
|
76
|
+
}
|
|
61
77
|
/**
|
|
62
78
|
* parse the result and return content between a tag, eg. <body></body>
|
|
63
79
|
* @param result {String} the ajax request result
|
|
@@ -281,6 +297,22 @@ class ASwapDispatcher extends EventDispatcher {
|
|
|
281
297
|
xhr.send();
|
|
282
298
|
|
|
283
299
|
}
|
|
300
|
+
/**
|
|
301
|
+
* Form submit
|
|
302
|
+
*/
|
|
303
|
+
formSubmit(form) {
|
|
304
|
+
const useCache = !form.classList.contains(this.noCacheClassName);
|
|
305
|
+
const url = form.getAttribute("action");
|
|
306
|
+
if (url.indexOf('://') < 0) {
|
|
307
|
+
this.currentTrigger = form
|
|
308
|
+
const method = form.getAttribute('method') ? form.getAttribute('method') : 'get'
|
|
309
|
+
const formData = new FormData(form);
|
|
310
|
+
this.submit(url, formData, method, false, useCache);
|
|
311
|
+
// const dataStr = new URLSearchParams(formData).toString();
|
|
312
|
+
// const requestUrl = method == 'get' ? (url + '?' + dataStr) : url;
|
|
313
|
+
// this.submit(requestUrl, formData, method, false, useCache);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
284
316
|
/**
|
|
285
317
|
*
|
|
286
318
|
* @param {string} url
|
|
@@ -289,7 +321,7 @@ class ASwapDispatcher extends EventDispatcher {
|
|
|
289
321
|
* @param {boolean} noHistory
|
|
290
322
|
* @param {boolean} useCache
|
|
291
323
|
*/
|
|
292
|
-
submit(url,
|
|
324
|
+
submit(url, formData, method, noHistory = false, useCache = true) {
|
|
293
325
|
// dispatch event
|
|
294
326
|
this.dispatch(Events.NAV_REQUEST_URL);
|
|
295
327
|
this.prevUrl = this.currentUrl;
|
|
@@ -297,11 +329,22 @@ class ASwapDispatcher extends EventDispatcher {
|
|
|
297
329
|
if (!noHistory) {
|
|
298
330
|
this.pushState(url);
|
|
299
331
|
}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
332
|
+
switch (method) {
|
|
333
|
+
case 'post':
|
|
334
|
+
// POST
|
|
335
|
+
this.loadURL(url, formData, method, false);
|
|
336
|
+
break;
|
|
337
|
+
default:
|
|
338
|
+
// GET
|
|
339
|
+
const dataStr = new URLSearchParams(formData).toString();
|
|
340
|
+
url = method == 'get' ? (url + '?' + dataStr) : url;
|
|
341
|
+
let result = useCache ? this.getStoredResult(url) : null;
|
|
342
|
+
if (result) {
|
|
343
|
+
this.handleResult(result);
|
|
344
|
+
} else {
|
|
345
|
+
this.loadURL(url, formData, method, useCache);
|
|
346
|
+
}
|
|
347
|
+
break;
|
|
305
348
|
}
|
|
306
349
|
}
|
|
307
350
|
/**
|
|
@@ -330,7 +373,6 @@ class ASwapDispatcher extends EventDispatcher {
|
|
|
330
373
|
// dispatch event
|
|
331
374
|
this.dispatch(Events.NAV_REQUEST_LOAD);
|
|
332
375
|
this.trace("ASwap load: ", url);
|
|
333
|
-
|
|
334
376
|
let xhr = new XMLHttpRequest();
|
|
335
377
|
xhr.onreadystatechange = () => {
|
|
336
378
|
if (xhr.readyState === 4) {
|
|
@@ -427,22 +469,56 @@ class ASwapDispatcher extends EventDispatcher {
|
|
|
427
469
|
}
|
|
428
470
|
}
|
|
429
471
|
}
|
|
472
|
+
// SUBMIT
|
|
430
473
|
onDocumentSubmit(e) {
|
|
431
474
|
if (e.target.tagName == 'FORM') {
|
|
432
|
-
|
|
433
|
-
if (this.isFormElementValid(f)) {
|
|
475
|
+
if (this.isFormElementValid(e.target)) {
|
|
434
476
|
e.preventDefault();
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
477
|
+
this.formSubmit(e.target);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
// Swipe touch start event
|
|
482
|
+
handleTouchStart = (e) => {
|
|
483
|
+
const firstTouch = e.touches[0];
|
|
484
|
+
this.xDown = firstTouch.clientX;
|
|
485
|
+
this.yDown = firstTouch.clientY;
|
|
486
|
+
}
|
|
487
|
+
// Swipe touch move event
|
|
488
|
+
handleTouchMove = (e) => {
|
|
489
|
+
if ( !this.xDown || !this.yDown ) {
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
|
+
const xUp = e.touches[0].clientX;
|
|
493
|
+
const yUp = e.touches[0].clientY;
|
|
494
|
+
const xDiff = this.xDown - xUp;
|
|
495
|
+
const yDiff = this.yDown - yUp;
|
|
496
|
+
if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) {
|
|
497
|
+
if (Math.abs(xDiff) > this.swipeMinDistance) {
|
|
498
|
+
if ( xDiff > 0 ) {
|
|
499
|
+
this.handleSwipe(e, 'left');
|
|
500
|
+
} else {
|
|
501
|
+
this.handleSwipe(e, 'right');
|
|
444
502
|
}
|
|
445
|
-
|
|
503
|
+
}
|
|
504
|
+
} else if (Math.abs(yDiff) > this.swipeMinDistance) {
|
|
505
|
+
if ( yDiff > 0 ) {
|
|
506
|
+
this.handleSwipe(e, 'up');
|
|
507
|
+
} else {
|
|
508
|
+
this.handleSwipe(e, 'down');
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
/* reset values */
|
|
512
|
+
this.xDown = null;
|
|
513
|
+
this.yDown = null;
|
|
514
|
+
}
|
|
515
|
+
// handle SWIPE direction
|
|
516
|
+
handleSwipe = (e, direction) => {
|
|
517
|
+
const d = e.target.closest('[data-as-swipe-' + direction + ']')
|
|
518
|
+
if (d) {
|
|
519
|
+
const path = d.getAttribute('data-as-swipe-' + direction);
|
|
520
|
+
if (path) {
|
|
521
|
+
this.openURL(path);
|
|
446
522
|
}
|
|
447
523
|
}
|
|
448
524
|
}
|
|
@@ -460,6 +536,11 @@ class ASwapDispatcher extends EventDispatcher {
|
|
|
460
536
|
if (this.formsEnabled) {
|
|
461
537
|
document.addEventListener('submit', this.onDocumentSubmit.bind(this), false)
|
|
462
538
|
}
|
|
539
|
+
// swipe?
|
|
540
|
+
if (this.swipeEnabled) {
|
|
541
|
+
document.addEventListener('touchstart', this.handleTouchStart, false);
|
|
542
|
+
document.addEventListener('touchmove', this.handleTouchMove, false);
|
|
543
|
+
}
|
|
463
544
|
// browser back button
|
|
464
545
|
window.addEventListener('popstate', this.onHistoryBack.bind(this), false)
|
|
465
546
|
}
|