113. 前端JavaScript(一)全局设置与前端API

由于drupal前端js内容庞大,本系列将分多个主题逐个讲述较常用和较重要的前端资源库,并以序号进行标识,推荐按序号阅读

 

前言:

在开始前端js探索前有一些注意事项:

ES6升级:

Drupal8.4开始核心使用ES6开发js程序,但为每个ES6版本的js文件都添加了自动转码的ES5版本文件,因此我们在查看源代码时应该查看ES6版本(也就是.es6.js后缀的文件),里面有开发者清晰的注释说明,ES5版本的js是依据ES6版本自动转码生成的,注释均被去除了,在使用上目前依然使用ES5版本的js

JS代码风格:

Drupaljs程序采用airbnb编码风格,参看地址:

  https://github.com/airbnb/javascript

也可以查看drupal官网上对代码风格的介绍:

  https://www.drupal.org/docs/develop/standards/javascript

drupal使用ESLint来检查代码风格,ESLint 是一个js代码规范和错误检查工具,官网地址为:

  https://cn.eslint.org/

在核心目录下存放了ESLint的配置文件,drupal以前的js编码风格存放在“.eslintrc.legacy.json”配置中,现在推荐的风格保存在“.eslintrc.json”中

准备:

如果你还不清楚后端是怎么处理js文件的,请参考本系列以下主题:

  《资源库assets library详解》

  《响应附属处理attachments_processor

  《资源解析器AssetResolver

如果你需要整理补充自己的js知识体系,云客为你准备了以下资料:

  《PHP开发者的JavaScript快速文档》

 

核心库core/drupalSettings

用于后端向前端提供js设置信息,渲染数组的“$render_array['#attached']['drupalSettings']”键和资源库的“drupalSettings”键用于在后端保存将传递到前端的js设置信息,在最终页面上设置信息将被合并,并以json方式保存到前端的如下标签中:

  <script type="application/json" data-drupal-selector="drupal-settings-json"></script>

该标签称为js设置保存标签,后端模块可以通过以下钩子向页面提供js设置数据:

  hook_js_settings_build(&$settings, $assets);

  hook_js_settings_alter(array &$settings, \Drupal\Core\Asset\AttachedAssetsInterface $assets)

详见本系列《资源解析器AssetResolver》,对应类:\Drupal\Core\Asset\AssetResolver::getJsAssets

渲染数组提供的设置优先级高于资源库。“core/drupalSettings”库仅有一个js文件:

  /core/misc/drupalSettingsLoader.js

该文件读取上文js设置保存标签的内容并在window对象上建立一个全局变量:drupalSettings,前端任何依赖“core/drupalSettings 库的js都可以访问全局变量drupalSettings获得配置信息,不管在head还是在body中加载“core/drupalSettings”库,设置标签总是出现在其前,该库也总是出现在依赖她的库前,如果js需要使用设置功能,必须声明依赖“core/drupalSettings”库,该库本身提供了一些设置信息:

path:
      baseUrl:值为$request->getBaseUrl() . '/'
      scriptPath:脚本路径
      pathPrefix:路径前缀
      currentPath:当前路径 
      currentPathIsAdmin:当前路径是否为管理路径
      isFront:当前页是否为首页
      currentLanguage:当前语言的语言代码
      currentQuery:当前查询参数,如果存在才有
pluralDelimiter:复数字符串的分隔符"\03";
ajaxPageState:
      theme_token:保护令牌,仅在当前主题不是默认主题时存在
      theme:当前主题机器名
      libraries:已被加载的库集的最小表示(集合中被其他库依赖的库不存在)

这些设置信息由system_js_settings_alter()负责初始化,其他模块提供的比较常用的设置有:

user.uid:当前用户id

user.permissionsHash:当前用户权限哈希

editor:编辑器配置

 

核心库core/domready

该库仅一个js文件:

  /core/assets/vendor/domready/ready.min.js

用于在文档加载完成后(派发DOMContentLoaded事件时)自动执行回调:

  domready(fn);

参数fn是用于执行的回调,该库添加了一个全局(window对象的属性)函数domready用于添加回调,可反复调用以添加多个需要文档就绪后执行的回调,添加的异步回调在事件循环中属于宏任务,在已经就绪后调用该函数添加的回调,将立即放入事件列队

 

核心库core/drupal

系统JSAPI,依赖于设置和core/domready,有两个js文件:

文件一:/core/misc/drupal.js

整个文件在运行一个闭包,其中参数window.drupalTranslations来自翻译数据文件,详见本系列《前端js中的翻译》篇,参数window.drupalSettings是后端提供的设置数据;该文件定义了一个全局变量Drupal,用作名字空间,全部drupal提供的前端API接口函数被定义在该变量下,但该文件并没有包含全部API接口,因为部分API是可选加载的,比如进度条、Ajax等,这些可选组件定义的接口也在全局变量Drupal上,只在加载后才可用;该文件定义的API接口函数如下:

Drupal.throwError(error)

以异步方式抛出错误,方便调试,这种方式不会中断当前列队任务的执行

Drupal.formatString(str, args);

格式化一个字符串,字符串中可以包含占位参数,占位参数的值在args中传递,args是一个对象,属性值代表要替换占位参数的值,属性名的第一个字符有特殊含义:

如果是“@”那么意指属性值是一个原始文本,里面不会存在标签,将先进行html转义处理后再替换

如果是“!”那么代表属性值是安全的,将直接替换

如果既不是“@”也不是“!”,那么将先进行html转义并放入“<em class="placeholder"></em>”中再替换

Drupal.checkPlain(str);

