חיפוש ]

כיצד להוסיף גלילה אינסופית לאתר וורדפרס בעזרת JavaScript

גלילה אינסופית (Infinite Scroll) טוענת תוכן חדש באופן דינמי ככל שהמשתמש גולל למטה בדף. במקום ללחוץ על קישורי עימוד, המבקרים רואים את הקבוצה הבאה של פוסטים מופיעה אוטומטית כשהם מגיעים לתחתית.

גישה זו עובדת היטב עבור בלוגים ואתרים עתירי תוכן בהם אתם רוצים לשמור על מעורבות המשתמשים ללא הפרעה לזרימת הגלישה. במדריך הזה תלמדו איך ליישם גלילה אינסופית בוורדפרס באמצעות JavaScript ו-AJAX, ללא צורך בתוסף.

"Infinite scrolling is a web design technique that loads content continuously as the user scrolls down the page, eliminating the need for pagination." – MDN Web Docs, Web Design Patterns.

אם אתם מעדיפים גישה מבוססת כפתור במקום טעינה אוטומטית, עיינו במדריך על הוספת כפתור לטעינת פוסטים נוספים עם AJAX.

איך זה עובד

המימוש כולל ארבעה חלקים:

  1. פונקציית PHP שמטפלת בבקשות AJAX ומחזירה את הקבוצה הבאה של פוסטים
  2. טעינת סקריפט שמעבירה נתוני וורדפרס (כתובת AJAX, עמוד נוכחי, מקסימום עמודים) לצד הלקוח
  3. קובץ JavaScript שמזהה מתי המשתמש גולל קרוב לתחתית ומפעיל בקשת AJAX
  4. קונטיינר HTML שעוטף את רשימת הפוסטים כדי שפוסטים חדשים יתווספו אליו

כל קוד ה-PHP נכנס לקובץ functions.php של תבנית הבת שלכם.

שלב 1: יצירת מטפל ה-AJAX

הפונקציה הבאה מקבלת את מספר העמוד מהצד הלקוח, מריצה WP_Query, ומוציאה את ה-HTML של הפוסטים:

function savvy_infinite_scroll_handler() {
    check_ajax_referer( 'infinite_scroll_nonce', 'nonce' );

    $paged = isset( $_POST['page'] ) ? intval( $_POST['page'] ) : 1;

    $query = new WP_Query( array(
        'post_type'      => 'post',
        'posts_per_page' => 6,
        'paged'          => $paged,
    ) );

    if ( $query->have_posts() ) :
        while ( $query->have_posts() ) : $query->the_post();
            get_template_part( 'template-parts/content', get_post_format() );
        endwhile;
    endif;

    wp_reset_postdata();
    wp_die();
}
add_action( 'wp_ajax_infinite_scroll', 'savvy_infinite_scroll_handler' );
add_action( 'wp_ajax_nopriv_infinite_scroll', 'savvy_infinite_scroll_handler' );

שתי הקריאות ל-add_action רושמות את המטפל עבור משתמשים מחוברים ולא מחוברים כאחד. הקריאה ל-check_ajax_referer() מאמתת את ה-nonce לצורכי אבטחה.

תמיד אמתו את ה-nonce עם check_ajax_referer() במטפל ה-AJAX שלכם. בלעדיו, כל אחד יכול לשלוח בקשות ל-endpoint שלכם. כמו כן, השתמשו ב-wp_die() במקום die() – היא מפעילה את הוקי ה-shutdown המתאימים של וורדפרס והיא הדרך המומלצת לסיום תגובות AJAX.

שלב 2: טעינת ה-JavaScript

כעת טענו את קובץ ה-JavaScript והעבירו את הפרמטרים הנדרשים באמצעות wp_localize_script():

function savvy_enqueue_infinite_scroll() {
    wp_enqueue_script(
        'infinite-scroll',
        get_stylesheet_directory_uri() . '/js/infinite-scroll.js',
        array( 'jquery' ),
        '1.0.0',
        true
    );

    wp_localize_script( 'infinite-scroll', 'infinite_scroll_params', array(
        'ajax_url'     => admin_url( 'admin-ajax.php' ),
        'nonce'        => wp_create_nonce( 'infinite_scroll_nonce' ),
        'current_page' => get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1,
        'max_page'     => $GLOBALS['wp_query']->max_num_pages,
    ) );
}
add_action( 'wp_enqueue_scripts', 'savvy_enqueue_infinite_scroll' );

