“中国要复兴、富强,必须在开源软件领域起到主导作用,为了国家安全和人类发展,责无旁贷,我们须为此而奋斗”——By:云客
本主题接着《前端JavaScript(四)》讲述,推荐按序号阅读
核心库core/drupal.form:
文件: core/misc/form.es6.js
该库做以下事情:
一、为jquery对象添加两个扩展方法:
drupalSetSummary(callback)
设置一个生成摘要的回调函数,调用时接收jquery集中第一个元素作为参数,回调应该返回一个字符串作为摘要;callback参数也可以是一个非函数值,此时每次取回摘要将返回这个值
drupalGetSummary()
和前一个函数是对应的,用于取回摘要信息
二、附加文档就绪后自动执行的行为:
Drupal.behaviors.formSingleSubmit
防止GET类型以外的表单在相同值的情况下连续多次提交,相同值是以jquery的serialize方法返回值做比较,注意:由于serialize方法的限制,文件类型表单控件的值不被考虑,图片类型提交按钮的值不被考虑,换句话说这些控件的值不论是否相同都不可以连续提交
Drupal.behaviors.formUpdated
文档就绪时为表单绑定更新事件,事件名为:change.formUpdated和input.formUpdated,这使用了防抖函数,最多300毫秒执行一次,实际上起到了事件限洪的作用,最终派发的事件名是formUpdated,通过ajax新加载的表单值有变化也会派发更新事件
Drupal.behaviors.fillUserInfoFromBrowser:
使用浏览器本地储存中的用户信息自动填充表单,仅限三种用户信息:'name', 'mail', 'homepage',对应着表单输入控件的name值,需自动填充的表单需有data-user-info-from-browser属性,且仅在输入控件的值为空字符串或默认值时才填充,默认值保存在输入控件的“data-drupal-default-value”属性中,浏览器保存的用户信息保存在本地储存中(localStorage),键名为:`Drupal.visitor.${info}`,这些信息来自曾经表单提交时设置的值。
三、为哈希改变和点击片段绑定事件
为页面中所有包含“#”的“a”标签绑定“click.form-fragment”事件,为window对象绑定“hashchange.form-fragment”事件,事件回调函数采用了防抖变体限洪,需要响应哈希改变或片段变化的事件处理器应被绑定到“hashchange.form-fragment”事件上
核心库core/drupal.entity-form
文件:core/misc/entity-form.es6.js
仅用于实体表单,用于处理版本和翻译提示信息,强耦合不通用
核心库core/modernizr
文件:core/assets/vendor/modernizr/modernizr.min.js
是一个独立的js库,用于检测浏览器对H5和css3的特性支持
核心库core/drupal.date:
文件:core/misc/date.es6.js
用于处理输入表单中日期类型控件,使得有统一的显示方式(弹出日期选择器),如果浏览器原生支持日期控件则该库什么也不做,否则将使用jquery日期处理库,以便点击日期控件后弹出日期选择框
日期类型的input元素应当具备data-drupal-date-format属性,其值为日期格式,如:“Y-m-d”
(注:jquery的data('drupalDateFormat');方法就是获取该属性的值,内部连字符和驼峰写法是等效的)
在后端日期控件采用日期元素类型('#type'=> 'date')处理,元素类如下:
\Drupal\Core\Render\Element\Date
表单前端验证:
在HTML5之前的时代,针对表单的正则验证、必填性验证,都需要开发者自行写js实现,现在,如果浏览器支持HTML5,那么可以直接给表单元素设置pattern、required属性来实现,如:
<input pattern="yk[0-9]+" type="text" name="title" value="" required="required" aria-required="true">
pattern:值为验证用正则表达式,在有值的情况下必须符合该正则,但可以无值
required:指示是否必填,值为‘required’,存在时为必填
aria-required:指示辅助设备,该字段为必填项
注意:针对这一块系统并未提供什么库,完全依赖浏览器原生功能,如果在IE8之类的老式浏览器之下运行,前端并无验证提醒,如果网站主要群体使用这种浏览器应该自定义验证js,但不管前端是否验证,在后端一定是会被验证的,见:\Drupal\Core\Render\Element\FormElement::validatePattern
核心库core/drupal.displace
如果你想在页面左上方显示一个固定框,但又不想遮挡工具栏和菜单栏怎么办?这就是该库的作用。
该库用于辅助处理相对于文档有固定位置的元素的正确显示,使得当窗口尺寸变化时,那些依赖偏移定位的固定元素也能够合理正确的显示,通常是为了不遮挡工具栏或管理菜单栏;该库注册一个全局函数:
Drupal.displace()
当调整窗口大小时会自动运行该函数,需要时也可以手动调用,她将计算当前页面中在上下左右四个方向被保护元素占用的最大位置,为以下全局变量赋值:
Drupal.displace.offsets
该变量的键名是top、right、bottom、left之一,其值是一个数字,代表该方向被保护的安全区域,假设left的值为240,表示:如果我们想显示一个相对于页面有固定位置的元素,此时它的左距不应低于240px,否则会遮挡位于这个区域的元素(这些可能被遮挡的元素就是被保护的元素,通常是管理菜单栏和工具栏),该函数的目的就是提供信息给其他js,告诉它们不要遮挡受保护的区域。
那么该函数是如何计算的呢?受保护的元素其实是具备以下属性的元素:
“data-offset-${edge}”
这里${edge}是四个方向之一,如:data-offset-left,工具栏和管理菜单栏就具有这样的属性,属性值如果是一个数字则以数字为准,如果不是数字将实时计算,最终在Drupal.displace.offsets中的值是以这些受保护元素中该方向最大的那个为准,这样就能安全的表明受保护区域
示例:
在页面左上方显示一张固定位置的通知图片,但不要遮挡工具栏和管理菜单栏,jquery代码如下:
let img = $('<img src="/sites/default/files/2018-08/qq.jpg">');
img.prependTo($('body'));
Drupal.displace();
let offsets = Drupal.displace.offsets;
img.css('position','absolute');
img.css('left',offsets.left);
img.css('top',offsets.top);
img.css('z-index',99);
那些依赖偏移定位的元素应该监听“drupalViewportOffsetChange”事件,以便窗口改动时调整自己的位置,回调应有两个参数,第一个接收事件对象,第二个会被传递新计算出来的Drupal.displace.offsets参数
反馈互动