将字符串参数中的“&”、“<”、“>”以及单双引号全部替换为html实体(&amp;&lt;&gt;&#39;&quot;后返回

Drupal.stringReplace(str, args, keys)

用参数替换字符串中的占位符后返回,参数str是包含占位符的字符串,参数args是一个对象,属性名为占位符,属性值为要替换的值,参数keys可以指定仅替换哪些占位符,以数组方式列出占位符,如果要替换args中的全部参数可以指定为非数组值,比如null

Drupal.t(str, args, options)

返回单数翻译,str为要翻译的字符串,args为可选翻译参数,options为选项参数,其属性仅context使用,以指定翻译上下文;在使用该函数时参数尽量以字面量方式使用,而不要使用变量,这是为了让后端从js文件中提取翻译源字符串和上下文,详见本系列《前端js中的翻译》篇

Drupal.formatPlural(count, singular, plural, args, options)

复数翻译,参数count代表传递的数量,参数singular代表单数时的字符串,参数plural代表复数时的字符串,参数args代表需要替换的额外占位符,参数options代表选项,其属性仅context可用,以指定翻译上下文,该方法内部使用单数翻译方法,同理参数尽量使用字面量方式。

Drupal.url(path)

典型的用于传递一个路由中的路径,然后返回一个完整的drupal路径,该方法可以让调用者不用考虑语言前缀、协议等问题,这些自动添加到返回路径中,如Drupal.url('node/36');将返回“/zh-hans/node/36”,注意传递的路径不要以“/”开头

Drupal.url.toAbsolute(url)

传递一个不带协议、主机的路径,返回一个带协议的绝对路径,该方法的协议和主机来自当前页面,如果传递的路径以“/”开始,那么会在其前追加协议和主机(此情况不会考虑语言前缀等,此时可与Drupal.url(path)组合使用),如果不以“/”开始,那么返回的绝对路径是相对于当前页面的路径,假设当前页面为:

  http://www.dp.com/zh-hans/node/36

Drupal.url.toAbsolute('/node/36');返回:

  http://www.dp.com/node/36

Drupal.url.toAbsolute('node/36');返回:

  http://www.dp.com/zh-hans/node/node/36

如果传递带协议的绝对路径将原封不动返回

Drupal.url.isLocal(url)

判断一个url是否为本站的地址,返回布尔值,true代表是,参数可以是绝对路径,也可以是非绝对路径,httpshttp视为同一个站,其他协议将返回false

Drupal.encodePath(item):

用于对url的组成部分进行编码(不是对整个url编码),内部采用encodeURIComponent方法,但不对“/”编码,注意和encodeURI()的区别,后者是对整个url编码,前者仅对url的各组成部分编码,因此前者会编码url各组成部分之间的分隔符,如冒号、正斜杠、问号和井字号。

Drupal.theme(func, ...args)

用于输出一些有固定特征内容的格式化字符串,通常是一些标签块,这称为主体化输出,如进度条标签、占位符标签等等;这是一个路由方法,参数func应该是Drupal.theme对象的一个函数类型的属性的属性名,意为调用这个属性函数并将随后的参数传递给它,最后返回该属性函数的返回值

Drupal.theme.placeholder(str)

将传递的字符串进行html转义后包装在“<em class="placeholder"></em>”中返回

 

变量Drupal.behaviors:

用于全局保存行为对象,其属性是行为对象behavior,行为是指页面元素上事件触发的动作,每个行为对象可选的有一个附加行为方法(attach属性)或分离行为方法(detach属性),也就是:

Drupal.behaviors.behavior.attach

Drupal.behaviors.behavior.detach”,

她们都应是方法function类型,参数默认为文档对象:document和设置对象:drupalSettings,用于给元素附加或分离行为,其他js可以在同步阶段通过Drupal.behaviors来注册行为对象,比如“drupal.form”库就注册了一个行为对象:Drupal.behaviors.formSingleSubmit,该行为对象为get方法以外的表单附加了相同值只能提交一次的行为;attach属性会在文档就绪时执行,如果发生异常,将异步抛出错误,不会中断当前任务执行

Drupal.attachBehaviors(context, settings)

在文档准备就绪时自动执行Drupal.behaviors中行为对象的附加行为方法,传入的参数是文档对象:document和设置对象:drupalSettings,这两个参数也是该方法的默认参数值,如果发生异常,将异步抛出错误,不会中断当前任务执行,换句话说就是每个行为对象的附加动作都会被执行

Drupal.detachBehaviors(context, settings, trigger)

用于执行全部行为对象的行为分离动作,也就是“Drupal.behaviors.behavior.detach”,参数默认值是文档对象:document,设置对象:drupalSettings,触发分离的动作名(往往是unloadmoveserialize),如果发生异常,将异步抛出错误,不会中断当前任务执行

 

文件二:/core/misc/drupal.init.js

该文件做三件事:

如果加载了jQuery,那么让渡变量“$”的控制权

html标签加上“js”类名,样式表可以据此判断前端是否启用了js

在文档就绪时执行:Drupal.attachBehaviors(document, drupalSettings);

 

补充:

1、前端浏览器中国区使用占比(数据来自百度统计2018.10.01-2019.03.31):

Chrome    45.67%

IE 9.0        9.10%

IE 11.0      6.34%

IE 8.0        5.79%

QQ       5.47%

2345         5.13%

搜狗         4.53%

Firefox      2.62%

Safari        2.45%

其他         12.90%

2Drupal8在匿名访问时,默认主题首页没有加载任何js文件

3、官方目前还没有较系统的前端文档,仅有较简单的介绍,见:

https://www.drupal.org/docs/8/api/javascript-api/javascript-api-overview

本书共137小节:

评论 (写第一个评论)