Wordpress AJAX на чистом Javascript

ajax в wordpress на чистом javascript

Ранее я уже писал про то как в wordpress можно динамически выводить записи и страницы в модальном окне. Вот ссылка. Там я использовал jQuery для работы с AJAX. Но не всегда есть возможность использовать какие-то библиотеки. Сейчас я пишу плагин и в нём я сделал фильтр записей в зависимости от заданных произвольных полей. Дело в том, что плагином могут использоваться в десятках темах и подключение лишних скриптов не хорошо для оптимизации сайта, особенно сейчас, когда в моду вошли различные JS-фрэймворки, а в wordpress-е до сих пор стоит jQuery очень старой версии.

Старт

Сначало я предлагаю создать вам событие на странице. На этой странице будет выводиться весь контент, который связан с работой с AJAX. Допустим пусть будет так:

do_action('our_page_whith_ajax');

Ну конечно же это стоит делать в новом шаблоне страницы. После того как вы создали новый шаблон и в нём создали событие перейдите в файл functions.php в вашей теме.

В functions.php

Регистрация скрипта нам будет нужна по двум причинам:

  1. Нужно напичатать служебный скрипт wordpress’а после нашего скрипта.
  2. Мы не хотим, чтобы наш скрипт подключался на других страницач и по-этому мы вызовем его подключение по собыитию.

И так. сам код:

// 
function our_page_whith_ajax_script(){     wp_register_script('our_page_whith_ajax_js', get_template_directory_uri() . 'assets/js/front.js', array('jquery'), '1.0', true);     
// Не забудьте создать assets/js/front.js     
// Можно тут зарегистрировать стили для нашеё страницы 
} 
add_action( 'wp_enqueue_scripts', 'our_page_whith_ajax_script' );

Отсюда нам нужно запомнить наш handler our_page_whith_ajax_js. Если вам нужна помощь по использованию данной функции вы можете перейти в мою статью о правильном подключении JS и CSS в WordPress.

2. Добавим действие к хуку

В начале мы объявили на нашей странице do_action(‘our_page_whith_ajax’) к по которому у нас и будет вызываться «всякое» для AJAX-са. Теперь мы добавим функцию, которая будет за всё это отвечать.

functions our_page_whith_ajax(){     
// Далее наш код будет тут 
} 
add_action('our_page_whith_ajax', 'our_page_whith_ajax');

Давайте сразу добавим вызов нашего скрипта и объявим несколько функций.

function our_page_whith_ajax(){     
// Подключение скриптов
 wp_enqueue_script('our_page_whith_ajax_js');
// Напечатаем кнопку которая будет отправлять наш запрос      do_action('our_page_button');
// Напечатаем блок в котором будет выводиться наш ajax контент      do_action('our_page_response_box');
// Напечатаем наш скрипт с ajax
 add_action('wp_footer', 'our_page_js_in_footer');
} 
add_action('our_page_whith_ajax', 'our_page_whith_ajax');
add_action( 'wp_enqueue_scripts', 'our_page_localize_script', 99 );

Обращу внимание на add_action(‘wp_footer’, ‘our_page_js_in_footer’). Наш ajax-скрипт можно создать и в том js-файле который мы подключили, но в моём деле мне содержание моего js зависело от php и я его там изменял, да и так сложнее и интереснее.

3. Объявим наши функции и хуки

function our_page_button(){     
	echo '<button data-type="our-btn">Нажать</button>'; 
} 
add_action('our_page_button', 'our_page_button'); 
function our_page_response_box(){     
	echo '<div data-type="our-resposnse-box"';
}
add_action('our_page_response_box', 'our_page_response_box');
 function our_page_localize_script(){     
 // our_page_whith_ajax_js - тот самы хэндрег о котором я говорил     
 // Запомним admin_url     
 wp_localize_script('our_page_whith_ajax_js', 'admin_url', array('url' => admin_url('admin-ajax.php'))); }
 function our_page_js_in_footer(){     
	 ?>     
		 <script type="text/javascript" >
		 // Получаем нашу кнопку
		 var btn = document.querySelector('[data-type="our-btn"]');
		 function OUR_submitListener(event){
			 //На всякий случай убираем дефолтные действия
			 event.preventDefault();
			 
			 // Создадим FormData с данными, чтобы передать их на сервер в POST-запросе
			 var data = new FormData();
			 
			 // Наполним его данными 		 
			 data.append('explF', 'data');
			 data.append('explT', 'data2');
			 // И тут же прописываем action который будет вызываться в php
			 data.append('action', 'our_action');

			 // Далее то что касается отправки запроса на сервер
			 var xhttp = new XMLHttpRequest(); 
			 xhttp.onreadystatechange = function () {
				 if(this.readyState == 4 && this.status == 200){ 
					 // В блок с data-type="our-resposnse-box" вернём полученный HTML 
					 document.querySelector('[data-type="our-resposnse-box"]').innerHTML = this.responseText;  
				 }
			 };             
			 // Тут наш admin_url
			 xhttp.open('POST', admin_url.url, true);
			 xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
			 // Отправляем наши данные             
			 xhttp.send(data); 
		 }         
		 // Ждём клик        
		 btn.addEventListener('click', OUR_submitListener, btn);      
		 </script>     
	 <?php 
 }

Далее давайте привяжем action к php-функции в wp. Ранее в js мы определили её название здесь data.append(‘action’, ‘our_action’);

function our_page_whith_ajax_response(){
	// Получим то что пришло к нам
	$arr = $_POST;
	//и просто распечатаем     
	echo '<pre>';     
	print_r($arr);     
	echo '</pre>';
	// Прекратим процесс
	wp_die(); 
} 
// Обратите внимание где мы использовали
// our_action - это то, что и в data.append('action', 'our_action');
our_action add_action('wp_ajax_our_action', 'our_page_whith_ajax_response');
add_action('wp_ajax_nopriv_our_action', 'our_page_whith_ajax_response');

итоге на странице вы получите такую запись:

Array(
	[action] => our_action
	[explF] => data
	[explT] => data2 
)

Fetch-реализация

Сейчас я довольно часть пользуюсь fetch и наверное и вам бы хотелось. Сейчас я вам покажу реализацию на асинхронного запроса в wordpress через fetch.

И так, fetch нам заменяет XMLHttpRequest(). Следовательно и нам нужно его заменить в нашей функции, плюс я его улучшу с помощью ES6. Теперь наш скрипт будет выглядеть так:

<script>
(()=>{
	const btn = document.querySelector('[data-type="our-btn"]');
	btn.addEventListener('click', ()=>{
		const url = admin_url.url;
		const data = new FormData();
		data.append('explF', 'data');
		data.append('explT', 'data2');
		data.append('action', 'our_action');
		fetch(url, {
			methode: 'post',
			body:data
		}).then(
			(response)=>(response.text()), // Возвращаем текст из промиса
			(reject)=>(console.error('Fetch отклонён')) // Обрабатываем ошибку
		).catch() // перехватываем ошибку сервер
		.then(
			(text)=>{
				document.querySelector('[data-type="our-resposnse-box"]').innerHTML = text; // Записываем текст в нужный блок
			}
			(reject)=>(console.error('Ошибка на клиенте'))
		).catch() // перехватываем ошибку фронтенда
	});
})()
</script>

Напоминаю! Fetch не поддерживается старыми браузерами. Попробуйте использовать Axios — он обёртка над XMLHttpRequest в отличие от fetch

P.S.

Если у вас возникли сложности то напишите мне в вк, ссылка в подвале сайта. Пользуйтесь моими сервисами, используйте stickjaw для быстрого изменения пропорций блога. Пока!)