114. 前端JavaScript(二)jQuery、进度条等
本主题接着《前端JavaScript(一)》讲述,推荐按序号阅读
核心库core/jquery:
该库用于加载大名鼎鼎的jquery,在Drupal8.7中使用的是v3.2.1版本,此时最新的jquery版本是v3.4.1,网络上有v3.2.1版本的chm格式中文参考手册下载,drupal中大多重要库依赖jquery,本主题不做介绍,但务必学会使用,这是Drupal前端基础也是很多web项目的基础
该库还加载了以下js文件:
/core/assets/vendor/jquery/jquery-extend-3.4.0.js
作用是为v3.4.0以下版本的jquery重新定义jQuery.extend方法,该方法用于合并对象,或者为jQuery对象增加方法
核心库core/jquery.once:
加载/core/assets/vendor/jquery-once/jquery.once.min.js,该库依赖于jquery库,jquery对象可视为一个元素集对象,用于对jquery对象执行某种操作时,保证jquery对象中每个元素仅被执行一次,该库使用频率很高,但实现却很简单,在内部以是否添加标记的方式判断元素是否已被执行过,她扩展了jquery对象,在原型上添加了以下三个方法(在jquery对象上均可使用这些方法):
once(id):
返回被id过滤后的jquery对象,参数id是一个字符串,如果没有传递将采用默认值“once”,在jquery对象中的元素上如果存在id标识说明是被执行过的,不存在则没有,以此方式判断是否被执行过,返回的jquery对象中每个元素会在内部被id标记,换句话说在返回对象上再次以相同id调用once(id)将返回空
removeOnce(id)
移除jquery对象中元素的id标识,返回的jquery对象仅包括被id标记过的那些元素,但返回时已经被移除了标记
findOnce(id)
返回被id过滤后的jquery对象,其中仅保留被id标记过的元素
核心库core/classList:
这是一个垫片库,用于跨浏览器实现元素的classList属性支持,有些浏览器品牌或同一个品牌浏览器的早期版本不支持元素的classList属性,或者支持不统一,该库解决兼容问题,让元素的classList属性有一个统一的接口,便于用户操作元素的类属性,是在原型上修改的,因此所有元素对象均可用,元素的classList属性有以下方法:
add( String [, String] )
添加指定的类值,可以一次性传递多个参数以添加多个类,如果这些类已经存在于元素的属性中,那么它们将被忽略。
remove( String [,String] )
删除指定的类值,同样可以传递多个参数以删除
item ( Number )
按集合中的索引返回类值。
toggle ( String [, force] )
当只有一个参数时:切换 class value; 即如果类存在,则删除它并返回false,如果不存在,则添加它并返回true。
当存在第二个参数时:如果第二个参数的计算结果为true,则添加指定的类值,如果计算结果为false,则删除它
contains( String )
检查元素的类属性中是否存在指定的类值。
replace( oldClass, newClass )
用一个新类替换已有类。
核心库core/drupal.active-link:
文件:core/misc/active-link.es6.js
加载后便运行,立即添加一个行为对象,在文档就绪时为页面中的当前链接添加类:“is-active”,在卸载事件(unload)发生时取消这个类;如果语言、路径、查询参数均与当前页面相同,则这个链接视为激活链接(当前链接),判断依据保存在元素的以下属性中:
“data-drupal-link-system-path”
“hreflang”
“data-drupal-link-query”
当前页面的这些信息保存在全局设置对象drupalSettings中
核心库core/drupal.progress:
文件:core/misc/progress.es6.js
用于实现进度条提示,进度条原理是在页面显示一个进度条,然后每隔一段时间向服务器请求进度数据,然后更新,该库依赖jquery;需要使用进度条的库需要声明对她的依赖,使用示例如下:
function testProgress() {
let bar = new Drupal.ProgressBar('yunke');
document.body.appendChild(bar.element[0]);
let percent = 0;
let timer = setInterval(function () {
bar.setProgress(++percent, '进度消息', '进度label');
if (percent >= 100) {
clearTimeout(timer);
}
}, 100)
}
如果在文档就绪时执行该函数,将在页尾模拟现实一个进度条,说明如下:
实例化:
new Drupal.ProgressBar(id, updateCallback, method, errorCallback);
将得到一个进度条对象,对应的进度条页面元素是:
<div id="${id}" class="progress" aria-live="polite">
<div class="progress__label"> </div>
<div class="progress__track"><div class="progress__bar"></div></div>
<div class="progress__percentage"></div>
<div class="progress__description"> </div>
</div>
可通过该元素中相关类属性控制进度条外观,实例化后进度条元素并没有插入DOM,构造方法参数:
id:为该进度条元素的id属性值
updateCallback:每次执行进度条更新后的回调,其参数依次为更新百分比、更新消息、进度条对象
method:向服务器获取进度数据时使用的http方法,get或post,默认为get
errorCallback:发生错误时的回调,参数为进度条对象
这些参数都保存在进度条对象对应的属性上(属性名同参数名),这里假设进度条对象的变量名为bar,也就是bar.id、bar.updateCallback、bar.method、bar.errorCallback
进度条对象还有一个元素属性bar.element,保存对应的进度条元素,在实例化进度条对象后需要将其插入DOM才可见,她是一个jQuery对象,所以插入时需要采用bar.element[0]以便转化为DOM对象,进度条对象有一些方法被定义在她的原型上,插入后可用这些方法进行相关操作,如下:
bar.setProgress(percentage, message, label)
更新进度条,并在每次更新后执行更新回调,参数如下:
percentage:整数,0-100之间,代表百分比
message:描述消息
label:进度条标题
bar.startMonitoring(uri, delay):
开始执行进度条更新动作,也意味着开始执行任务,参数:
uri:获取进度数据的服务器url
delay:每隔多少毫秒执行一次更新数据请求,也可以理解为执行一次进度条更新;注意该时间并不是不管服务器响应,严格的按这个时间间隔发送请求,准确理解是:在成功收到服务器响应后,会在这个时间间隔之后再次发送请求,每一个请求都在上一个请求完成后间隔该时间再发起,换句话说这不会导致服务器并发
bar.stopMonitoring():
停止执行更新数据请求,并删除进度条对象上保存的uri地址
bar.sendPing():
向服务器发起请求获得更新数据,要求服务器返回json数据,格式如下:
status:状态码,如果为0则视为服务器端发生错误
data:发生错误时(状态码为0)返回的消息
percentage:整数,0-100之间,代表百分比
message:用于进度条显示的描述消息
label:用于进度条显示的标题
在成功发起后将设置下一次发起任务,如果服务器端或ajax错误将不再更新进度条
bar.displayError(string):
在服务器端发生错误或ajax错误时显示错误消息,并执行错误回调,当显示错误时进度条将被隐藏
文件:core/misc/timezone.es6.js
添加一个行为对象,在文档就绪时查找具备类属性“timezone-detect”的元素,并为其自动设置用户所在的时区,值如“Asia/Shanghai”,被找到的元素应当是一个表单元素,用来自动侦查用户时区,时区信息的获取是通过收集浏览器的特征并发送给后端,由服务器返回的,服务器控制器为:
\Drupal\system\Controller\TimezoneController::getTimezone
获取时采用同步方式,这意味着取回数据前浏览器会被暂时冻结
本系列后续有一期主体全面介绍时区,这里仅是关于前端的一个简略片段