ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Blockly FieldDate 日期字段插件实战指南:基于浏览器原生日期选择器的 @blockly/field-date 深度解析

Blockly FieldDate 日期字段插件实战指南:基于浏览器原生日期选择器的 @blockly/field-date 深度解析 前端低代码UI组件【免费下载链接】blocklyThe web-based visual programming editor.项目地址https://gitcode.com/gh_mirrors/bl/blockly点击查看免费下载blockly/field-date是 Blockly 官方生态中的一个字段插件它让积木块获得一个基于浏览器原生typedate输入控件的日期字段用户点击后可直接调用浏览器自带的日期选择器无需引入任何第三方日期组件。本文将以该插件在仓库中的 README 为核心骨架结合 field_date.ts 源码与 测试用例完整讲解其安装方式、JavaScript / JSON 两种积木定义用法、内部校验与时区处理机制、无障碍支持以及测试方法帮助你在自己的 Blockly 项目中快速接入并定制日期字段。插件定位字段Field是什么在 Blockly 中字段Field是附着在积木上的可编辑元素例如数字输入、下拉菜单、文本输入等。Blockly 核心库通过 字段注册表 维护了一张字段类型名 → 字段类的映射当积木定义中出现field_date类型时Blockly 会从注册表中取出对应的FieldDate类实例化。blockly/field-date正是这样一个标准插件它没有修改 Blockly 核心而是以官方插件的形态向字段注册表中注入一个名为field_date的新字段类型。其核心特性是——直接复用浏览器原生日期选择器而非自绘日历 UI因此跨平台外观一致、几乎零维护成本。从源码结构看该插件包packages/plugins/field-date规模非常精简仅包含三个源码文件src/field_date.tsFieldDate主类与配置类型定义src/utils.ts日期格式化辅助函数src/index.ts统一导出入口。安装blockly/field-date以 npm 包形式分发官方 README 提供了 Yarn 与 npm 两种安装方式二者等价Yarnyarn add blockly/field-datenpmnpm install blockly/field-date --save安装前请注意版本约束。查看插件的 package.json 可知当前仓库内该插件版本为13.3.0peerDependencies要求blockly: ^13.2.0即需要配套安装 Blockly v13 及以上版本版本号与 Blockly 主版本保持同步发布详见 CHANGELOG.md其中记录了自 8.0.0 起迁移到 TypeScript、9.0.0 起要求 Blockly v11 等多次 Breaking Change开发脚本统一由blockly/dev-scripts提供包括build、lint、start、test等。因此在实际项目中请确保blockly与blockly/field-date的主版本号匹配避免出现 API 不兼容。基本用法插件使用上最关键的一步是导入插件模块以触发字段注册。无论是 JavaScript 方式还是 JSON 方式定义积木都必须保证blockly/field-date的模块被加载过它的模块顶层执行了Blockly.fieldRegistry.register(field_date, FieldDate)。JavaScript 方式当以代码形式编写积木定义时需要同时导入 Blockly 核心与FieldDate类然后像使用任何内置字段一样将其追加到输入上import * as Blockly from blockly; import {FieldDate} from blockly/field-date; Blockly.Blocks[test_fields_date] { init: function () { this.appendDummyInput() .appendField(date: ) .appendField(new FieldDate(2020-02-20), FIELDNAME); }, };这里new FieldDate(2020-02-20)的第一个参数指定了字段的初始值格式必须为YYYY-MM-DDFIELDNAME则是字段名称后续可通过block.getFieldValue(FIELDNAME)读取日期值。JSON 方式更推荐的做法是使用 JSON 积木定义此时只需导入blockly/field-date让注册生效field_date就能像内置字段一样被 JSON 解析器识别import * as Blockly from blockly; import blockly/field-date; Blockly.defineBlocksWithJsonArray([ { type: test_fields_date, message0: date: %1, args0: [ { type: field_date, name: FIELDNAME, date: 2020-02-20, }, ], }, ]);JSON 定义中type: field_date指定字段类型name指定字段名date指定初始值。值得注意的是date参数在源码中被定义为可选项见 field_date.ts 中的FieldDateFromJsonConfig接口当省略date时字段默认值为当前日期——源码底部通过FieldDate.prototype.DEFAULT_VALUE toLocalISOString(new Date())实现见 field_date.ts。插件自带的 测试页 test/index.ts 展示了更多 JSON 定义细节例如还可以在args0中为字段添加tooltiptooltip: This date block has a tooltip!以及提供alt降级字段当field_date不可用时回退为普通标签字段并演示了把日期字段放在 shadow block影子块中使用的情形。深入源码FieldDate 的实现原理要真正用好这个字段理解其源码实现非常关键。FieldDate直接继承自 Blockly 核心的FieldTextInput文本输入字段因此天然继承了文本编辑、校验器、序列化等能力再在此基础上覆盖若干钩子方法实现日期语义。类结构与序列化export class FieldDate extends Blockly.FieldTextInput { SERIALIZABLE true; ... }SERIALIZABLE true声明该字段可被 Blockly 的 XML 序列化机制保存/恢复。这与 README 中字段可编辑、应可序列化的设计准则一致日期字段的值必须在保存工作区后原样还原。构造函数签名与文本输入字段完全兼容constructor( value?: string, // 初始值YYYY-MM-DD 格式缺省为当前日期 validator?: FieldDateValidator, // 校验器见下文 config?: FieldDateConfig, // 配置对象 )其中FieldDateValidator就是Blockly.FieldTextInputValidator类型接收日期字符串、返回合法日期字符串或null以中止修改FieldDateConfig继承自FieldTextInputConfig并显式禁用了对日期字段无意义的spellcheck选项见 field_date.ts。JSON 定义的解析由静态方法fromJson完成见 field_date.ts它从 JSON 对象中解构出date作为初始值其余键作为配置传给构造函数。由于使用了new this(...)子类继承fromJson时也能正确实例化。值校验与规范化字段的核心逻辑在doClassValidation_方法中见 field_date.ts它负责把用户输入规范化为标准格式空值直接返回null拒绝用new Date(newValue)解析若结果为非法日期isNaN(newDate.getTime())则返回null若输入本身是YYYY-MM-DD的 ISO 格式通过isISOFormat判断原样返回否则假定输入携带了时间信息例如2023-04-28T12:00:00Z调用toLocalISOString(newDate)去除时间、转换为用户时区下的日期字符串。配套的isISOFormat与toLocalISOString工具函数位于 src/utils.ts 与 field_date.tsisISOFormat(value)用正则/\d\d\d\d-\d\d-\d\d/匹配并校验整串完全匹配形如2000-02-20返回true2000-02-20T00:00:00Z返回falsetoLocalISOString(date)先按en-US区域格式化为M/D/YYYY再通过两次正则替换转回YYYY-MM-DD并补齐前导零从而避免date.toISOString()返回 UTC 日期导致日期串一天的问题。显示文本与无障碍getText_方法见 field_date.ts控制字段在积木上显示的文本。它调用getLocaleDateStringsrc/utils.ts用Intl.DateTimeFormat(navigator.language, {timeZone: UTC})将YYYY-MM-DD渲染为本地化格式例如en-US区域显示2/14/2020。需要注意源码注释中的提示不同浏览器的文本与输入框内显示可能存在差异例如 iOS Safari 中点击后会显示Feb 14, 2020。无障碍方面该字段覆盖了两个 ARIA 钩子getAriaTypeName()返回Blockly.Msg[ARIA_TYPE_FIELD_DATE]该消息键在 消息文件 中定义为date并被翻译成 130 余种语言getAriaValue()将日期渲染为长格式自然语言描述如January 20, 2020供屏幕阅读器朗读避免读成带斜杠的短格式。编辑器唤起与原生日期选择器FieldDate最亮眼的行为是点击字段后直接弹出浏览器原生日期选择器其实现贯穿三个方法showEditor_见 field_date.ts调用super.showEditor_(e, true)第二个参数true表示quietInput即仅为该字段关闭模态输入而不影响整个工作区的modalInputs选项随后聚焦并全选输入框再调用showDropdown()showDropdown见 field_date.ts给输入框添加blocklyDateInput样式类并在requestAnimationFrame回调中调用HTMLInputElement.showPicker()弹出原生日期选择器源码注释指出该方法在旧版 TypeScript 与 Safari 中存在兼容性限制因此做了类型断言widgetCreate_见 field_date.ts创建底层 HTML 输入框后将其type设置为date这是整个浏览器默认日期输入能力的来源。此外updateSize_见 field_date.ts在原有边距基础上额外增加 20 像素避免日期选择器的日历图标与文本相互裁剪。平台相关样式修补源码文件底部有一段条件注册的 CSS见 field_date.ts当运行在 macOS 上时通过Blockly.Css.register将 Safari 日期输入框内部 Shadow DOM 的 4px 内边距清零使内部输入框与外部文本节点高度一致。文件顶部注释还给出了::-webkit-datetime-edit、::-webkit-calendar-picker-indicator等伪元素说明开发者可在部分浏览器上进一步定制日期选择器的外观但兼容性因浏览器而异官方不保证一致效果。校验器Validator与错误值处理FieldDate支持 Blockly 标准的校验器机制通过setValidator(fn)注册回调回调接收新值字符串返回规范化的字符串生效或null中止本次修改。插件测试 field_date_test.mocha.js 中的Validators用例给出了三类典型行为校验器返回null时setValue(3030-03-30)不生效字段保持原值2020-02-20校验器把日改为20 号时newValue.substr(0, 8) 2 newValue.substr(9, 1)3030-03-30变为3030-03-20校验器返回undefined时值原样设置不做任何改动。对于非法输入测试用例invalidValueTestCases覆盖了undefined、null、NaN、不可解析字符串bad、非法月份2020-13-20、非法日2020-02-32等场景——这些值都会被doClassValidation_拒绝字段回落为默认值当前日期。合法值3030-03-30则被原样保存并按en-US区域显示为3/30/3030。时区行为这是最容易踩坑的地方日期字段最容易出错的场景是时区。由于 JavaScript 的new Date(YYYY-MM-DD)会按 UTC 零点解析而date.toISOString()又按 UTC 输出直接转换很容易让用户看到前一天/后一天的日期。blockly/field-date通过两个设计规避了该问题纯日期输入原样保留doClassValidation_中isISOFormat(newValue)为真时直接返回原值不做任何时区换算带时间的输入按用户时区折算非 ISO 格式的输入先由toLocalISOString按本地时区重新格式化成日期。field_date_test.mocha.js 中专门设置了Time Zones测试套件通过切换process.env.TZ在America/New_York西、Etc/Universal零时区、Europe/Paris东三套时区下验证行为例如西部时区-05:00下输入2000-01-23T23:00:00-05:00得到2000-01-23而输入2000-01-23T00:00:0000:00得到前一天的2000-01-22零时区下西部时区的23:00对应本地已是2000-01-24东部时区01:00下2000-01-23T23:00:0000:00同样折算为2000-01-24。这组用例精确刻画了日期按用户本地时区解释的语义也提醒集成方如果应用面向全球用户务必理解字段值代表的是用户本地日期而不是 UTC 日期。测试与本地调试在仓库中运行插件自身的测试可直接在packages/plugins/field-date目录执行npm test或使用仓库统一脚本测试由blockly/dev-scripts test驱动其测试用例即 field_date_test.mocha.js。该文件覆盖了runConstructorSuiteTests构造字段含从 JSON 构造时合法/非法值的处理runSetValueTests空字段与已有值字段上setValue的行为Validators校验器三种返回值的语义Time Zones三套时区下的日期折算。此外test/index.ts 提供了一个基于blockly/dev-tools的 Playground 测试页通过createPlayground将多种测试积木注入工作区开发者可运行npm start后在浏览器中手动验证日期字段在普通积木、带标签积木、shadow block 等不同上下文中的表现——工具箱中同时包含了默认日期值与自定义日期值如 2020-02-20、2021-03-13两类测试块。小结blockly/field-date是一个小而美的官方字段插件安装一条命令、定义积木两种写法JavaScript / JSON核心实现则完全建立在 BlocklyFieldTextInput的扩展机制之上。它通过widgetCreate_将底层输入框设为typedate、用showPicker()唤起浏览器原生日期选择器并通过doClassValidation_、toLocalISOString与getLocaleDateString三个关键函数保证了YYYY-MM-DD值的严格校验、本地时区语义与本地化显示。若你的 Blockly 应用需要日期输入能力无需自绘日历或引入重型组件库直接在args0中声明type: field_date即可获得与浏览器一致的日期选择体验。该插件以 Apache 2.0 协议开源见 README 的 License 一节源码与测试全部收录于本仓库可放心在商业与非商业项目中集成使用。赞分享前端低代码UI组件【免费下载链接】blocklyThe web-based visual programming editor.项目地址https://gitcode.com/gh_mirrors/bl/blockly点击查看免费下载相关推荐Blockly 插件 blockly/field-dependent-dropdown 实战基于父字段值自动联动切换下拉选项Blockly 插件 blockly/field dependent dropdown 实战基于父字段值自动联动切换下拉选项 本文以 Blockly 官方插前端低代码UI组件Blockly 角度字段插件 blockly/field-angle 深度指南CHANGELOG 演进解读、参数配置与源码原理Blockly 角度字段插件 blockly/field angle 深度指南CHANGELOG 演进解读、参数配置与源码原理 blockly/field前端低代码UI组件Blockly 位图字段插件 blockly/field-bitmap 完整使用指南Blockly 位图字段插件 blockly/field bitmap 完整使用指南 本指南围绕 Blockly 官方插件 blockly/field bi前端低代码UI组件创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表