Skip to content

Commit 64f479f

Browse files
authored
Merge pull request #439 from fieg/trigger-factory
Trigger factory
2 parents 0242923 + e275485 commit 64f479f

File tree

6 files changed

+106
-9
lines changed

6 files changed

+106
-9
lines changed

docs/advanced/triggers.md

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,55 @@
11
# Triggers
22

3-
{% hint style='working' %}
4-
This feature is still work in progress
5-
{% endhint %}
6-
73
Instead of loading next pages on scroll you can use a trigger. A trigger is a link or button that has to be clicked before the next page is loaded.
84

95
Reasons for a trigger might be:
106

117
* To make the footer reachable.
128
* To ease the load on the server. Users have to click before loading the next page. This adds a natural delay.
139

10+
First add a button to your document
11+
12+
```html
13+
<button class="load-more">Load More</button>
14+
```
15+
16+
Next add a bit of CSS to make it look nice and hide if from view (opacity 0)
17+
18+
```css
19+
.load-more {
20+
display: inline-block;
21+
height: 32px;
22+
padding: 0 16px;
23+
border: 1px solid #aaa;
24+
border-radius: 4px;
25+
opacity: 0;
26+
font-family: Lucida Grande,Lucida Sans Unicode,Lucida Sans,Geneva,Arial,sans-serif;
27+
font-size: 14px;
28+
font-weight: 400;
29+
line-height: 30px;
30+
color: #555;
31+
background-color: #fff;
32+
cursor: pointer;
33+
transition: opacity .4s;
34+
}
35+
36+
.load-more:hover {
37+
color: #F63840;
38+
border: solid 1px #F63840;
39+
}
40+
```
41+
42+
Next configure the trigger.
43+
44+
```javascript
45+
let ias = new InfiniteAjaxScroll(/*..*/, {
46+
// other options here
47+
48+
trigger: '.load-more'
49+
});
50+
```
51+
52+
See [trigger options](../options.md#trigger) for information.
53+
54+
[View this behaviour in a live demo](https://infiniteajaxscroll.com/examples/button/)
55+

docs/options.md

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,17 +176,20 @@ You can also set advanced spinner options.
176176
```javascript
177177
let ias = new InfiniteAjaxScroll(/*..*/, {
178178
spinner: {
179-
// element
179+
// element to show as spinner
180180
element: '.spinner',
181+
181182
// delay in milliseconds
182183
// this is the minimal time the loader should be displayed. If loading takes longer, the spinner
183184
// will be shown for the duration of the loading. If the loading takes less then this duration,
184185
// say 300ms, then the spinner is still shown for 600ms.
185186
delay: 600,
187+
186188
// this function is called when the button has to be shown
187189
show: function(element) {
188190
element.style.opacity = '1'; // default behaviour
189191
},
192+
190193
// this function is called when the button has to be hidden
191194
hide: function(element) {
192195
element.style.opacity = '0'; // default behaviour
@@ -217,6 +220,16 @@ let ias = new InfiniteAjaxScroll(/*..*/, {
217220

218221
// alternatively we can pass an Element
219222
trigger: document.getElementById('trigger1'),
223+
224+
// we can also pass a factory function to create an Element
225+
trigger: function() {
226+
let el = document.createElement('button');
227+
el.innerText = 'Load More...';
228+
document.querySelector('.some_parent_class').appendChild(el);
229+
230+
// we have to return the element so IAS can add the necessary event listeners
231+
return el;
232+
},
220233
})
221234
```
222235

@@ -225,16 +238,19 @@ We can also set advanced trigger options.
225238
```javascript
226239
let ias = new InfiniteAjaxScroll(/*..*/, {
227240
trigger: {
228-
// element
241+
// element to show as trigger
229242
element: '.trigger',
243+
230244
// pass a function which returns true which determines if the load more button should be shown
231245
when: function(pageIndex) {
232246
return true; // default behaviour (always show a trigger)
233247
},
248+
234249
// this function is called when the button has to be shown
235250
show: function(element) {
236251
element.style.opacity = '1'; // default behaviour
237252
},
253+
238254
// this function is called when the button has to be hidden
239255
hide: function(element) {
240256
element.style.opacity = '0'; // default behaviour

examples/button/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
<div class="status">
1818
<div class="loader"></div>
19-
<button class="trigger">Load more</button>
19+
<button id="btn1" class="trigger">Load more</button>
2020
</div>
2121

2222
<script src="./index.js"></script>

examples/button/index.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,19 @@ window.ias = new InfiniteAjaxScroll('.blocks', {
3737
trigger: {
3838
element: '.trigger',
3939

40+
// alternatively we could pass an Element directly
41+
// element: document.getElementById('btn1'),
42+
43+
// alternatively we could pass a factory function
44+
// element: function() {
45+
// let el = document.createElement('button');
46+
// el.innerText = 'Load More...';
47+
// document.querySelector('.status').appendChild(el);
48+
//
49+
// // we have to return the element so IAS can add the necessary event listeners
50+
// return el;
51+
// },
52+
4053
// first page (pageIndex is -1) is generated, after that we show a load more button
4154
when: (pageIndex) => pageIndex >= 0,
4255

src/trigger.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,16 @@ const defaults = {
1515
};
1616

1717
function expand(options) {
18-
if (typeof options === 'string' || (typeof options === 'object' && options.nodeType === Node.ELEMENT_NODE)) {
18+
if (typeof options === 'string' || typeof options === 'function' || (typeof options === 'object' && options.nodeType === Node.ELEMENT_NODE)) {
1919
options = {
2020
element: options,
2121
}
2222
}
2323

24+
if (typeof options.element === 'function') {
25+
options.element = options.element();
26+
}
27+
2428
// expand array to a function, e.g.:
2529
// [0, 1, 2] -> function(pageIndex) { /* return true when pageIndex in [0, 1, 2] */ }
2630
if (options.when && Array.isArray(options.when)) {

test/trigger_spec.js

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ describe('Trigger', () => {
55
cy.visit('http://localhost:8080/test/fixtures/default/page1.html');
66
});
77

8-
it('accepts a selector', () => {
8+
it('should accept a selector', () => {
99
cy.InfiniteAjaxScroll().then((InfiniteAjaxScroll) => {
1010
let ias = new InfiniteAjaxScroll('.blocks', {
1111
item: '.blocks__block',
@@ -55,6 +55,28 @@ describe('Trigger', () => {
5555
});
5656
});
5757

58+
it('should accept a factory function', () => {
59+
cy.InfiniteAjaxScroll().then((InfiniteAjaxScroll) => {
60+
cy.document().then((doc) => {
61+
let ias = new InfiniteAjaxScroll('.blocks', {
62+
item: '.blocks__block',
63+
next: '.pager__next',
64+
trigger: () => {
65+
let el = doc.createElement('a');
66+
el.id = 'btn1';
67+
el.innerText = 'Load More Items';
68+
69+
doc.body.appendChild(el);
70+
71+
return el;
72+
},
73+
});
74+
75+
cy.get('#btn1').should((el) => expect(el[0]).to.be.eq(ias.trigger.element));
76+
});
77+
});
78+
});
79+
5880
it('should hide trigger on bind', () => {
5981
cy.InfiniteAjaxScroll().then((InfiniteAjaxScroll) => {
6082
let ias = new InfiniteAjaxScroll('.blocks', {

0 commit comments

Comments
 (0)