Bộ đếm hoạt hình với JavaScript

Tìm hiểu cách tạo bộ đếm động đơn giản, sử dụng mã ngắn WordPress PHP cho phần sau và một số JavaScript cho phần trước. Đó là một cách đơn giản để thu hút sự chú ý đến các số liệu thống kê chính mà không quá hào nhoáng.

Chúng tôi sẽ viết một hàm PHP nhỏ, một chút JavaScript, sau đó tạo kiểu cho nó bằng một số CSS. Chúng tôi cũng sẽ cẩn thận chỉ bao gồm các tệp CSS và JS của chúng tôi trên các trang cần chúng (các trang có bộ đếm) để chúng tôi không làm chậm phần còn lại của trang web một cách không cần thiết (các trang không có bộ đếm trên chúng).

Chúng tôi sẽ giữ các tệp PHP, JavaScript và CSS của mình trong một mô-đun độc lập để có thể dễ dàng sử dụng trong nhiều dự án. Ý tôi là… chúng ta sẽ không chỉ dán vô số đoạn mã vào tệp functions.php chính của theme - chúng ta sẽ giữ cho functions.php của theme đẹp và gọn gàng.

Bắt đầu với Tệp giữ chỗ

Trong thư mục của chủ đề con tùy chỉnh của bạn, hãy tạo một tệp có tên là animation-counter.php và một thư mục con có tên là animation-counter . Trong thư mục con, tạo thêm hai tệp trống, được gọi là afc-frontend.cssafc-frontend.js .

  • animation-counter.php (mã PHP)
  • bộ đếm động (thư mục)
    • afc-frontend.css (CSS stylesheet)
    • afc-frontend.js (mã JavaScript)
  • ... phần còn lại của các tập tin trong child theme tùy chỉnh của bạn ... ... ...
Chúng tôi sẽ đặt mã PHP tùy chỉnh của chúng tôi bên trong một shortcode. Đó là một cách hoạt động hơi lỗi thời (chúng ta thực sự nên sử dụng Khối Gutenberg) nhưng các mã ngắn rất nhanh chóng, dễ dàng và nhẹ. Tuyệt vời để thêm các đoạn mã PHP có thể tái sử dụng như thế này.

Mã PHP

Chỉnh sửa animation-counter.php và dán phần sau vào đó.
/**
 * Animated Frontend Counter.
 *
 * https://wp-tutorials.tech/add-functionality/animated-counter-with-javascript/
 */
// Block direct access.
if (!defined('WPINC')) {
   exit('Do NOT access this file directly.');
}
/**
 * Timings are in milliseconds (ms). 1sec = >1000ms
 */
