Есть ли способ проверить, загружается ли jQuery с помощью PHP?
У меня есть два разных плагина в Joomla, которые загружают jQuery JS, но когда он включен более одного раза, он работает некорректно.
Чтобы объяснить процесс немного больше: Joomla предлагает возможность перехватывать HTML-источник до его рендеринга, в основном работая над исходным кодом.
Это использует функцию:
onPrepareContent(&$row, &$params, $limitstart)
$ row – это содержимое HTML на странице, которое может быть проанализировано.
Я думал, что, возможно, preg_match может работать, но не имеет большого опыта с ним.
Еще лучше, вы можете проверить его с помощью JavaScript, а затем добавить его в голову, если он отсутствует.
if (typeof jQuery == 'undefined') { var head = document.getElementsByTagName("head")[0]; script = document.createElement('script'); script.id = 'jQuery'; script.type = 'text/javascript'; script.src = 'js/jquery.js'; head.appendChild(script); }
Я предполагаю, что вы используете Joomla1.0?
Joomla буферизирует содержимое, используя выходной буфер PHP. т.е.: ob_start ().
Вы можете получить содержимое, используя: ob_get_contents ();
Таким образом, вы можете иметь регулярное выражение, которое проверяет JQuery. Что-то вроде:
$jquery_loaded = preg_match("/<script.*?src=[\"']jquery[^\"']\"/i", ob_get_contents());
должно быть достаточно хорошим. (Я не тестировал это).
Использование ob_get_contents () может не работать в ситуациях, поскольку буфер вывода PHP может быть вложен. Вы можете запустить столько буферов в буферах.
Для Joomla1.5 вы можете получить буфер через API, который гарантирует, что вы всегда получаете выход Joomla.
$Document =& JFactory::getDocument(); $buffer = $Document->getBuffer();
Будь то Joomla1.0 или 1.5, вы должны заметить, что Joomla может добавить в буфер в любой момент, пока не отобразит результат (вызовы ob_flush () или эквивалентные). Таким образом, ваша проверка JQuery должна учитывать, что JQuery можно загрузить после проверки.
Обратите внимание, что буфер Joomla создается не только для HTML, но может быть CSS, JavaScript, XML, JSON и т. Д. Поэтому вы можете проверить HTML, прежде чем выполнять тесты JQuery. Вы также можете проверить панель администратора.
$mainframe =& JFactory::getApplication(); $doctype = $document->getType(); // deactivate for backend if ($mainframe->isAdmin() || $doctype != 'html') { return false; }
Для справки здесь приведен пример системного плагина, который частично делает то, что вы хотите. Это плагин совместимости для MooTools1.2.
<?php /** * MooTools1.2 w/ 1.1 compat for AjaxChat * @copyright www.fijiwebdesign.com * @author gabe@fijiwebdesign.com * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL */ // included only defined( '_JEXEC' ) or die( 'Direct Access to this location is not allowed!' ); jimport( 'joomla.plugin.plugin' ); /** * Joomla PHP Speedy Integration * * @author gabe@fijiwebdesign.com */ class plgSystemAjaxchat extends JPlugin { /** * Constructor * * For php4 compatability we must not use the __constructor as a constructor for plugins * because func_get_args ( void ) returns a copy of all passed arguments NOT references. * This causes problems with cross-referencing necessary for the observer design pattern. * * @access protected * @param object $subject The object to observe * @param array $config An array that holds the plugin configuration * @since 1.0 */ function plgSystemAjaxchat(& $subject, $config) { parent::__construct($subject, $config); $mainframe =& JFactory::getApplication(); $document =& JFactory::getDocument(); $doctype = $document->getType(); // deactivate for backend if ($mainframe->isAdmin()) { return false; } // add mootools 1.2 if ( $doctype == 'html' ) { $document->addScript('components/com_ajaxchat/js/mootools-1.2-core.js'); $document->addScript('components/com_ajaxchat/js/mootools-1.2-more.js'); $document->addScript('components/com_ajaxchat/js/mootools-1.2-core-compat.js'); $document->addScript('components/com_ajaxchat/js/mootools-1.2-more-compat.js'); } } /** * After Templte output is in buffer */ function onAfterRender() { $mainframe =& JFactory::getApplication(); $document =& JFactory::getDocument(); $doctype = $document->getType(); // deactivate for backend if ($mainframe->isAdmin()) { return false; } // Only render for HTML output if ( $doctype !== 'html' ) { return; } // get the output buffer $body = JResponse::getBody(); // remove mootools if not needed if (stristr($body, 'mootools.js') || stristr($body, 'mootools-uncompressed.js')) { $body = preg_replace("/<script.*?mootools(-uncompressed)?\.js.*?<\/script>/i", '', $body); } else { $body = preg_replace("/<script.*?mootools-1\.2\-.*?\.js.*?<\/script>[\s\t\r\n]*/i", "\n", $body); } JResponse::setBody($body); } } ?>
Сначала нужно сделать чек в javascript. например:
window.onload = function() { if (typeof(window.jQuery)=="undefined") alert('jQuery no load'); else alert('jQuery Ok'); }
то вы можете отправить сообщение ajax на сервер.
Это невозможно. PHP является серверным, а Javascript (язык JQuery написан) – это клиентская сторона. PHP-код по существу должен запускаться до того, как текст, который включает Javascript, даже будет отправлен пользователю и попытался быть загруженным.
Лучше всего не включать jQuery более одного раза. Вы можете сделать это, заменив все свои включенные вещи следующим:
<script type='text/javascript'> if($) { } // test to see if the jQuery function is defined else document.write("<script type='text/javascript' src='jquery.js'></script>"); </script>
По общему признанию, это немного взломать, и может быть лучший способ.
EDIT: немного подумал: это может даже не работать из-за асинхронности загрузки библиотеки jQuery с сервера. Кажется, что лучший способ сделать это будет с обработчиком событий onload
прикрепленным к скрипту, но DOM не поддерживает это.
EDIT 2: Хорошо, теперь я думаю, что лучше всего просто включить его один раз на странице, используя только один тег сценария для каждой страницы. Вы можете сделать это, добавив его в какой-либо глобальный заголовок, а затем удалив его везде. Тогда, несмотря ни на что, не включайте его снова. Это может означать, что вы загружаете его на некоторые страницы, которые ему не нужны, но из-за кеша в современных браузерах это не должно быть проблемой.
Возможно, вы захотите попробовать использовать объект JDocument
для получения заголовков, поиска jQuery, а затем, при необходимости, сброса настроек. getHeadData()
и setHeadData()
должны помочь вам оттуда. Вы можете получить текущий объект JDocument
с помощью этого кода:
$document =& JFactory::getDocument();
Вы также можете посмотреть на этот ответ на аналогичный вопрос: конфликты Joomla, jQuery
В этом случае вы фактически удаляете избыточные нагрузки jQuery.
Разве Joomla не предоставляет способ сообщить вам, какие сценарии он включает? (Zend Framework имеет такой список)