Per realizzare un infinte scroll o un bottone che carichi il contenuto successivo è necessario utilizzare AJAX.
Proprio per questo credo sia molto importante dare una breve introduzione a questo argomento.
Cos’è AJAX?
Ajax, acronimo di Asynchronous JavaScript and XML si basa su uno scambio di dati in background fra web browser e server.
Esso consente quindi l’aggiornamento dinamico di una pagina web senza un ricaricamento da parte dell’utente.
Perché utilizzarlo?
Facciamo subito un esempio pratico e immaginiamo di essere nella pagina blog del nostro sito.
Esso, con molta probabilità e se configurato correttamente avrà più pagine, solitamente nominate in questo modo: https://example.com/blog/page/1.
Passare alla seconda pagina del nostro blog comporterà un nuovo caricamento degli stili, degli script e dell’HTML stesso.
Invece, eseguendo una richiesta AJAX, non verranno ricaricati nuovamente tutti questi file ma solamente gli articoli successivi.
In quest’ultimo caso l’utente non sarà costretto ad aspettare il caricamento completo di una nuova pagina e tutto ciò si tradurrà in una miglior esperienza utente.
Infinite scroll e bottone load more
Ora che ti ho illustrato una breve introduzione sull’argomento AJAX sei pronto per costruire il tuo scroll infinito o alternativamente un bottone per caricare il contenuto successivo.
Creare uno shortcode WordPress
La prima cosa da fare è creare uno shortcode WordPress da utilizzare nella pagina in questione, nel mio caso la pagina del blog.
Per fare ciò dobbiamo creare una funzione di callback che verrà eseguita ogni volta che viene utilizzato il codice.
Aggiungiamo quindi il seguente codice nel file functions.php
.
Puoi trovare questo file al seguente percorso: /wp-content/themes/temaattivo/functions.php
.
function script_load_more($args = array()) {
echo '<div id="ajax-primary" class="content-area">';
echo '<div id="ajax-content" class="content-area">';
ajax_script_load_more($args);
echo '</div>';
echo '<a href="#" id="loadMore" data-page="1" data-url="'.admin_url("admin-ajax.php").'" >Load More</a>';
echo '</div>';
}
Ora creiamo il nostro shortcode il quale richiamerà la funzione script_load_more
.
Inseriscilo sempre nel file functions.php
.
add_shortcode('ajax_posts', 'script_load_more');
Crea la richiesta AJAX
Adesso dobbiamo creare la funzione che richiamerà gli articoli successivi, cioè ajax_script_load_more
chiamato all’interno della funzione script_load_more
.
Aggiungiamo perciò la seguente funzione nel file functions.php
.
function ajax_script_load_more($args) {
//Init ajax
$ajax = false;
//Controlla la chiamata AJAX
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) &&
strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
$ajax = true;
}
//Numero degli articoli da caricare
$num =3;
//Numero della pagina
$paged = $_POST['page'] + 1;
//Args
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' =>$num,
'paged'=>$paged
);
//Query
$query = new WP_Query($args);
//Controllo
if ($query->have_posts()):
//loop articales
while ($query->have_posts()): $query->the_post();
//include articles template
include 'contenuto-ajax.php';
endwhile;
else:
echo 0;
endif;
//Ripristina post
wp_reset_postdata();
//Controlla la chiamata AJAX
if($ajax) die();
}
Con questa funzione verranno caricati 3 articoli alla volta.
Se vuoi caricarne di più o di meno modifica il valore $num
.
Crea il template dell’articolo
Ora crea il file contenuto-ajax.php
che verrà utilizzato nella funzione ajax_script_load_more
.
Questo è il file che conterrà il template dell’articolo.
Inserisci questo file al seguente percorso /wp-content/themes/temaattivo/contenuto-ajax.php
.
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<div class="box-articolo">
<div class="img-articolo">
<a class="img-thumbnail" href="<?php the_permalink() ?>"><?php the_post_thumbnail(); ?></a>
</div>
<div class="container-articolo">
<h3 class="titolo-articolo"><a href="<?php the_permalink() ?>"><?php the_title(); ?></a></h3>
<div class="meta-articolo">
<p class="data">Pubblicato il <time><?php the_time('j F, Y'); ?></time></p>
<span class="divisore">/</span>
<a class="autore" href="<?php the_author_link(); ?>"><?php the_author(); ?> </a>
<span class="divisore">/</span>
<?php $parentscategory ="";
foreach((get_the_category()) as $category) {
if ($category->category_parent == 0) {
$parentscategory .= ' <a class="categoria" href="' . get_category_link($category->cat_ID) . '" title="' . $category->name . '">' . $category->name . '</a>, ';
}
}
echo substr($parentscategory,0,-2); ?>
</div>
<div class="excerpt">
<?php the_excerpt(); ?>
</div>
<div class="btn-altro">
<a class="leggi-altro" href="<?php the_permalink() ?>">Leggi altro</a>
</div>
</div>
</div>
</article>
Crea un action hook AJAX
Ora dobbiamo creare un action hook AJAX per richiamare la funzione ajax_script_load_more
.
Per farlo aggiungi il seguente codice nel file functions.php
.
add_action('wp_ajax_nopriv_ajax_script_load_more', 'ajax_script_load_more');
add_action('wp_ajax_ajax_script_load_more', 'ajax_script_load_more');
Crea il file script per lo scroll infinito o per il bottone load more
Ora creiamo il file scripts_ajax.js
all’interno della directory js del tema attivo.
Dovresti trovarla al seguente percorso: /wp-content/themes/temaattivo/js/scripts_ajax.js
.
Dopodiché creiamo una funzione nel file functions.php
che richiami questo script nel footer del nostro sito.
add_action( 'wp_enqueue_scripts', 'ajax_enqueue_script' );
function ajax_enqueue_script() {
wp_enqueue_script( 'scripts_ajax', get_theme_file_uri( '/js/scripts_ajax.js' ), array( 'jquery' ), '1.0', true );
}
Ora hai due possibilità, scegli una delle due e inserisci il codice apposito.
1) Caricare gli articoli successivi quando l’utente seleziona il bottone carica altro.
jQuery.noConflict($);
/* Funzioni AJAX */
jQuery(document).ready(function($) {
//Esegue la funzione quando avviene il click
$("#loadMore").on('click', function(e) {
e.preventDefault();
//Init
var that = $(this);
var page = $(this).data('page');
var newPage = page + 1;
var ajaxurl = that.data('url');
//Chiamata AJAX
$.ajax({
url: ajaxurl,
type: 'post',
data: {
page: page,
action: 'ajax_script_load_more'
},
error: function(response) {
console.log(response);
},
success: function(response) {
//Controllo
if (response == 0) {
$('#ajax-content').append('<div class="text-center"><h3>Non sono presenti altri articoli!</h3></div>');
$('#loadMore').hide();
} else {
that.data('page', newPage);
$('#ajax-content').append(response);
}
}
});
});
});
2) Caricare gli articoli quando l’utente scrolla la pagina.
jQuery.noConflict($);
/* Funzioni AJAX */
jQuery(document).ready(function($) {
//Trova la posizione dello scroll
$(window).scroll(function() {
//Init
var that = $('#loadMore');
var page = $('#loadMore').data('page');
var newPage = page + 1;
var ajaxurl = $('#loadMore').data('url');
//Controllo
if ($(window).scrollTop() == $(document).height() - $(window).height()) {
//Chiamata AJAX
$.ajax({
url: ajaxurl,
type: 'post',
data: {
page: page,
action: 'ajax_script_load_more'
},
error: function(response) {
console.log(response);
},
success: function(response) {
//Controllo
if (response == 0) {
//Controllo
if ($("#no-more").length == 0) {
$('#ajax-content').append('<div id="no-more" class="text-center"><h3>Non sono presenti altri articoli!</h3></div>');
}
$('#loadMore').hide();
} else {
$('#loadMore').data('page', newPage);
$('#ajax-content').append(response);
}
}
});
}
});
});
Utilizzando questo codice verranno caricati altri articoli solamente quando arriverai a toccare la fine della pagina.
Se vuoi che gli articoli successivi vengano caricati prima di toccare la fine della pagina utilizza questo codice:
jQuery.noConflict($);
/* Funzioni AJAX */
jQuery(document).ready(function($) {
var eseguito = false;
//Trova la posizione dello scroll
$(window).scroll(function() {
//Init
var that = $('#loadMore');
var page = $('#loadMore').data('page');
var newPage = page + 1;
var ajaxurl = $('#loadMore').data('url');
if (eseguito) {
//if ($(window).scrollTop() <= ($(document).height() - $(window).height())*0.8){
if ($(window).scrollTop() <= (($(document).height() - $(window).height())- $("footer").height())-200) {
eseguito = false;
} else {
return false;
}
}
if (!eseguito) {
//Controllo
//if ($(window).scrollTop() >= ($(document).height() - $(window).height())*0.8){
if ($(window).scrollTop() >= (($(document).height() - $(window).height())- $("footer").height())-200) {
eseguito = true;
//Chiamata AJAX
$.ajax({
url: ajaxurl,
type: 'post',
data: {
page: page,
action: 'ajax_script_load_more'
},
error: function(response) {
console.log(response);
},
success: function(response) {
//Controllo
if (response == 0) {
//Controllo
if ($("#no-more").length == 0) {
$('#ajax-content').append('<div id="no-more" class="text-center"><h3>You reached the end of the line!</h3><p>No more posts to load.</p></div>');
}
$('#loadMore').hide();
} else {
$('#loadMore').data('page', newPage);
$('#ajax-content').append(response);
}
}
});
}
}
});
});
Come puoi vedere viene dichiarata una variabile eseguito
che indica se la chiamata AJAX è già stata eseguita.
Questo perché utilizzando esclusivamente il valore >
nella selezione verrebbero eseguite più chiamate del singolo oggetto restituendo così gli stessi 3 articoli più volte.
Inoltre è presente un’altra possibile selezione sotto commento che ti permette di caricare altri post quando si arriva all’80% della pagina.
Aggiungere shortcode per visualizzare gli articoli
Ora non ti resta altro che aggiungere il seguente shortcode nella pagina del blog per ottenere il risultato sperato.
<?php echo do_shortcode('[[ajax_posts]]'); ?>
Come utilizzare AJAX “infinite scroll” o “load more” nelle pagine categorie e tag
Mi sono accorto che mano a mano che aumentava la popolarità di questo post, aumentavano anche le richieste di come poter applicare questa tipologia di codice alle pagine categoria e tag.
Molti per cercare di far funzionare il codice da me riportato hanno provato ad utilizzare il seguente filtro:
$categoria_corrente = get_queried_object();
$ID_categoria_corrente = $categoria_corrente->term_id;
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'cat' => $ID_categoria_corrente,
'posts_per_page' =>$num,
'paged'=>$paged
);
Purtroppo però questo codice funziona solo nel primo richiamo, dopodiché non riuscirà più a trovare la pagina da cui viene effettuata la richiesta, perché il codice partirà dal file JavaScript.
Così ho subito deciso di creare una versione funzionante con solo qualche piccola modifica. Di seguito il codice JavaScript:
jQuery.noConflict($);
jQuery(document).ready(function($) {
var eseguito = false;
//find scroll position
$(window).scroll(function() {
//init
var that = $('#loadMore');
// L'aggiornamento parte da qui
var classBody = document.getElementsByTagName("body")[0].className;
var cat = classBody.replace( /^\D+/g, '');
// L'aggiornamento finisce qui
var page = $('#loadMore').data('page');
var newPage = page + 1;
var ajaxurl = $('#loadMore').data('url');
if (eseguito) {
if ($(window).scrollTop() <= (($(document).height() - $(window).height())- $("footer").height())-200) {
eseguito = false;
} else {
return false;
}
}
if (!eseguito) {
//check
if ($(window).scrollTop() >= (($(document).height() - $(window).height())- $("footer").height())-200) {
eseguito = true;
/*ajax call*/
$.ajax({
url: ajaxurl,
type: 'post',
data: {
cat : cat, // Qui viene passata l'intera classe con l'ID categoria
page: page,
action: 'ajax_script_load_more_category'
},
error: function(response) {
console.log(response);
},
success: function(response) {
//check
if (response == 0) {
//check
if ($("#no-more").length == 0) {
$('#ajax-content').append('<div id="no-more" class="text-center"><h3>Non sono presenti altri articoli!</h3></div>');
}
$('#loadMore').hide();
} else {
$('#loadMore').data('page', newPage);
$('#ajax-content').append(response);
}
}
});
}
}
});
});
Mentre il codice da inserire sul functions.php è il seguente:
//INFINITY SCROLL
function script_load_more_category($args = array()) {
echo '<div id="ajax-primary" class="content-area">';
echo '<div id="ajax-content" class="content-area">';
ajax_script_load_more_category($args);
echo '</div>';
echo '<a href="#" id="loadMore" data-page="1" data-url="'.admin_url("admin-ajax.php").'" >Load More</a>';
echo '</div>';
}
add_shortcode('ajax_posts_category', 'script_load_more_category');
function ajax_script_load_more_category($args) {
//Init ajax
$ajax = false;
//Controlla la chiamata AJAX
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) &&
strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
$ajax = true;
}
//Numero degli articoli da caricare
$num =3;
//Numero della pagina
$paged = $_POST['page'] + 1;
// L'aggiornamento parte qui
$cat = $_POST['cat'];
if(!$cat){
$categoria_corrente = get_queried_object();
$cat = $categoria_corrente->term_id;
}
// L'aggiornamento finisce qui
//Args
//$categoria_corrente = get_queried_object();
//$ID_categoria_corrente = $categoria_corrente->term_id;
//error_log($ID_categoria_corrente);
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'cat' => $cat, // Qui viene inserito l'ID categoria che filtra i risultati
'posts_per_page' =>$num,
'paged'=>$paged
);
//Query
$query = new WP_Query($args);
//Controllo
if ($query->have_posts()):
//loop articales
while ($query->have_posts()): $query->the_post();
//include articles template
include 'ajax-content.php';
endwhile;
else:
echo 0;
endif;
//Ripristina post
wp_reset_postdata();
//Controlla la chiamata AJAX
if($ajax) die();
}
add_action('wp_ajax_nopriv_ajax_script_load_more_category', 'ajax_script_load_more_category');
add_action('wp_ajax_ajax_script_load_more_category', 'ajax_script_load_more_category');
Conclusioni
Oggi abbiamo visto come creare uno scroll infinito e un bottone carica altro tramite delle chiamate AJAX permettendoci di migliorare e di molto l’esperienza dell’utente nel nostro sito.
Hai avuto problemi nella riproduzione del codice? Fammelo sapere nei commenti!
Un abbraccio,
Matteo.
Lascia un commento
Funziona correttamente. Manca solo e.preventDefault(); per evitare il “rimbalzo” al click sul pulsante Load More.
Grazie
Grazie mille Mattia, è sempre ben accetta un’osservazione e/o consiglio!
Un saluto,
Matteo.
@Mattia posso chiederti dove metteresti e.preventDefault() ? che dove l’ho scritto io non mi corregge l’errore. Grazie!
Ciao Pietro,
l’ho appena aggiunto nel codice, sull’articolo! 😉
Un saluto,
Matteo.
non capisco il riferimento “admin_url(“admin-ajax.php”)” a cosa si riferisce, non ne fai menzione in nessuna parte del codice.
Grazie
Ciao Vittorio,
è una parte essenziale dell’infinite scroll che va a richiamare il file admin-ajax.php, essenziale per il funzionamento di questo codice 🙂
Un saluto,
Matteo.
Davvero utile, grazie mille!
Prego!
Un abbraccio,
Matteo.
Impossibile copiare e incollare il codice, tra testo sballato e la dicitura del copyright.
Ciao Marco, purtroppo hai proprio ragione, provvedo subito a risolvere il problema.
Grazie della tua recensione, per me è molto importante.
Un abbraccio,
Matteo.
Ti confermo che il problema è appena stato risolto.
Per ulteriori problemi non esitare a contattarci anche tramite la nostra chat di assistenza gratuita!
Un abbraccio,
Matteo.
Grazie Matteo! Mi hai salvato la vita! Ho provato a seguire tantissime guide ma nessuna di queste funzionava! La tua sono funziona perfettamente. Grazie ancora!
Prego Marco, sono molto contento che la guida ti sia servita!
Un abbraccio,
Matteo.