const ACF_ANIM_DURATION = 1500; // ms.
const ACF_ANIM_INTERVAL = 25;   // ms.
function do_shortcode_afc_counter($atts = null) {
   global $afc_have_assets_been_queued;
   // Extract the shortcodes' arguments.
   $args = shortcode_atts(
      array(
         'start' => 0,
         'end' => 100,
         'label' => null,
      ),
      $atts
   );
   // Start rendering our HTML.
   $html = '
'; // Render the optional label. if (!empty($args['label'])) { $html .= sprintf('%s', esc_html($args['label'])); } // Render the counter. $html .= sprintf( '--', esc_attr(json_encode($args)) ); // Finish rendering our HTML. $html .= '
'; // .afc-container // If this is the first acf_counter shortcode then enqueue our CSS and JS // files, so WordPress can add them to the document footer for us. if (is_null($afc_have_assets_been_queued)) { $base_url = get_stylesheet_directory_uri() . '/' . pathinfo(__FILE__, PATHINFO_FILENAME) . '/'; $theme_version = wp_get_theme()->get('Version'); // Our CSS styles asset. wp_enqueue_style('afc-frontend', $base_url . 'afc-frontend.css', null, $theme_version); // Our JavaScript asset. wp_register_script('afc-frontend', $base_url . 'afc-frontend.js', array('jquery'), $theme_version, true); wp_localize_script( 'afc-frontend', 'acfCounters', array( 'animDuration' => ACF_ANIM_DURATION, 'animInterval' => ACF_ANIM_INTERVAL, ) ); wp_enqueue_script('afc-frontend'); $afc_have_assets_been_queued = true; } return $html; } add_shortcode('afc_counter', 'do_shortcode_afc_counter');

Chức năng chính để xử lý shortcode và tạo HTML hoạt động như sau:

  1. Phân tích cú pháp các đối số của mã ngắn, như "nhãn", "bắt đầu" và "kết thúc".
  2. Mở hộp chứa của chúng tôi <div>.
  3. Nếu chúng tôi đã chỉ định một nhãn, thì hãy thêm nhãn đó vào HTML ngay bây giờ.
  4. Thêm một <span>phần tử để giữ bộ đếm thực tế.
  5. Đóng <div>thùng.
  6. Nói với WordPress về các tệp CSS và JavaScript (tài sản) của chúng tôi để nó có thể thêm chúng vào chân trang tài liệu.
Bây giờ chúng ta có một hàm PHP trong đó để hiển thị shortcode, chúng ta cần nói với theme con tùy chỉnh của chúng ta về nó. Trong chủ đề con tùy chỉnh của bạn, hãy mở functions.php và thêm những thứ sau:
/**
 * Shortcode for animated frontend counters.
 */
require_once 'animated-counter.php';

Như vậy là đủ để làm cho mọi thứ trở nên ổn thỏa. Hãy thử thêm một khối mã ngắn vào một số nội dung. Tất cả sẽ trông hơi rác rưởi và nó sẽ không hoạt hình, bởi vì chúng tôi chưa viết bất kỳ CSS / JS nào, nhưng nó sẽ xác nhận rằng khía cạnh PHP của mọi thứ được hỗ trợ đúng cách.

Hoạt ảnh JavaScript

Đối với nội dung JavaScript giao diện người dùng (mã để tạo hoạt ảnh cho bộ đếm), chúng tôi sẽ dựa vào jQuery. Điều này sẽ làm cho mã dễ đọc hơn nếu chúng ta chỉ làm 100% từ đầu.

Mở tệp afc-frontend.js và dán những thứ sau vào đó:

(function($) {
    'use strict';
    $(window).on('load', function() {
        console.log('Animated Frontend Counters : load');
        // Only run our code if acfCounters has been set in the HTML by the
        // WordPress wp_localize_script() function.
        if (typeof acfCounters != 'undefined') {
            var startTime = null;
            var counterElements = [];
            var isAnimationStarted = false;
            // the "observer" responsed when one of our counter animations
            // becomes 100% visible on the page.
            var observer = new IntersectionObserver(function(entries) {
                if (!isAnimationStarted) {
                    entries.forEach((entry) => {
                        if (entry.isIntersecting === true) {
                            isAnimationStarted = true;
                        }
                    });
                    if (isAnimationStarted) {
                        console.log('Starting counter animations now');
                        counterIteration();
                    }
                }
            }, { threshold: [1] });
            // Look for the  elements that have a data-counter-anim
            // property, stash them in the counterElements array and add them
            // to the observer.
            $('[data-counter-anim]').each(function(index, el) {
                var definition = $(this).data('counter-anim');
                counterElements.push(this);
                observer.observe($(this).closest('.afc-container')[0]);
            });
            function counterIteration() {
               // If this is the first iteration, the set the start time to now.
                if (startTime == null) {
                    startTime = new Date();
                }
                var now = new Date();
                var timeSinceStart = now - startTime;
                var percentage = timeSinceStart / acfCounters.animDuration;
                var isLastIteration = (percentage >= 1.00);
                counterElements.forEach(counterElement => {
                    var definition = $(counterElement).data('counter-anim');
                    var counterStart = parseInt(definition.start);
                    var counterEnd = parseInt(definition.end);
                    var currentCount = counterStart;
                    if (isLastIteration) {
                        currentCount = counterEnd;
                    } else {
                        currentCount = Math.round(counterStart + (percentage * (counterEnd - counterStart)));
                    }
                    $(counterElement).text(currentCount);
                });
                if (!isLastIteration) {
                    setTimeout(counterIteration, acfCounters.animInterval);
                }
            }
        }
    });
})(jQuery);
Logic ở đây chạy như thế này:
  1. Nếu biến toàn cục acfCountersđã được xác định (bởi hàm wp_localize_script trong PHP) thì hãy tìm kiếm các phần tử có data-counter-animtập thuộc tính trong DOM .
    1. Stash các phần tử này trong một mảng được gọi là counterElements.
    2. Thêm từng phần tử vào phần tử có thể quan sát, điều này sẽ cho chúng tôi biết khi nào bất kỳ <div>phần tử hoạt ảnh truy cập nào của chúng tôi hiển thị trên trang.
  2. Nếu một hoặc nhiều phần tử hoạt ảnh bộ đếm của chúng tôi hiển thị và chúng tôi chưa bắt đầu chạy hoạt ảnh, thì hãy bắt đầu ngay bây giờ.
  3. Đối với mỗi lần lặp lại hoạt ảnh…
    1. Tìm ra phần trăm hoạt ảnh mà chúng ta đang ở hiện tại, dựa trên thời gian hiện tại và thời gian chúng ta bắt đầu. 100% có nghĩa là chúng tôi sắp kết xuất khung hình cuối cùng của hoạt ảnh.
    2. Lặp qua các phần tử trong counterElements, tìm ra giá trị hiện tại để hiển thị, sau đó gọi hàm text () của phần tử.
    3. Nếu chúng ta không ở cuối hoạt ảnh, hãy chạy một lần lặp khác sau khi hết thời gian animInterval.
Sau khi bạn đã lưu tệp JavaScript… hãy tải lại trang thử nghiệm của bạn và bạn sẽ thấy hoạt ảnh hoạt động.

thông tin Nếu bạn không thấy hoạt ảnh, hãy mở các công cụ phát triển của trình duyệt và xem bảng điều khiển lỗi JavaScript của bạn. Có lẽ tên tệp đã bị sai chính tả, vì vậy trình duyệt của bạn không thể tìm thấy tệp JavaScript của bạn?

Thêm một số phong cách và thử nghiệm nó

Chút cuối cùng là dễ dàng. Dán phần sau vào afc-frontend.css của bạn để bắt đầu tạo kiểu. HTML cho bộ đếm được cấu trúc đơn giản nên bạn có thể dễ dàng tùy chỉnh nó cho trang web của mình.
/**
 * Animated Frontend Counters
 */
.afc-container {
    background-color: #202020;
    background-image: linear-gradient(to bottom, transparent, #303030);
    color: white;
    text-align: center;
    border-radius: 0.5rem;
    overflow: hidden;
    margin-bottom:  1rem;
}
.afc-container label {
    font-size: 16pt;
    display: block;
    letter-spacing: 0.1em;
    background-image: linear-gradient(to bottom, transparent -50%, #303030);
    border-bottom: 1px dotted #606060;
    padding: 1.25rem 0;
    opacity: 0.80;
}
.afc-container [data-counter-anim] {
    display: block;
    font-family: monospace;
    font-size: 24pt;
    letter-spacing: 0.1em;
    padding: 1.25rem;
}
Nên làm vậy. Lưu các thay đổi vào tệp CSS của bạn, tải lại nội dung thử nghiệm của bạn và bạn sẽ được sắp xếp. Nếu điều gì đó không hoạt động, hãy theo dõi bảng điều khiển JavaScript của trình duyệt của bạn để biết lỗi… thiếu tệp và lỗi chính tả.

Chúc bạn cập nhật vui vẻ!