UNPKG

2.7 kBJavaScriptView Raw
1import extend from "extend";
2import Assert from "./assert";
3import $ from "tealight";
4import * as Events from "./events";
5
6const defaults = {
7 element: undefined,
8 when: (pageIndex) => true,
9 show: (element) => {
10 element.style.opacity = '1';
11 },
12 hide: (element) => {
13 element.style.opacity = '0';
14 }
15};
16
17function expand(options) {
18 if (typeof options === 'string' || typeof options === 'function' || (typeof options === 'object' && options.nodeType === Node.ELEMENT_NODE)) {
19 options = {
20 element: options,
21 }
22 }
23
24 if (typeof options.element === 'function') {
25 options.element = options.element();
26 }
27
28 // expand array to a function, e.g.:
29 // [0, 1, 2] -> function(pageIndex) { /* return true when pageIndex in [0, 1, 2] */ }
30 if (options.when && Array.isArray(options.when)) {
31 let when = options.when;
32 options.when = function(pageIndex) {
33 return when.indexOf(pageIndex) !== -1;
34 }
35 }
36
37 return options;
38}
39
40export default class Trigger {
41 constructor(ias, options) {
42 // no trigger wanted
43 if (options === false) {
44 return;
45 }
46
47 this.ias = ias;
48 this.options = extend({}, defaults, expand(options));
49
50 if (this.options.element !== undefined) {
51 Assert.singleElement(this.options.element, 'trigger.element');
52 }
53
54 this.element = $(this.options.element)[0]; // @todo should we really cache this?
55 this.hideFn = this.options.hide;
56 this.showFn = this.options.show;
57 this.voter = this.options.when;
58 this.showing = undefined;
59 this.enabled = undefined;
60
61 ias.on(Events.BINDED, this.bind.bind(this));
62 ias.on(Events.UNBINDED, this.unbind.bind(this));
63 ias.on(Events.HIT, this.hit.bind(this));
64 ias.on(Events.NEXT, (e) => this.ias.once(Events.APPENDED, () => this.update(e.pageIndex)));
65 }
66
67 bind() {
68 this.hide();
69 this.update(this.ias.pageIndex);
70
71 this.element.addEventListener('click', this.clickHandler.bind(this));
72 }
73
74 unbind() {
75 this.element.removeEventListener('click', this.clickHandler.bind(this));
76 }
77
78 clickHandler() {
79 this.hide().then(this.ias.next.bind(this.ias));
80 }
81
82 update(pageIndex) {
83 this.enabled = this.voter(pageIndex);
84
85 if (this.enabled) {
86 this.ias.disableLoadOnScroll();
87 } else {
88 this.ias.enableLoadOnScroll();
89 }
90 }
91
92 hit() {
93 if (!this.enabled) {
94 return;
95 }
96
97 this.show();
98 }
99
100 show() {
101 if (this.showing) {
102 return;
103 }
104
105 this.showing = true;
106
107 return Promise.resolve(this.showFn(this.element));
108 }
109
110 hide() {
111 if (!this.showing && this.showing !== undefined) {
112 return;
113 }
114
115 this.showing = false;
116
117 return Promise.resolve(this.hideFn(this.element));
118 }
119}