assets/js/frontend/auto-load-next-post.dev.js
// Variables
var version = auto_load_next_post_params.alnp_version,
content_container = auto_load_next_post_params.alnp_content_container,
post_title_selector = auto_load_next_post_params.alnp_title_selector,
nav_container = auto_load_next_post_params.alnp_navigation_container,
comments_container = auto_load_next_post_params.alnp_comments_container,
remove_comments = auto_load_next_post_params.alnp_remove_comments,
track_pageviews = auto_load_next_post_params.alnp_google_analytics,
is_customizer = auto_load_next_post_params.alnp_is_customizer,
is_mobile = auto_load_next_post_params.alnp_is_mobile,
event_on_load = auto_load_next_post_params.alnp_event_on_load,
event_on_entering = auto_load_next_post_params.alnp_event_on_entering,
post_title = window.document.title,
curr_url = window.location.href,
orig_curr_url = window.location.href,
post_count = 0,
post_url = curr_url,
overridden_post_url = '',
stop_reading = false,
scroll_up = false,
article_container = 'article',
ready = auto_load_next_post_params.alnp_load_in_footer,
disable_mobile = auto_load_next_post_params.alnp_disable_mobile;
(function($) {
// Ensure auto_load_next_post_params exists to continue.
if ( typeof auto_load_next_post_params === 'undefined' ) {
return false;
}
// Stop Auto Load Next Post from running if disabled for mobile devices.
if ( is_mobile == 'yes' && disable_mobile ) {
return false;
}
/**
* Ensure the main required selectors are set before continuing.
*
* 1. Content Container
* 2. Post Title
* 3. Post Navigation
*/
if ( content_container.length <= 0 ) {
console.error( 'Auto Load Next Post requires that you set the content container selector.' );
return false;
}
if ( post_title_selector.length <= 0 ) {
console.error( 'Auto Load Next Post requires that you set the post title selector.' );
return false;
}
if ( nav_container.length <= 0 ) {
console.error( 'Auto Load Next Post requires that you set the post navigation container selector.' );
return false;
}
// Do we load right away or wait until the page has finished loading?
if ( ready == false ) {
// Run Auto Load Next Post once the document is ready.
$( document ).ready(function () {
run_alnp();
});
}
// Run Auto Load Next Post.
if ( ready ) {
run_alnp();
}
// This function runs the Auto Load Next Post script.
function run_alnp() {
if ( $( 'article' ).length <= 0 ) {
console.log( 'HTML5 semantics for article has not been found. Setting compatible HTML semantic.' );
article_container = 'div';
}
if ( is_customizer == 'yes' ) {
console.log( 'You are previewing with the customizer.' );
}
console.log( 'Auto Load Next Post is version: ' + version );
// Don't do anything if post was loaded looking for comments.
if ( orig_curr_url.indexOf( '#comments' ) > -1 || orig_curr_url.match(/#comment-*([0-9]+)/) ) {
console.log( 'Auto Load Next Post is disabled while requested to view comments.' );
return;
}
// Don't do anything if post was loaded to post a comment.
if ( orig_curr_url.indexOf( '#respond' ) > -1 ) {
console.log( 'Auto Load Next Post is disabled while requested to respond and post a comment.' );
return;
}
// Add a post divider.
$( content_container ).prepend( '<hr style="height:0px;margin:0px;padding:0px;border:none;" data-powered-by="alnp" data-initial-post="true" data-title="' + post_title + '" data-url="' + orig_curr_url + '"/>' );
// Mark the first article as the initial post.
$( content_container ).find( article_container ).attr( 'data-initial-post', true );
// Find the post ID of the initial loaded article.
var initial_post_id = $( content_container ).find( article_container ).attr( 'id' );
// Apply post ID to the first post divider if found.
if ( typeof initial_post_id !== 'undefined' && initial_post_id.length > 0 ) {
initial_post_id = initial_post_id.replace( 'post-', '' ); // Make sure that only the post ID remains.
console.log( 'Initial Post ID: ' + initial_post_id );
$( content_container ).find( 'article[data-initial-post]' ).prev().attr( 'data-post-id', initial_post_id );
}
console.log( 'Post URL: ' + post_url );
console.log( 'Post Count: ' + post_count );
// Remove Comments.
if ( remove_comments === 'yes' ) {
$( comments_container ).remove();
// Remove Disqus comments if found.
if ( $( '#disqus_thread' ).length > 0 ) {
$( '#disqus_thread' ).remove();
}
if ( $( comments_container ).length <= 0 ) {
console.log( 'Comments have been removed' );
}
}
// Initialise scrollSpy
scrollspy();
$( 'body' ).on( 'alnp-enter', function( e ) {
console.log( 'Entering new post' );
});
$( 'body' ).on( 'alnp-leaving', function( e ) {
console.log( 'Leaving post' );
});
/**
* Track pageviews with Google Analytics.
*
* It will first detect if Google Analytics is installed before
* attempting to send a pageview.
*
* The tracker detects both classic and universal tracking methods.
*
* Also supports Google Analytics by Monster Insights should it be used.
*/
$( 'body' ).on( 'alnp-post-changed', function( e, post_title, post_url, post_id, post_count, stop_reading ) {
if ( track_pageviews != 'yes' ) {
return;
}
// If we are previewing in the customizer then dont track.
if ( is_customizer == 'yes' ) {
console.log( 'Google Analytics tracking is disabled when previewing in the customizer.' );
return;
}
console.log( 'Google Analytics tracking is enabled' );
if ( typeof _gaq === 'undefined' && typeof ga === 'undefined' && typeof __gaTracker === 'undefined' ) {
console.error( 'Google Analytics was not found installed on your site!' );
return;
}
console.log( 'Post URL before clean: ' + post_url );
// Clean Post URL before tracking.
post_url = post_url.replace(/https?:\/\/[^\/]+/i, '');
console.log( 'Post URL after clean: ' + post_url );
// This uses Google's classic Google Analytics tracking method.
if ( typeof _gaq !== 'undefined' && _gaq !== null ) {
console.log( 'Google Analytics is installed but you are using a classic version. Recommend upgrading!' );
_gaq.push(['_trackPageview', post_url]);
}
// This uses Google Analytics Universal Analytics tracking method.
if ( typeof ga !== 'undefined' && ga !== null ) {
console.log( 'Google Analytics Universal Analytics is installed. Yahoo!' );
ga( 'send', 'pageview', post_url );
}
// This uses Monster Insights method of tracking Google Analytics.
if ( typeof __gaTracker !== 'undefined' && __gaTracker !== null ) {
console.log( 'Google Analytics by MonsterInsights is installed. Awesome!' );
__gaTracker( 'send', 'pageview', post_url );
}
});
// If the browser back button is pressed or the user scrolled up then change history state.
$( 'body' ).on( 'mousewheel', function( e ) {
scroll_up = e.originalEvent.wheelDelta > 0;
});
// Update the History ONLY if we are NOT in the customizer.
if ( ! is_customizer ) {
// Note: We are using statechange instead of popstate
History.Adapter.bind( window, 'statechange', function() {
var state = History.getState(); // Note: We are using History.getState() instead of event.state
console.log(state);
// If they returned back to the first post, then when you click the back button go to the url from which they came.
if ( scroll_up ) {
var states = History.savedStates;
var prev_state_index = states.length - 2;
var prev_state = states[prev_state_index];
console.log( 'Previous URL: ', prev_state.url );
if ( prev_state.url === orig_curr_url ) {
window.location = document.referrer;
return;
}
}
// If the previous URL does not match the current URL then go back.
if ( state.url != curr_url ) {
var previous_post = $( 'hr[data-url="' + state.url + '"]' ).next( article_container ).find( post_title_selector );
// Is there a previous post?
if ( previous_post.length > 0 ) {
var previous_post_title = previous_post[0].dataset.title;
console.log( 'Previous Post: ' + previous_post_title );
History.pushState(null, previous_post_title, state.url);
// Scroll to the top of the previous article.
$( 'html, body' ).animate({ scrollTop: (previous_post.offset().top - 100) }, 1000, function() {
$( 'body' ).trigger( 'alnp-previous-post', [ previous_post ] );
});
}
}
});
}
} // END run_alnp()
/**
* ScrollSpy.
*
* 1. Load a new post once the post comes near the end.
* 2. If a new post has loaded and comes into view, change the URL in the browser
* address bar and the post title for history.
*
* This is done by looking for the post divider.
*/
function scrollspy() {
// Do not enter once the initial post has loaded.
if ( post_count > 0 ) {
$( 'hr[data-powered-by="alnp"]' ).on( 'scrollSpy:enter', alnp_enter );
}
$( 'hr[data-powered-by="alnp"]' ).on( 'scrollSpy:exit', alnp_leave ); // Loads next post.
$( 'hr[data-powered-by="alnp"]' ).scrollSpy();
} // END scrollspy()
// Trigger multiple events
function triggerEvents(events, params) {
if (typeof events !== 'string') return;
var body = jQuery( 'body' );
events = events.split(',');
for (var i = 0; i < events.length; i++) {
//support all browsers, "replace" instead of "trim"
events[i] = events[i].replace(/^\s\s*/, '').replace(/\s\s*$/, '');
body.trigger(events[i], params);
}
return this;
}
// Entering a post
function alnp_enter() {
var divider = $(this);
$( 'body' ).trigger( 'alnp-enter', [ divider ] );
triggerEvents(event_on_entering, [ divider ]);
changePost( divider, 'enter' );
} // END alnp_enter()
// Leaving a post
function alnp_leave() {
var divider = $(this);
$( 'body' ).trigger( 'alnp-leave', [ divider ] );
changePost( divider, 'leave' );
} // END alnp_leave()
// Change Post
function changePost( divider, $direction ) {
var el = $(divider);
var this_url = el.attr( 'data-url' );
var this_title = el.attr( 'data-title' );
var this_post_id = el.attr( 'data-post-id' );
var initial_post = el.attr( 'data-initial-post' );
var offset = el.offset();
var scrollTop = $( document ).scrollTop();
// If exiting or entering from the top, then change the URL.
if ( ( offset.top - scrollTop ) <= 200 && curr_url != this_url ) {
curr_url = this_url;
// Update the History ONLY if we are NOT in the customizer.
if ( ! is_customizer ) {
History.pushState(null, this_title, this_url);
}
$( 'body' ).trigger( 'alnp-post-changed', [ this_title, this_url, this_post_id, post_count, stop_reading, initial_post ] );
}
console.log( 'Direction: ' + $direction);
// Look for the next post to load if any when leaving previous post.
if ( $direction == 'leave' ) {
auto_load_next_post();
}
} // END changePost()
/**
* This is the main function.
*/
function auto_load_next_post() {
// If the user can not read any more then stop looking for new posts.
if ( stop_reading ) {
return;
}
// Reset the overridden post URL.
overridden_post_url = '';
if ( !overridden_post_url ) {
console.log( 'Post is not overridden!' );
}
// This helps prevent causing an undefined URL.
if ( $( nav_container ).length <= 0 ) {
console.log( 'Post navigation container was not found!' );
return;
}
// Grab the url for the next post in the post navigation.
post_url = $( nav_container ).find( 'a[rel="prev"]').attr( 'href' );
// If the post url returns nothing then try finding the alternative and set that as the next post.
if ( !post_url ) {
post_url = $( nav_container ).find( 'a[rel="previous"]').attr( 'href' );
}
// If we are in the customizer then clean the post url before fetching the post.
if ( is_customizer == 'yes' ) {
post_url = post_url.substring(0, post_url.indexOf("?"));
}
// Override the post url via a trigger.
$( 'body' ).trigger( 'alnp-post-url', [ post_count, post_url ] );
// If post URL is overridden then update post_url variable.
if ( overridden_post_url ) {
console.log( 'Post has been overridden!' );
post_url = overridden_post_url;
}
// For some browsers, `post_url` is undefined; for others,
// `post_url` is false. So we check for both possibilites.
if ( typeof post_url !== typeof undefined && post_url !== false ) {
console.log( 'Post URL was defined. Next Post URL: ' + post_url );
} else {
console.error( 'Unable to find another post to load!' );
}
// If the post navigation is not found then dont continue.
if ( !post_url ) return;
// Define next post URL to load.
var np_url = '';
// Check to see if pretty permalinks, if not then add alnp=1
if ( post_url.indexOf( '?p=' ) > -1 ) {
np_url = post_url + '&alnp=1';
} else {
var partial_endpoint = 'alnp/';
if ( post_url.charAt(post_url.length - 1) != '/' )
partial_endpoint = '/' + partial_endpoint;
np_url = post_url + partial_endpoint;
}
// Remove the post navigation HTML once the next post has loaded.
$( nav_container ).remove();
if ( $( nav_container ).length <= 0 ) {
console.log( 'Post Navigation Removed!' );
}
$.get( np_url , function( data ) {
var post = $( "<div>" + data + "</div>" );
// Allows the post data to be modified before being appended.
$( 'body' ).trigger( 'alnp-post-data', [ post ] );
data = post.html(); // Returns the HTML data of the next post that was loaded.
var post_divider = '<hr style="height:0px;margin:0px;padding:0px;border:none;" data-powered-by="alnp" data-initial-post="false" data-url="' + post_url + '"/>';
var post_html = $( post_divider + data );
var post_title = post_html.find( post_title_selector ); // Find the post title of the loaded article.
var post_ID = $( post ).find( article_container ).attr( 'id' ); // Find the post ID of the loaded article.
var triggerParams = [ post_title.text(), post_url, post_ID, post_count ];
if ( typeof post_ID !== typeof undefined && post_ID !== "" ) {
post_ID = post_ID.replace( 'post-', '' ); // Make sure that only the post ID remains.
console.log( 'Post ID: ' + post_ID );
} else {
console.error( 'Post ID was not found.' );
}
// Check if the post title exists.
if ( post_title.length > 0 ) {
console.log( 'Post Title: ' + post_title.text() );
} else {
console.log( 'Post title was not found!' );
}
$( content_container ).append( post_html ); // Add next post.
$( article_container + '[id="post-' + post_ID + '"]' ).attr( 'data-initial-post', false ); // Set article as not the initial post.
// Remove Comments.
if ( remove_comments === 'yes' ) {
$( comments_container ).remove();
// Remove Disqus comments if found.
if ( $( '#disqus_thread' ).length > 0 ) {
$( '#disqus_thread' ).remove();
}
if ( $( comments_container ).length <= 0 ) {
console.log( 'Comments Removed' );
}
}
// Get the hidden "HR" element and add the missing post title and post id attributes.
$( 'hr[data-url="' + post_url + '"]').attr( 'data-title', post_title.text() ).attr( 'data-post-id', post_ID );
scrollspy(); // Need to set up ScrollSpy now that the new content has loaded.
post_count = post_count+1; // Updates the post count.
console.log( 'Post Count: ' + post_count );
// Run an event once the post has loaded.
$( 'body' ).trigger( 'alnp-post-loaded', triggerParams );
// Trigger user defined events
triggerEvents(event_on_load, triggerParams);
});
} // END auto_load_next_post()
})(jQuery);