Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 46 additions & 4 deletions docs/advanced/triggers.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,55 @@
# Triggers

{% hint style='working' %}
This feature is still work in progress
{% endhint %}

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.

Reasons for a trigger might be:

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

First add a button to your document

```html
<button class="load-more">Load More</button>
```

Next add a bit of CSS to make it look nice and hide if from view (opacity 0)

```css
.load-more {
display: inline-block;
height: 32px;
padding: 0 16px;
border: 1px solid #aaa;
border-radius: 4px;
opacity: 0;
font-family: Lucida Grande,Lucida Sans Unicode,Lucida Sans,Geneva,Arial,sans-serif;
font-size: 14px;
font-weight: 400;
line-height: 30px;
color: #555;
background-color: #fff;
cursor: pointer;
transition: opacity .4s;
}

.load-more:hover {
color: #F63840;
border: solid 1px #F63840;
}
```

Next configure the trigger.

```javascript
let ias = new InfiniteAjaxScroll(/*..*/, {
// other options here

trigger: '.load-more'
});
```

See [trigger options](../options.md#trigger) for information.

[View this behaviour in a live demo](https://infiniteajaxscroll.com/examples/button/)

20 changes: 18 additions & 2 deletions docs/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,17 +176,20 @@ You can also set advanced spinner options.
```javascript
let ias = new InfiniteAjaxScroll(/*..*/, {
spinner: {
// element
// element to show as spinner
element: '.spinner',

// delay in milliseconds
// this is the minimal time the loader should be displayed. If loading takes longer, the spinner
// will be shown for the duration of the loading. If the loading takes less then this duration,
// say 300ms, then the spinner is still shown for 600ms.
delay: 600,

// this function is called when the button has to be shown
show: function(element) {
element.style.opacity = '1'; // default behaviour
},

// this function is called when the button has to be hidden
hide: function(element) {
element.style.opacity = '0'; // default behaviour
Expand Down Expand Up @@ -217,6 +220,16 @@ let ias = new InfiniteAjaxScroll(/*..*/, {

// alternatively we can pass an Element
trigger: document.getElementById('trigger1'),

// we can also pass a factory function to create an Element
trigger: function() {
let el = document.createElement('button');
el.innerText = 'Load More...';
document.querySelector('.some_parent_class').appendChild(el);

// we have to return the element so IAS can add the necessary event listeners
return el;
},
})
```

Expand All @@ -225,16 +238,19 @@ We can also set advanced trigger options.
```javascript
let ias = new InfiniteAjaxScroll(/*..*/, {
trigger: {
// element
// element to show as trigger
element: '.trigger',

// pass a function which returns true which determines if the load more button should be shown
when: function(pageIndex) {
return true; // default behaviour (always show a trigger)
},

// this function is called when the button has to be shown
show: function(element) {
element.style.opacity = '1'; // default behaviour
},

// this function is called when the button has to be hidden
hide: function(element) {
element.style.opacity = '0'; // default behaviour
Expand Down
2 changes: 1 addition & 1 deletion examples/button/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

<div class="status">
<div class="loader"></div>
<button class="trigger">Load more</button>
<button id="btn1" class="trigger">Load more</button>
</div>

<script src="./index.js"></script>
Expand Down
13 changes: 13 additions & 0 deletions examples/button/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,19 @@ window.ias = new InfiniteAjaxScroll('.blocks', {
trigger: {
element: '.trigger',

// alternatively we could pass an Element directly
// element: document.getElementById('btn1'),

// alternatively we could pass a factory function
// element: function() {
// let el = document.createElement('button');
// el.innerText = 'Load More...';
// document.querySelector('.status').appendChild(el);
//
// // we have to return the element so IAS can add the necessary event listeners
// return el;
// },

// first page (pageIndex is -1) is generated, after that we show a load more button
when: (pageIndex) => pageIndex >= 0,

Expand Down
6 changes: 5 additions & 1 deletion src/trigger.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,16 @@ const defaults = {
};

function expand(options) {
if (typeof options === 'string' || (typeof options === 'object' && options.nodeType === Node.ELEMENT_NODE)) {
if (typeof options === 'string' || typeof options === 'function' || (typeof options === 'object' && options.nodeType === Node.ELEMENT_NODE)) {
options = {
element: options,
}
}

if (typeof options.element === 'function') {
options.element = options.element();
}

// expand array to a function, e.g.:
// [0, 1, 2] -> function(pageIndex) { /* return true when pageIndex in [0, 1, 2] */ }
if (options.when && Array.isArray(options.when)) {
Expand Down
24 changes: 23 additions & 1 deletion test/trigger_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ describe('Trigger', () => {
cy.visit('http://localhost:8080/test/fixtures/default/page1.html');
});

it('accepts a selector', () => {
it('should accept a selector', () => {
cy.InfiniteAjaxScroll().then((InfiniteAjaxScroll) => {
let ias = new InfiniteAjaxScroll('.blocks', {
item: '.blocks__block',
Expand Down Expand Up @@ -55,6 +55,28 @@ describe('Trigger', () => {
});
});

it('should accept a factory function', () => {
cy.InfiniteAjaxScroll().then((InfiniteAjaxScroll) => {
cy.document().then((doc) => {
let ias = new InfiniteAjaxScroll('.blocks', {
item: '.blocks__block',
next: '.pager__next',
trigger: () => {
let el = doc.createElement('a');
el.id = 'btn1';
el.innerText = 'Load More Items';

doc.body.appendChild(el);

return el;
},
});

cy.get('#btn1').should((el) => expect(el[0]).to.be.eq(ias.trigger.element));
});
});
});

it('should hide trigger on bind', () => {
cy.InfiniteAjaxScroll().then((InfiniteAjaxScroll) => {
let ias = new InfiniteAjaxScroll('.blocks', {
Expand Down