Есть много способов разбить ваши архивы WordPress на страницы. Функция paginate_links()
является одной из них. Он вернет ссылки на номера страниц для ваших архивов. Однако эта разбивка на страницы будет отображать сообщения на отдельных страницах, таких как 1, 2, 3 и т. д. Но есть способ загрузить больше сообщений в ваш архив, не обновляя всю страницу. Мы изучим наиболее эффективный способ сделать это с помощью простого API-интерфейса JavaScript. В этом руководстве рассматривается весь процесс использования API выборки без какой-либо зависимости от jQuery.
Начните с цикла WordPress
Самая основная настройка файла index.php или archive.php в WordPress очень проста. Основной цикл while()
будет извлекать самые последние сообщения в хронологическом формате. Вот пример кода, который мы будем использовать в наших архивах и индексной странице.
<?php get_header(); if (have_posts()) : global $wp_query; ?> <div class="posts-wrapper"> <?php while (have_posts()) : the_post(); ?> <article <?php post_class(); ?>> <?php the_post_thumbnail('medium'); the_title('<h2>','</h2>'); the_excerpt(); ?> </article> <?php endwhile; ?> </div> <?php //default WordPress pagination links echo paginate_links();
//load more button for JS fetch API printf( '<div class="load-more" data-totalpages="%s"><button id="load_more_posts">%s</button></div>', esc_attr( $wp_query->max_num_pages ), esc_html__('Load More','text-doamin') );
endif; get_sidebar(); get_footer(); ?>
Это базовый цикл WordPress. Но я должен указать на пару вещей, на которые мы будем ориентироваться при написании кода на JavaScript. Div с классом .posts-wrapper
является нашим целевым контейнером, а article.post
— нашим индивидуальным контейнером сообщений.
Кнопка "Загрузить больше"
В приведенном выше коде мы добавили кнопку для события «Загрузить больше». Если вы заметили, мы передали общее количество доступных страниц в HTML-атрибут data-totalpages
, который позже будет использоваться в нашем JS. Это все, что касается первоначальной настройки файлов index.php и archive.php. Это покажет сообщения на основе настроек чтения для количества сообщений на странице.
Создайте и поставьте в очередь файл JS
Теперь мы создадим новый файл JS в папке нашей темы. Откройте текстовый редактор, добавьте новый файл и сохраните его как fetch-posts.js в папке JS, например:
theme's root folder
-- js (folder)
-- fetch-posts.js (file)
Мы поставим в очередь файл JS из function.php нашей темы. Пожалуйста, используйте код ниже -
function enqueue_scripts(){ //enqueue the fetch-posts js for archives and home only if( is_archive() || is_home() ){ wp_enqueue_script('fetch-posts', get_theme_file_uri('/js/fetch-posts.js'), NULL, '', true ); } }
add_action( 'wp_enqueue_scripts', 'enqueue_scripts', 10 );
Итак, мы настроили все для JS. Прежде чем перейти к коду JS, давайте проверим пару вещей:
- Убедитесь, что у вас есть нумерация страниц, проверив общее количество сообщений и сообщений на странице в настройках чтения.
- Если доступно разбиение на страницы, вы можете увидеть ссылки на страницы прямо над кнопкой «Загрузить еще».
Вы можете проверить, правильно ли работает пагинация. Однако, если у вас хорошие настройки постоянной ссылки, вы можете проверить нумерацию страниц, добавив ?paged=2
в конец URL-адреса страницы в адресной строке. Если у вас есть простые настройки постоянной ссылки, вы можете проверить это, добавив &paged=2
в конец URL-адреса страницы.
API выборки
Fetch API предоставляет интерфейс для получения ресурсов (в том числе по сети). Он покажется знакомым любому, кто использовал XMLHttpRequest
, но новый API предоставляет более мощный и гибкий набор функций.
Концепции и использование API выборки JavaScript
Fetch предоставляет общее определение объектов Request
и Response
(и других вещей, связанных с сетевыми запросами). Метод fetch()
принимает один обязательный аргумент — путь к ресурсу, который вы хотите получить. Он возвращает Promise
, который разрешается в Response
для этого запроса, независимо от того, успешен он или нет. После извлечения Response
существует ряд доступных методов для определения того, что представляет собой содержимое тела и как с ним следует обращаться.
Базовый запрос на выборку очень прост в настройке. Взгляните на следующий код:
fetch('http://example.com/movies.json')
.then(response => response.json())
.then(data => console.log(data));
Возможно, вам будет интересно узнать больше о методе fetch()
и его использовании здесь — Использование Fetch. Это очень простой и мощный метод для получения данных JSON или любых текстовых данных с заданного URL-адреса. Наш URL-адрес страницы будет предоставлять нам HTML. Поэтому нам нужно преобразовать его в строку с помощью метода text()
вместо метода json()
. Позже мы преобразуем это в узлы HTML, используя DOMParser()
, и извлечем из него наши данные записи.
В этом процессе мы будем использовать ключевые слова async
и await
, а затем fetch()
. Как код ниже -
async function x(){
let data = await ( await fetch( Url ).catch( errorHandle ) ).text()
console.log(data)
}
function errorHandle(err){
console.log(err)
}
Асинхронная функция — это функция, объявленная с ключевым словом async
. Асинхронные функции являются экземплярами конструктора AsyncFunction
, и в них разрешено ключевое слово await
. Ключевые слова async
и await
позволяют писать асинхронное поведение на основе промисов в более чистом стиле, избегая необходимости явно настраивать цепочки промисов. Вы можете найти подробнее об асинхронности здесь.
Наш фрагмент кода
Теперь, когда у нас есть общее представление об API-интерфейсе выборки JavaScript и асинхронной функции, мы перейдем к нашему фактическому кодированию JS. Откройте файл fetch-posts.js в текстовом редакторе, например vscode. Добавьте в него следующий код и сохраните.
/** * Load more function for WordPress archives and category pages * Works on all types of permalinks */
//set all initial variables let postContainer = document.querySelector('.posts-wrapper'), loadMore_btn = document.querySelector('#load_more_posts'), totalPages = document.querySelector('.load-more').getAttribute('data-totalpages'), currentPage = 1, url = document.location.href, fetchUrl = url.match(/[?]/) ? url + '&paged=' : url + '?paged=',//checking permalink structure parser = new DOMParser();//Initialize the DOM parser
//console.log(totalPages, url)
if( currentPage == totalPages ) {
//run if there is only 1 page loadMore_btn.classList.add('end-page') loadMore_btn.disabled = true loadMore_btn.innerHTML = 'No more posts'
}else if( currentPage < totalPages ){
//run if there is more than 1 page loadMore_btn.disabled = false
//add event listner for the load more button loadMore_btn.addEventListener( 'click', loadMorePosts )
}
/** * @callback loadMorePosts * async function for the fetch function with await */ async function loadMorePosts(){
//increment page number for each click currentPage++
//change button text while loading this.innerHTML = 'Loading...'
//fetch function and returned data let data = await ( await fetch( fetchUrl + currentPage ).catch( errorHandle ) ).text(),
//use DOMParser to convert text string to HTML nodes htmlData = parser.parseFromString( data, 'text/html' ),
//select posts that will be appended posts = htmlData.querySelectorAll('article.post')
for( let i = 0; i<posts.length; i++ ){
//initially add 'hide' class to the posts for fadein effect posts[i].classList.add('hide')
//then append it to the container postContainer.append( posts[i] ) }
/*********** fadein effect ***********/ //select all hidden posts let hiddenPosts = postContainer.querySelectorAll('.hide'),
//set time out and make the posts visible //css transition will fade in timer = setTimeout( function(){ Array.prototype.map.call( hiddenPosts, function(el){ el.classList.remove('hide') el.classList.add('show') }) }, 300) /*********** fadein effect ends ***********/
if( currentPage == totalPages ){
//if there is no more page, //disable the button this.classList.add('end-page') this.disabled = true this.innerHTML = 'No more posts'
}else{
//if there is more pages, //change the button text this.innerHTML = 'Load More' } }
/** * @callback errorHandle * @param err to handle errors */ function errorHandle(err){ console.warn(err) }
В приведенном выше фрагменте кода я использовал соответствующие комментарии и имена переменных для лучшего понимания того, что именно происходит. Теперь он более удобочитаем. Если у вас есть базовые понятия JavaScript, вы сможете хорошо это понять.
CSS для эффекта затухания и кнопки «Загрузить больше».
Когда вы читаете код, вы должны видеть, что мы добавили сообщения с классом .hide
, а затем с тайм-аутом мы удалили класс .hide
и добавили класс .show
к добавленным сообщениям. Теперь мы можем написать немного CSS для этого класса, и эффект плавного появления будет виден. Давайте добавим следующий код в ваш файл style.css.
.load-more{
text-align: center;
}
.show {
opacity: 1;
transition: opacity 1000ms;
}
.hide {
opacity: 0;
transition: opacity 1000ms;
}
.end-page,
.end-page:hover {
opacity: 0.5;
pointer-events: none;
}
Дополнительный эффект затухания
Если вам действительно не нужен эффект постепенного появления добавленных сообщений, вы можете просто удалить следующие строки кода из JS-файла.
//initially add 'hide' class to the posts for fadein effect posts[i].classList.add('hide')
/*********** fadein effect ***********/ //select all hidden posts let hiddenPosts = postContainer.querySelectorAll('.hide'),
//set time out and make the posts visible //css transition will fade in timer = setTimeout( function(){ Array.prototype.map.call( hiddenPosts, function(el){ el.classList.remove('hide') el.classList.add('show') }) }, 300) /*********** fadein effect ends ***********/
Аналогичным образом удалите коды CSS .show
и .hide
из файла style.css. Это удалит эффект затухания. На этом этапе вы можете удалить код разбиения на страницы по умолчанию paginate_links()
из связанных php-файлов. Или вы можете использовать CSS, чтобы скрыть элемент.
Задача для вас
Хотите поиграть с кодом? Вот у меня есть задание для вас подумать и сделать. Наш JavaScript управляется событиями с помощью кнопки «Загрузить еще». Теперь изучите объекты window
и document
и попробуйте сделать с ними бесконечную прокрутку. Вы можете это сделать? С нетерпением жду этого.
#task 2 — В этом руководстве Архив пользовательских сообщений WordPress с REST API и ajax мы использовали jQuery ajax. Попробуйте преобразовать его в чистый JavaScript с помощью fetch()
API.
Полезные ресурсы для API выборки JavaScript
Здесь вы можете найти несколько полезных ресурсов для руководств по JavaScript —