Работа с клиентскими скриптами
Современные веб-приложения, помимо статических HTML-страниц, которые рендерятся и отправляются браузеру, содержат JavaScript, используемый для модификации страницы в браузере путём манипулирования существующими элементами или загрузки нового содержимого через AJAX. Этот раздел описывает методы, предоставляемые Yii для добавления JavaScript и CSS на веб-сайт, а также динамической корректировки этих элементов.
Регистрация скриптов
При работе с объектом yii\web\View вы можете динамически регистрировать скрипты для фронта. Для этого есть два специальных метода:
- registerJs() для встроенных скриптов
- registerJsFile() для внешних скриптов
Регистрация встроенных скриптов
Встроенные скрипты полезны для конфигурации, динамически генерируемого кода и небольших фрагментов, создаваемых многократно используемым кодом фронта, содержащимся в виджетах. Метод registerJs() для добавления этих скриптов может быть использован следующим образом:
$this->registerJs(
"$('#myButton').on('click', function() { alert('Button clicked!'); });",
View::POS_READY,
'my-button-handler'
);
Первый аргумент — фактический код JS, который мы хотим вставить на страницу. Он будет обернут в <script> тег. Второй аргумент определяет позицию вставки скрипта на странице. Возможные значения:
- View::POS_HEAD для раздела head.
-
View::POS_BEGIN для вставки сразу после открывающего
<body>. -
View::POS_END для вставки сразу перед закрывающим
</body>. -
View::POS_READY для выполнения кода при событии document
ready. Это автоматически зарегистрирует jQuery и обернёт код в соответствующий jQuery-код. Это значение по умолчанию. -
View::POS_LOAD для выполнения кода при событии document
load. Также, как и выше, это автоматически зарегистрирует jQuery.
Последний аргумент — уникальный идентификатор скрипта, используемый для идентификации блока скрипта и замены существующего блока с тем же идентификатором вместо добавления нового. Если его не указать, код JS будет использоваться в качестве идентификатора. Это используется для предотвращения регистрации одного и того же кода несколько раз.
Регистрация файлов скриптов
Аргументы для registerJsFile() аналогичны аргументам для registerCssFile(). В следующем примере мы регистрируем файл main.js с зависимостью от yii\web\JqueryAsset. Это означает, что файл main.js будет добавлен ПОСЛЕ jquery.js. Без указания такой зависимости относительный порядок между main.js и jquery.js будет неопределённым, и код не будет работать.
Внешний скрипт может быть добавлен следующим образом:
$this->registerJsFile(
'@web/js/main.js',
['depends' => [\yii\web\JqueryAsset::className()]]
);
Это добавит тег для скрипта /js/main.js, расположенного по адресу приложения основного URL.
Сильно рекомендуется использовать наборы ресурсов для регистрации внешних файлов JS вместо registerJsFile(), так как это позволяет лучшую гибкость и более тонкую конфигурацию зависимостей. Также использование наборов ресурсов позволяет объединять и сжимать несколько JS-файлов, что желательно для веб-сайтов с высоким трафиком.
Регистрация CSS
Аналогично JavaScript, вы можете регистрировать CSS с помощью registerCss() или registerCssFile(). Первый регистрирует блок CSS-кода, а второй — внешний CSS-файл.
Регистрация встроенного CSS
$this->registerCss("body { background: #f00; }");
Код выше приведёт к добавлению следующего в <head> раздел страницы:
<style>
body { background: #f00; }
</style>
Если вы хотите указать дополнительные свойства тега style, передайте массив имён и значений в качестве второго аргумента. Последний аргумент — уникальный идентификатор, используемый для идентификации блока стилей и обеспечения того, что он добавляется только один раз, в случае, если тот же стиль зарегистрирован из разных мест кода.
Регистрация CSS-файлов
CSS-файл может быть зарегистрирован следующим образом:
$this->registerCssFile("@web/css/themes/black-and-white.css", [
'depends' => [\yii\bootstrap\BootstrapAsset::className()],
'media' => 'print',
], 'css-print-theme');
Вышеприведённый код добавит ссылку на файл CSS /css/themes/black-and-white.css в <head> раздел страницы.
- Первый аргумент указывает CSS-файл для регистрации.
@webв этом примере — псевдоним основного URL приложения. - Второй аргумент указывает HTML-атрибуты для результирующего
<link>тега. Опцияdependsобрабатывается специально. Она указывает, на какие наборы ресурсов зависит этот CSS-файл. В данном случае зависимым набором ресурсов является BootstrapAsset. Это означает, что CSS-файл будет добавлен после CSS-файлов из BootstrapAsset. - Последний аргумент указывает идентификатор, идентифицирующий этот CSS-файл. Если он не предоставлен, будет использован URL CSS-файла.
Сильно рекомендуется использовать наборы ресурсов для регистрации внешних CSS-файлов вместо registerCssFile(). Использование наборов ресурсов позволяет объединять и сжимать несколько CSS-файлов, что желательно для веб-сайтов с высоким трафиком. Также это обеспечивает большую гибкость, так как все зависимости наборов ресурсов вашего приложения настроены в одном месте.
Регистрация наборов ресурсов
Как уже упоминалось, рекомендуется использовать наборы ресурсов вместо прямой регистрации CSS и JavaScript-файлов. Подробности о том, как определять наборы ресурсов, можно найти в разделе "Ресурсы". Что касается использования уже определённых наборов ресурсов, это очень просто:
\frontend\assets\AppAsset::register($this);
В приведённом коде, в контексте файла представления, набор AppAsset зарегистрирован в текущем представлении (представленном $this). При регистрации наборов ресурсов из виджета, вы передадите $view виджета вместо этого ($this->view).
Генерация динамического JavaScript
В файлах представлений HTML-код часто не выводится напрямую, а генерируется некоторым PHP-кодом, зависящим от переменных представления. Для того, чтобы сгенерированный HTML можно было обрабатывать с помощью JavaScript, код JS также должен содержать динамические части, например, идентификаторы селекторов jQuery.
Для вставки PHP-переменных в JS-код их значения должны быть корректно экранированы. Особенно это важно, когда JS-код вставляется в HTML вместо размещения в отдельном JS-файле. Yii предоставляет метод htmlEncode() помощника Json для этой цели. Его использование будет показано в следующих примерах.
Регистрация глобальной конфигурации JavaScript
В этом примере мы используем массив для передачи глобальных параметров конфигурации из PHP-части приложения в JavaScript-код фронта.
$options = [
'appName' => Yii::$app->name,
'baseUrl' => Yii::$app->request->baseUrl,
'language' => Yii::$app->language,
// ...
];
$this->registerJs(
"var yiiOptions = ".\yii\helpers\Json::htmlEncode($options).";",
View::POS_HEAD,
'yiiOptions'
);
Вышеприведённый код зарегистрирует <script>-тег, содержащий определение JavaScript-переменной, например:
var yiiOptions = {"appName":"My Yii Application","baseUrl":"/basic/web","language":"en"};
Теперь в вашем коде JavaScript вы можете получить доступ к этим значениям, например, как yiiOptions.baseUrl или yiiOptions.language.
Передача переведённых сообщений
Вы можете столкнуться со случаем, когда ваш JavaScript должен выводить сообщение, реагируя на какое-либо событие. В приложении, работающем с несколькими языками, эта строка должна быть переведена на текущий язык приложения. Один из способов достижения этого — использование функции перевода сообщений, предоставляемой Yii, и передача результата в JavaScript-код.
$message = \yii\helpers\Json::htmlEncode(
\Yii::t('app', 'Button clicked!')
);
$this->registerJs(<<<JS
$('#myButton').on('click', function() { alert( $message ); });",
JS
);
Вышеприведённый пример кода использует PHP Heredoc синтаксис для лучшей читаемости. Это также обеспечивает лучшую подсветку синтаксиса в большинстве IDE, поэтому это предпочтительный способ написания встроенного JavaScript, особенно полезно для кода, более длинного, чем одна строка. Переменная $message создаётся в PHP, и благодаря Json::htmlEncode она содержит строку в допустимом синтаксисе JavaScript, которая может быть вставлена в JavaScript-код для размещения динамической строки в вызове функции alert().
Примечание: При использовании Heredoc будьте внимательны с именами переменных в JS-коде, так как переменные, начинающиеся с
$могут быть интерпретированы как PHP-переменные, которые будут заменены их содержанием. Функция jQuery в форме$(или$.не интерпретируется как PHP-переменная и может безопасно использоваться.
Скрипт yii.js
Примечание: Этот раздел ещё не написан. Он должен содержать объяснение функциональности, предоставляемой
yii.js:
- Yii JavaScript Модули
- Обработка CSRF параметра
data-confirmобработчикdata-methodобработчик- фильтрация скриптов
- обработка перенаправления
© 2008–2017 by Yii Software LLC
Licensed under the three clause BSD license.
http://www.yiiframework.com/doc-2.0/guide-output-client-scripts.html