-
Notifications
You must be signed in to change notification settings - Fork 0
/
loadMore.js
121 lines (107 loc) · 3.14 KB
/
loadMore.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
( function ( $ ) {
/**
* Class Loadmore.
*/
class LoadMore {
/**
* Contructor.
*/
constructor() {
this.ajaxUrl = siteConfig?.ajaxUrl ?? '';
this.ajaxNonce = siteConfig?.ajax_nonce ?? '';
this.loadMoreBtn = $( '#load-more' );
this.loadingTextEl = $( '#loading-text' );
this.isRequestProcessing = false;
this.options = {
root: null,
rootMargin: '0px',
threshold: 1.0, // 1.0 means set isIntersecting to true when element comes in 100% view.
};
this.init();
}
init() {
if ( ! this.loadMoreBtn.length ) {
return;
}
this.totalPagesCount = $( '#post-pagination' ).data( 'max-pages' );
/**
* Add the IntersectionObserver api, and listen to the load more intersection status.
* so that intersectionObserverCallback gets called if the element intersection status changes.
*
* @type {IntersectionObserver}
*/
const observer = new IntersectionObserver(
( entries ) => this.intersectionObserverCallback( entries ),
this.options
);
observer.observe( this.loadMoreBtn[ 0 ] );
}
/**
* Gets called on initial render with status 'isIntersecting' as false and then
* everytime element intersection status changes.
*
* @param {array} entries No of elements under observation.
*
*/
intersectionObserverCallback( entries ) {
// array of observing elements
// The logic is apply for each entry ( in this case it's just one loadmore button )
entries.forEach( ( entry ) => {
// If load more button in view.
if ( entry?.isIntersecting ) {
this.handleLoadMorePosts();
}
} );
}
/**
* Load more posts.
*
* 1.Make an ajax request, by incrementing the page no. by one on each request.
* 2.Append new/more posts to the existing content.
* 3.If the response is 0 ( which means no more posts available ), remove the load-more button from DOM.
* Once the load-more button gets removed, the IntersectionObserverAPI callback will not be triggered, which means
* there will be no further ajax request since there won't be any more posts available.
*
* @return null
*/
handleLoadMorePosts() {
// Get page no from data attribute of load-more button.
const page = this.loadMoreBtn.data( 'page' );
if ( ! page || this.isRequestProcessing ) {
return null;
}
const nextPage = parseInt( page ) + 1; // Increment page count by one.
this.isRequestProcessing = true;
$.ajax( {
url: this.ajaxUrl,
type: 'post',
data: {
page: page,
action: 'load_more',
ajax_nonce: this.ajaxNonce,
},
success: ( response ) => {
this.loadMoreBtn.data( 'page', nextPage );
$( '#load-more-content' ).append( response );
this.removeLoadMoreIfOnLastPage( nextPage );
this.isRequestProcessing = false;
},
error: ( response ) => {
console.log( response );
this.isRequestProcessing = false;
},
} );
}
/**
* Remove Load more Button If on last page.
*
* @param {int} nextPage New Page.
*/
removeLoadMoreIfOnLastPage( nextPage ) {
if ( nextPage + 1 > this.totalPagesCount ) {
this.loadMoreBtn.remove();
}
}
}
new LoadMore();
} )( jQuery );