web-dev-qa-db-fra.com

Chargement différé à l'aide de la pagination WP_Query

Je pensais utiliser la pagination de WP_Query pour créer un chargement paresseux personnalisé. Existe-t-il un moyen d'utiliser la pagination du WP_Query pour une charge paresseuse?

Par exemple, je dois charger 24 messages dans le premier chargement, et lorsque le parchemin atteindra le bas, il chargera les 24 prochains messages.

Est-ce possible?

1
karlo jay bueno

Jetez un coup d'œil à cet exemple approximatif. Cela nécessite un peu d’adaptation, mais dans l’ensemble, il fait ce que vous voulez: il charge un nombre X de messages suivant si l’utilisateur clique sur un bouton situé en dessous des messages déjà chargés.

Si vous souhaitez charger automatiquement plus de publications si l'utilisateur fait défiler l'écran vers le bas, remplacez simplement l'événement click par un autre code qui surveille le défilement. Il y a beaucoup d'exemples en ligne.

  • Gardez un œil sur jQuery('some-html-element')-s, assurez-vous de renommer ces noms d’éléments ou modifiez votre propre HTML pour les adapter.
  • Nombre total de publications: vous pouvez la rendre visible si vous voulez que les utilisateurs voient le nombre total de publications ou utilisent CSSopacity pour le masquer. Il doit encore être quelque part pour avoir un endroit pour stocker la valeur

Cela va à votre principal .js:

Cette fonction gère toutes les manipulations DOM et ajax. Il peut être appelé comme vous le souhaitez.

//ajaxLock is just a flag to prevent double clicks and spamming
var ajaxLock = false;

if( ! ajaxLock ) {

    function ajax_next_posts() {

        ajaxLock = true;

        //How many posts there's total
        var totalPosts = parseInt( jQuery( '#total-posts-count' ).text() );
        //How many have been loaded
        var postOffset = jQuery( '.single-post' ).length;
        //How many do you want to load in single patch
        var postsPerPage = 24;

        //Hide button if all posts are loaded
        if( totalPosts < postOffset + ( 1 * postsPerPage ) ) {

            jQuery( '#more-posts-button' ).fadeOut();
        }

        //Change that to your right site url unless you've already set global ajaxURL
        var ajaxURL = 'http://www.my-site.com/wp-admin/admin-ajax.php';

        //Parameters you want to pass to query
        var ajaxData = '&post_offset=' + postOffset + '&action=ajax_next_posts';

        //Ajax call itself
        jQuery.ajax({

            type: 'get',
            url:  ajaxURL,
            data: ajaxData,
            dataType: 'json',

            //Ajax call is successful
            success: function ( response ) {

                //Add new posts
                jQuery( '#posts-container' ).append( response[0] );
                //Update the count of total posts
                jQuery( '#total-posts-count' ).text( response[1] );

                ajaxLock = false;
            },

            //Ajax call is not successful, still remove lock in order to try again
            error: function () {

                ajaxLock = false;
            }
        });
    }
}

Cela va à votre principal .js:

Ceci est un exemple de la façon dont on appelle la fonction ci-dessus avec le bouton, c’est mieux à mon avis, l’utilisateur peut choisir s’il veut en voir plus ..

//Load more posts button
jQuery( '#more-posts-button' ).click( function( e ) {

    e.preventDefault(); 

    ajax_next_posts(); 

});

Cela va à functions.php ou créer un plug-in mu:

C'est la fonction qui "s'exécute" sur votre serveur, ajax appelle ceci, fait son travail et renvoie les résultats.

//More posts - first for logged in users, other for not logged in
add_action('wp_ajax_ajax_next_posts', 'ajax_next_posts');
add_action('wp_ajax_nopriv_ajax_next_posts', 'ajax_next_posts');

function ajax_next_posts() {

    //Build query
    $args = array(
        //All your query arguments
    );

    //Get offset
    if( ! empty( $_GET['post_offset'] ) ) {

        $offset = $_GET['post_offset'];
        $args['offset'] = $offset;

        //Also have to set posts_per_page, otherwise offset is ignored
        $args['posts_per_page'] = 24;
    }

    $count_results = '0';

    $query_results = new WP_Query( $args );

    //Results found
    if ( $query_results->have_posts() ) {

        $count_results = $query_results->found_posts;

        //Start "saving" results' HTML
        $results_html = '';
        ob_start();

        while ( $query_results->have_posts() ) { 

            $query_results->the_post();

            //Your single post HTML here
        }    

        //"Save" results' HTML as variable
        $results_html = ob_get_clean();  
    }

    //Build ajax response
    $response = array();

    //1. value is HTML of new posts and 2. is total count of posts
    array_Push ( $response, $results_html, $count_results );
    echo json_encode( $response );

    //Always use die() in the end of ajax functions
    die();  
}
2
N00b

J'ai utilisé le défilement infini pour cela.

Voici ce que j'ai utilisé dans script.js

$(function(){
    var $container = $('#ms-container');
    $container.imagesLoaded(function(){
      $container.masonry({
        itemSelector : '.ms-item',


      });
    });
//var templateUrl = object_name.templateUrl;
//var src =  "'"+templateUrl+"/images/loader.gif' ";

$container.infinitescroll({
      navSelector  : '#navigation',    // selector for the paged navigation 
      nextSelector : '#navigation a',  // selector for the NEXT link (to page 2)
      itemSelector : '.ms-item', 


      loading: {
          finishedMsg: $('<div class="finmsg">No More Posts.</div>'),
          msgText: '',
          img: '',
          speed: 0
        }
      },
      // trigger Masonry as a callback
      function( newElements ) {
        // hide new items while they are loading
        var $newElems = $( newElements ).css({ opacity: 0 });
        // ensure that images load before adding to masonry layout
        $newElems.imagesLoaded(function(){
          // show elems now they're ready
          $newElems.animate({ opacity: 1 });
          $container.masonry( 'appended', $newElems, true ); 
        });
      }
    );
});

J'utilise de la maçonnerie, vous devrez peut-être modifier cela. Le conteneur global sur la page d'archive est

<div id="ms-container">

Par conséquent:

var $container = $('#ms-container');

Mon conteneur pour chaque publication individuelle affichée sur ma page d'archives est:

<div class="ms-item col-sm-4">

Par conséquent:

itemSelector : '.ms-item',

C'est ce que j'utilise comme pagination au bas de la page d'archive:

      <div id ="navigation" class="pagination pull-left prevnext">
      <ul class="list-inline clearfix">
        <li class="text-left pull-left"><?php previous_posts_link( '<span class="glyphicon glyphicon-menu-left" aria-hidden="true"></span> Previous' );?></li>
        <li class="text-right pull-right"><?php next_posts_link( 'Next <span class="glyphicon glyphicon-menu-right" aria-hidden="true"></span>'); ?></li>
      </ul>
      </div>

Si je me souviens bien, c'est ici que j'ai compris comment faire: https://stackoverflow.com/questions/9766515/imagesloaded-method-not-working-with-jquery-masonry-and-infinite-scroll

0
MrFox