客户端脚本使用

现代 Web 应用程序, 除了呈现并发送到浏览器的静态 HTML 页面外, 还包含 JavaScript, 用于通过操纵现有元素或通过 AJAX 加载新内容来修改浏览器中的页面。 本节介绍 Yii 提供的用于向网站添加 JavaScript 和 CSS 以及动态调整它们的方法。

注册脚本

使用 yii\web\View 对象时,可以动态注册前端脚本。 这里有两个专门的方法:

注册内联脚本

内联脚本对于配置,动态生成的代码以及由 widgets 中包含的可重用前端代码创建的小片段非常有用。 registerJs() 添加这些方法可以像如下使用:

$this->registerJs(
    "$('#myButton').on('click', function() { alert('Button clicked!'); });",
    View::POS_READY,
    'my-button-handler'
);

第一个参数是我们想插入的实际 JS 代码。 它将被包含到 <script> 标签中。第二个参数确定脚本应插入页面的位置。 可能的值是:

最后一个参数是一个唯一的脚本 ID,主要是用于标识一段代码块,在添加一段新的代码块时,如果当前页面已经存在同样 ID 代码块时,那么将会被新的替换。 如果你不传这个参数,JS 代码本身将会作为 ID 来使用。

注册脚本文件

registerJsFile() 的参数类似于 registerCssFile()。在以下示例中, 我们注册 main.js 文件,依赖于 yii\web\JqueryAsset。这意味着 main.js 文件将在 jquery.js 之后添加。没有这样的依赖规范, main.jsjquery.js 之间的相对顺序将是未定义的,代码将不起作用。

外部脚本的引入使用像下面这样:

$this->registerJsFile(
    '@web/js/main.js',
    ['depends' => [\yii\web\JqueryAsset::className()]]
);

这将为 base URL 下的 /js/main.js 脚本添加一个标记。

我们强烈建议使用 asset bundles 来注册外部 JS 文件而非使用 registerJsFile() 来注册。 因为这些允许更好的灵活性和更精细的依赖配置。 此外,使用资源包允许您组合和压缩多个 JS 文件,这对于高流量网站来说是比较理想的方式。

注册 CSS

与 JavaScript 类似,您可以使用注册 CSS 使用 registerCss()registerCssFile()。 前者注册一个 CSS 代码块,而后者注册一个外部 CSS 文件。

注册内联 CSS

$this->registerCss("body { background: #f00; }");

上面的代码将导致将以下内容添加到页面的 <head> 部分:

<style>
body { background: #f00; }
</style>

如果要指定样式标记的其他属性,请将 name-values 数组传递给第二个参数。 最后一个参数是一个唯一的 ID,用于标识样式块,并确保仅在代码中的不同位置注册相同样式时仅添加一次。

注册 CSS 文件

可以使用以下方法注册 CSS 文件:

$this->registerCssFile("@web/css/themes/black-and-white.css", [
    'depends' => [\yii\bootstrap\BootstrapAsset::className()],
    'media' => 'print',
], 'css-print-theme');

上面的代码将把 /css/themes/black-and-white.css 文件的链接添加到页面的 <head> 部分。

  • 第一个参数指明被注册的 CSS 文件。
  • 第二个参数指明 <link> 标签的 HTML 属性,选项 depends 是专门处理 指明 CSS 文件依赖于哪个资源包。在这种情况下,依赖资源包就是 BootstrapAsset。这意味着 CSS 文件将 被添加在 BootstrapAsset 之后
  • 最后一个参数指明一个 ID 来标识这个 CSS 文件。 如果参数未提供,则将使用 CSS 文件的 URL。

我们强烈建议使用 asset bundles 来注册外部 CSS 文件, 而非使用 registerCssFile() 来注册。 使用资源包允许你合并并且压缩多个 CSS 文件,对于高流量的网站来说,这是比较理想的方式。 它还提供了更大的灵活性,因为应用程序的所有资源依赖性都在一个位置配置。

注册资源包

如前所述,建议使用资源包而不是直接注册 CSS 和 JavaScript 文件。 您可以获取有关如何定义资源包的详细信息在 "Assets" 部分. 至于使用已定义的资源包,它非常简单:

\frontend\assets\AppAsset::register($this);

在上面的代码中,在视图文件的上下文中,AppAsset 包在当前视图上注册(由 $this 表示)。 从小部件中注册资产包时,您将传递小部件的 $view 来替代($this->view)。

生成动态 Javascript

在视图文件中,HTML 代码通常不直接写出, 而是由某些依赖于视图变量的 PHP 代码生成。 为了使用 Javascript 操作生成的 HTML,JS 代码也必须包含动态部分,例如 jQuery 选择器的 ID。

要将PHP变量插入 JS 代码, 必须正确转义它们的值。 特别是当 JS 代码插入 HTML 而不是驻留在专用的 JS 文件中时。 为此,Yii 提供了 Json 助手类的 htmlEncode() 方法,其用法将在以下示例中显示。

注册全局 JavaScript 配置

在这个例子中, 我们使用一个数组将全局配置参数从应用程序的 PHP 部分传递给 JS 前端代码。

$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'
);

上面的代码将注册一个包含 JavaScript 的 <script> 标签定义, 例如:

var yiiOptions = {"appName":"My Yii Application","baseUrl":"/basic/web","language":"en"};

在您的 JavaScript 代码中,您现在可以像 yiiOptions.baseUrlyiiOptions.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 它包含有效 JS 语法中的字符串,可以将其插入到 JavaScript 代码中以放置 函数中的动态字符串调用 alert()

注意: 使用 Heredoc 时,请注意 JS 代码中的变量命名, 因为以 $ 开头的变量可能会被解释为 PHP 变量, 这些变量将被其内容替换。 jQuery 函数以 $($. 的形式不被解释为 PHP 变量, 可以安全地使用。

yii.js 脚本

注意: 本节尚未编写。 它应该包含 yii.js 提供的功能的说明:

  • Yii JavaScript 模块
  • CSRF 参数处理
  • data-confirm 处理
  • data-method 处理
  • 脚本过滤
  • 重定向处理