Проверьте, включен ли jQuery в заголовок (Joomla) - PullRequest
7 голосов
/ 26 августа 2009

Есть ли способ проверить, загружен ли jQuery с использованием PHP?

У меня есть два разных плагина в Joomla, которые загружают JQuery JS, но когда он включен несколько раз, он не работает правильно.

Чтобы объяснить процесс немного подробнее: Joomla предлагает возможность перехватывать исходный HTML-код перед его рендерингом, фактически работая над самим исходным кодом.

Используется функция:

onPrepareContent(&$row, &$params, $limitstart)

$ row - это HTML-содержимое страницы, которое можно проанализировать.

Я думал, что, возможно, preg_match может сработать, но у меня не очень много опыта с ним.

Ответы [ 6 ]

14 голосов
/ 27 ноября 2009

Еще лучше, вы можете проверить это с помощью 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); 
}
3 голосов
/ 26 августа 2009

Я предполагаю, что вы используете 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);
    }

}

?>
1 голос
/ 26 августа 2009

Вы можете попробовать использовать объект JDocument для получения заголовков, выполнить поиск jQuery, а затем выполнить сброс при необходимости. Методы getHeadData() и setHeadData() должны помочь вам в этом. Вы можете получить текущий JDocument объект с этим кодом:

$document =& JFactory::getDocument();

Вы также можете посмотреть на этот ответ на похожий вопрос: Joomla, конфликтующие модули jQuery

В этом случае вы фактически удаляете избыточные нагрузки jQuery.

1 голос
/ 26 августа 2009

Это невозможно. 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>

По общему признанию, это что-то вроде хака, и может быть, есть лучший способ.

РЕДАКТИРОВАТЬ: После недолгого размышления: это может даже не работать из-за асинхронности загрузки библиотеки jQuery с сервера. Кажется, что лучший способ сделать это - использовать обработчик событий onload, подключенный к сценарию include, но DOM не поддерживает это.

РЕДАКТИРОВАТЬ 2: Хорошо, теперь я думаю, что лучше всего было бы просто включить его один раз на странице, используя только один тег сценария на страницу. Вы можете сделать это, добавив его в какой-либо глобальный заголовок, а затем удалив его повсюду. Тогда, несмотря ни на что, не включайте его снова. Это может означать, что вы загружаете его на некоторые страницы, которые ему не нужны, но из-за кеша в современных браузерах это не должно быть проблемой.

1 голос
/ 26 августа 2009

Должен сначала сделать проверку в javascript.например:

window.onload = function()
{
   if (typeof(window.jQuery)=="undefined")
      alert('jQuery no load');
   else
      alert('jQuery Ok');
}

тогда вы можете отправить сообщение через ajax на сервер.

0 голосов
/ 26 августа 2009

Если Joomla не предоставляет способ сообщить вам, какие скрипты он включает? (У Zend Framework такой список есть)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...