שימו לב לשימוש ב-get_stylesheet_directory_uri() במקום get_template_directory_uri(). זה מבטיח שהקובץ נטען מתבנית הבת שלכם.

שלב 3: יצירת קובץ ה-JavaScript

צרו קובץ בשם infinite-scroll.js בתוך תיקיית js של התבנית:

jQuery(function($) {
    var canLoadMore = true;
    var currentPage = parseInt(infinite_scroll_params.current_page);
    var maxPage = parseInt(infinite_scroll_params.max_page);

    $(window).on('scroll', function() {
        if (
            $(window).scrollTop() + $(window).height() >= $(document).height() - 300
            && canLoadMore
            && currentPage < maxPage
        ) {
            canLoadMore = false;
            currentPage++;

            $.ajax({
                url: infinite_scroll_params.ajax_url,
                type: 'POST',
                data: {
                    action: 'infinite_scroll',
                    nonce: infinite_scroll_params.nonce,
                    page: currentPage
                },
                success: function(response) {
                    if (response) {
                        $('.post-list').append(response);
                        canLoadMore = true;
                    } else {
                        canLoadMore = false;
                    }
                },
                error: function() {
                    canLoadMore = false;
                }
            });
        }
    });
});

הסקריפט מאזין לאירוע הגלילה ומפעיל בקשת AJAX כשהמשתמש מגיע ל-300 פיקסלים מתחתית הדף. הוא מגדיל את מספר העמוד עם כל בקשה ומוסיף את ה-HTML של התגובה לקונטיינר רשימת הפוסטים.

שלב 4: הגדרת מבנה ה-HTML

עטפו את לולאת הפוסטים בקונטיינר עם הקלאס post-list. זהו האלמנט שה-JavaScript מכוון אליו כשהוא מוסיף פוסטים חדשים:

<div class="post-list">
    <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
        <?php get_template_part( 'template-parts/content', get_post_format() ); ?>
    <?php endwhile; endif; ?>
</div>

ודאו ששם הקלאס תואם למה שבקוד ה-JavaScript שלכם. תוכלו גם להוסיף אינדיקטור טעינה והודעת סיום תוכן:

<div class="infinite-scroll-status" style="display:none; text-align:center; padding:20px;">
    ...טוען פוסטים נוספים
</div>

אופטימיזציה לביצועים

אירוע הגלילה מופעל בתדירות גבוהה מאוד, מה שעלול לגרום לבעיות ביצועים. השתמשו ב-requestAnimationFrame() כדי לווסת אותו:

var ticking = false;

$(window).on('scroll', function() {
    if (!ticking) {
        window.requestAnimationFrame(function() {
            if (
                $(window).scrollTop() + $(window).height() >= $(document).height() - 300
                && canLoadMore
                && currentPage < maxPage
            ) {
                // הפעלת טעינת AJAX כאן
            }
            ticking = false;
        });
        ticking = true;
    }
});

זה מבטיח שבדיקת הגלילה תרוץ לכל היותר פעם אחת לכל פריים של אנימציה, ומונע עיבוד מיותר.

הוספת חלופת עימוד

תמיד כללו חלופה לעימוד מסורתי עבור משתמשים עם JavaScript מושבת ועבור סורקי מנועי חיפוש:

<noscript>
    <?php
    if ( function_exists( 'the_posts_pagination' ) ) {
        the_posts_pagination();
    }
    ?>
</noscript>

עטיפת העימוד בתגית <noscript> אומרת שהוא יופיע רק כש-JavaScript אינו זמין. כך למשתמשים תמיד יש דרך לנווט בתוכן שלכם.

שיקולי SEO

גלילה אינסופית עלולה להקשות על סורקי מנועי חיפוש לגלות את כל התוכן שלכם, מכיוון שהם לא מפעילים את הטעינה מבוססת הגלילה. שמרו על הנקודות הבאות:

  • תמיד כללו חלופת עימוד כדי שסורקים יוכלו לעקוב אחרי קישורי דפים
  • ודאו שכל URL מעומד (?paged=2, ?paged=3) מחזיר תוכן תקף כשניגשים אליו ישירות
  • השתמשו ב-sitemap כדי לוודא שכל הפוסטים ניתנים לגילוי ללא קשר לאיך שהם נטענים בצד הלקוח

שאלות נפוצות

שאלות נפוצות על מימוש גלילה אינסופית בוורדפרס:

האם גלילה אינסופית פוגעת ב-SEO?
היא יכולה, אם סורקי מנועי חיפוש לא יכולים לגשת לכל התוכן. הפתרון פשוט: תמיד כללו חלופת עימוד מסורתי. סורקים עוקבים אחרי קישורי עימוד כדי לגלות את כל הפוסטים, בזמן שמשתמשים מקבלים את חוויית הגלילה האינסופית החלקה.
אפשר להשתמש בגלילה אינסופית בלי jQuery?
כן. תוכלו להחליף את $.ajax() של jQuery ב-API המובנה fetch() ולהשתמש ב-document.addEventListener('scroll', ...) במקום המטפל של jQuery. הלוגיקה נשארת זהה - רק התחביר משתנה. דפדפנים מודרניים תומכים ב-fetch באופן מובנה ללא ספרייה.
למה צריך nonce במטפל ה-AJAX?
nonce (מספר חד-פעמי) מוודא שבקשת ה-AJAX הגיעה מהאתר שלכם, ולא ממקור חיצוני. בלעדיו, ה-endpoint שלכם פתוח להתקפות CSRF (זיוף בקשות חוצה אתרים). וורדפרס מייצרת את ה-nonce בצד הלקוח ומאמתת אותו בצד השרת עם check_ajax_referer().
איך משנים את מספר הפוסטים שנטענים בכל גלילה?
שנו את ערך posts_per_page בארגומנטים של WP_Query בתוך פונקציית מטפל ה-AJAX. למשל, הגדירו ל-10 כדי לטעון 10 פוסטים לכל בקשה. שמרו על מספר סביר - טעינת פוסטים רבים מדי בבת אחת מבטלת את מטרת הטעינה העצלה.
מה ההבדל בין גלילה אינסופית לכפתור Load More?
גלילה אינסופית טוענת תוכן אוטומטית כשהמשתמש גולל. כפתור Load More דורש מהמשתמש ללחוץ כדי לטעון את הקבוצה הבאה. הלוגיקה של ה-AJAX כמעט זהה - ההבדל היחיד הוא הטריגר. כפתור נותן למשתמשים יותר שליטה, בזמן שגלילה אינסופית מספקת חוויית גלישה חלקה יותר.
האם להשתמש ב-wp_die() או ב-die() במטפל AJAX?
תמיד השתמשו ב-wp_die(). היא מפעילה את הוקי ה-shutdown המתאימים של וורדפרס והיא הדרך המומלצת לסיום תגובות AJAX. שימוש ב-die() או exit עוקף הוקים אלה, מה שעלול לשבור פונקציונליות שתלויה בהם, כמו object caching או לוגינג.

סיכום

מימוש גלילה אינסופית בוורדפרס דורש ארבעה חלקים: מטפל AJAX ששולף את העמוד הבא של פוסטים, טעינת סקריפט שמעבירה נתוני דף לצד הלקוח, קובץ JavaScript שמפעיל בקשות בגלילה, וקונטיינר HTML להוספת התוצאות.

תמיד כללו אימות nonce במטפל ה-AJAX שלכם לאבטחה, השתמשו ב-wp_die() במקום die(), וווסתו את אירוע הגלילה עם requestAnimationFrame() לביצועים טובים יותר.

שמרו על חלופת עימוד ל-SEO ונגישות – סורקים ומשתמשים ללא JavaScript צריכים דרך לנווט בתוכן שלכם גם כן.

דיון ותגובות
0 תגובות  ]

השאירו תגובה

הוסיפו קוד באמצעות הכפתורים מטה. למשל, בכדי להוסיף PHP לחצו על הכפתור PHP והוסיפו את הקוד בתוך השורטקוד. מצאתם שגיאה בפוסט? עדכנו אותנו...

Savvy WordPress Development official logo