
Elementor 编辑器命令体系详解document/dynamic 组件下的动态标签启用、禁用与设置【免费下载链接】elementorThe most advanced frontend drag drop page builder. Create high-end, pixel perfect websites at record speeds. Any theme, any page, any design.项目地址: https://gitcode.com/GitHub_Trending/el/elementor导读本文基于 Elementor 官方开发文档 docs/assets/dev/js/editor/document/dynamic/readme.md 及编辑器前端源码深入讲解$e.components.get(document/dynamic)这一 Document 子组件它提供了启用enable、禁用disable与修改设置settings动态标签Dynamic Tags的标准命令接口。读者读完本文后将掌握如何通过$e.run(...)以编程方式控制任意控件如标题、链接、图片的动态标签行为理解__dynamic__设置在底层如何被写入元素设置、如何参与历史记录History的撤销/重做并能在实际开发中组合使用三个命令完成启用 → 改格式 → 禁用的完整动态化工作流。组件概览$e.components.get(document/dynamic)document/dynamic是 Elementor 编辑器Document组件下的一个子组件其职责非常聚焦提供一种方式来启用enable、修改change或禁用disable与动态标签Dynamic Tags关联的动态设置。在源码层面该组件定义于 assets/dev/js/editor/document/dynamic/component.js结构十分简洁import ComponentBase from elementor-api/modules/component-base; import * as commands from ./commands/; export default class Component extends ComponentBase { getNamespace() { return document/dynamic; } defaultCommands() { return this.importCommands( commands ); } }getNamespace()返回的document/dynamic即为组件的命令命名空间所有命令都注册在$e.run(document/dynamic/xxx)之下defaultCommands()通过importCommands()批量注册commands/目录下导出的全部命令见 commands/index.js按字母序导出Disable、Enable、Settings。该组件隶属于更上层的Document组件$e.components.get(document)其定位在 component.md 中描述为用于命名描述文档中由命令引起的变化的命名空间。Document 组件之下还包含 Elements、History、Repeater、Save、UI 等子组件而 Dynamic 专门负责动态标签相关的三个命令如下表所示。命令总览enable / disable / settings命令调用方式说明Disable$e.run(document/dynamic/disable)禁用动态标签Enable$e.run(document/dynamic/enable)启用动态标签Settings$e.run(document/dynamic/settings)修改动态标签设置三个命令共享相同的目标参数约定文档中每个元素都有唯一 ID可通过elementor.getContainer( ID )解析为唯一的Container对象命令以container单个目标或containers批量目标指定作用对象且两者只能传其一详见 component.md 中的约定说明。Disable 命令 --$e.run(document/dynamic/disable)名称Disable。描述禁用动态设置。返回值{void}参数属性类型描述container{Container}目标元素单个containers{Container[]}目标元素批量settings{Object}需要禁用的动态设置示例假设我们有一个标题title上挂了动态标签的 Heading 组件想要禁用它。编辑器面板中带有动态标题/日期的 Heading页面上的 Heading 效果// 通过 id 获取视图再取得其 container。 const eWidget elementor.getContainer( 0b9da89 ); // 禁用 title 上的动态标签 date。 $e.run( document/dynamic/disable, { container: eWidget, settings: { title: true, }, } );该调用将禁用 title 的动态标签。源码实现commands/disable.jsexport class Disable extends DisableEnable { apply( args ) { const { settings, containers [ args.container ] } args; containers.forEach( ( container ) { container container.lookup(); Object.keys( settings ).forEach( ( setting ) { container.dynamic.unset( setting ); } ); $e.internal( document/elements/set-settings, { container, settings: { __dynamic__: container.dynamic.toJSON(), }, } ); } ); } }可以看到Disable 的apply()遍历settings的所有键对container.dynamic依次执行unset( setting )只移除指定控件的动态绑定不影响其他控件的动态设置随后通过内部命令$e.internal(document/elements/set-settings)把序列化后的__dynamic__写回元素设置。Enable 命令 --$e.run(document/dynamic/enable)名称Enable。描述启用动态设置。返回值{void}参数属性类型描述container{Container}目标元素单个containers{Container[]}目标元素批量settings{Object}需要启用的动态设置示例为 Heading 启用动态标题假设你有一个普通的 Heading 组件// 获取 heading 的 container。 const eWidget elementor.getContainer( 0b9da89 ), postDateTag elementor.dynamicTags.tagDataToTagText( elementorCommon.helpers.getUniqueId(), post-date, new Backbone.Model( {} ) ); // 为 title 启用动态标签 post-date。 $e.run( document/dynamic/enable, { container: eWidget, settings: { title: postDateTag, }, } );执行后将为 heading 标题启用动态标签post-date这里需要重点解释tagDataToTagText的返回值。它定义于 assets/dev/js/editor/components/dynamic-tags/manager.jstagDataToTagText( tagID, tagName, tagSettings ) { tagSettings encodeURIComponent( JSON.stringify( ( tagSettings tagSettings.toJSON( { remove: [ default ] } ) ) || {} ) ); return [elementor-tag id tagID name tagName settings tagSettings ]; }它把{ tagID, tagName, tagSettings }序列化为形如[elementor-tag id... namepost-date settings...]的短代码文本——这正是 Elementor 在元素设置__dynamic__中持久化动态标签的方式。三个参数中tagID标签实例的唯一 ID示例中使用elementorCommon.helpers.getUniqueId()生成tagName动态标签的注册名如post-date、site-url等tagSettings标签的配置模型通常为Backbone.Model示例中为new Backbone.Model( {} )无额外配置。源码实现commands/enable.jsexport class Enable extends DisableEnable { apply( args ) { const { settings, containers [ args.container ] } args; containers.forEach( ( container ) { container container.lookup(); container.dynamic.set( settings ); $e.internal( document/elements/set-settings, { container, settings: { __dynamic__: container.dynamic.toJSON(), }, } ); } ); } }与 Disable 相对Enable 通过container.dynamic.set( settings )把控件名 → 动态标签短代码的映射写入动态设置集合。Settings 命令 --$e.run(document/dynamic/settings)名称Settings。描述修改动态设置。返回值{void}参数属性类型描述container{Container}目标元素单个containers{Container[]}目标元素批量settings{Object}需要修改的动态设置示例修改标题上post-date动态标签的设置。假设你有一个标题挂了post-date动态标签的 Heading现在希望把日期格式改为人类可读格式human-readable使用如下示例// 获取 heading 的 container。 const eWidget elementor.getContainer( 0b9da89 ), postDateTag elementor.dynamicTags.tagDataToTagText( elementorCommon.helpers.getUniqueId(), post-date, new Backbone.Model( { format: human } ) ); // 修改动态设置。 $e.run( document/dynamic/settings, { container: eWidget, settings: { title: postDateTag, }, } );执行后的效果注意由于tagDataToTagText会把tagSettings序列化进短代码manager.js因此在new Backbone.Model( { format: human } )中传入的format配置会一并编码进settings属性从而在修改设置场景下达到更新标签参数的目的。源码实现commands/settings.js与 Enable/Disable 相比有两点关键差异源码注释直接点明The difference betweendocument/elements/settingsanddocument/dynamic/settingsis: thatdocument/elements/settingsapply settings tocontainer.settingsanddocument/dynamic/settingsaffectcontainer.settings.__dynamic__, also clearing the dynamic ifargs.settingsis empty.即document/elements/settings作用于container.settings而document/dynamic/settings作用于container.settings.__dynamic__并且当args.settings为空时会清空全部动态设置。export class Settings extends $e.modules.editor.document.CommandHistoryDebounceBase { // ... apply( args ) { const { settings, containers [ args.container ] } args; containers.forEach( ( container ) { container container.lookup(); if ( ! Object.keys( settings ).length ) { container.dynamic.clear(); } else { container.dynamic.set( settings ); } $e.internal( document/elements/set-settings, { container, settings: { __dynamic__: container.dynamic.toJSON(), }, } ); } ); } }apply()的关键分支settings为空对象Object.keys(settings).length 0时调用container.dynamic.clear()整体清空该容器的动态设置否则调用container.dynamic.set( settings )合并更新最终同样通过$e.internal(document/elements/set-settings)回写__dynamic__。同时Settings 命令继承自CommandHistoryDebounceBase带防抖的历史命令基类其validateArgs()通过requireContainer()校验目标、通过requireArgumentConstructor( settings, Object, args )强制settings必须是Object。底层原理__dynamic__、历史记录与联动 Hook__dynamic__如何被写入元素设置三个命令在apply()阶段的收尾动作完全一致——通过内部命令$e.internal(document/elements/set-settings, ...)将container.dynamic.toJSON()序列化结果写入__dynamic__设置项。也就是说动态标签的持久化形态是元素设置里的__dynamic__字段其值为控件名 →[elementor-tag ...]短代码的映射对象。撤销/重做CommandDisableEnable 与 restoreenable与disable命令共享基类DisableEnablecommands/base/disable-enable.jsexport default class DisableEnable extends CommandDisableEnable { static getName() { return Dynamic; } static getEnableCommand() { return document/dynamic/enable; } static getDisableCommand() { return document/dynamic/disable; } getTitle() { return __( Dynamic ); } }它继承自CommandDisableEnablecommand-bases/command-disable-enable.js后者为启用/禁用类命令提供了通用的历史记录与恢复逻辑initialize()根据当前执行的命令判断this.type为enable或disablevalidateArgs()复用requireContainer()与requireArgumentConstructor( settings, Object, args )双校验getHistory()为每个容器记录settings变更subTitle由getTitle()DynamicElementsSettings.getSubTitle( args )拼接而成type即 enable/disablerestore( historyItem, isRedo )撤销disable时会翻转isRedo因为 disable 的逆操作是 enable再通过$e.run( toggle, { container, settings } )重新执行对应的启用/禁用命令并调用container.panel.refresh()刷新面板。Settings 命令则实现了自己的getHistory()与restore()历史记录中保存每个容器的oldcontainer.dynamic.toJSON()与new两份快照重做redo时应用new、撤销undo时恢复old见 commands/settings.js。联动 Hook动态标签控件如何回写设置在编辑器面板中直接编辑动态标签控件时最终也会落到document/dynamic/settings命令上。这由 After 型 HookHandleDynamicassets/dev/js/editor/document/hooks/data/document/elements/settings/handle-dynamic.js完成它挂载于document/elements/settings命令之后当容器类型为dynamic时通过elementor.dynamicTags.tagContainerToTagText( container )把动态标签容器转换回短代码文本实现见 manager.js利用container.view的id、name与model再以$e.run(document/dynamic/settings, commandArgs)将结果写回父容器的对应控件。这解释了面板操作与命令 API 之间如何打通手动编辑动态标签 →document/elements/settings→ HandleDynamic Hook →document/dynamic/settings→ 写入__dynamic__。实战组合一次完整的动态标签生命周期结合三个命令可以完成启用 → 改配置 → 禁用的完整闭环以下均假设 Heading 元素 ID 为0b9da89const eWidget elementor.getContainer( 0b9da89 ), getTag ( settings ) elementor.dynamicTags.tagDataToTagText( elementorCommon.helpers.getUniqueId(), post-date, new Backbone.Model( settings ) ); // 1. 启用为 title 绑定 post-date 动态标签。 $e.run( document/dynamic/enable, { container: eWidget, settings: { title: getTag( {} ) }, } ); // 2. 修改将日期格式改为人类可读格式。 $e.run( document/dynamic/settings, { container: eWidget, settings: { title: getTag( { format: human } ) }, } ); // 3. 禁用移除 title 上的动态标签。 $e.run( document/dynamic/disable, { container: eWidget, settings: { title: true }, } );几点实战提示批量操作三个命令均支持containers数组可一次作用于多个元素传containers时不要同时传container空 settings 即清空settings传{}给document/dynamic/settings会清空整个容器的全部动态设置而disable只会移除settings键中列出的控件历史可撤销三个命令都注册了历史记录编辑器内 Ctrl/CmdZ 可逐步回退动态标签的启用、禁用与配置变更元素 ID 获取示例中的0b9da89是文档元素的唯一 ID详见 component.md 的图例约定实际开发中可通过$e.components.get(document).utils.findContainerById( id )或编辑器导航面板获取。参考源码与文档索引组件定义assets/dev/js/editor/document/dynamic/component.js命令入口导出索引assets/dev/js/editor/document/dynamic/commands/index.js三个命令实现disable.js、enable.js、settings.js启用/禁用共享基类base/disable-enable.js 与 command-bases/command-disable-enable.js动态标签短代码生成components/dynamic-tags/manager.js面板联动 Hookdocument/hooks/data/document/elements/settings/handle-dynamic.js上层 Document 组件与元素 ID 约定component.md【免费下载链接】elementorThe most advanced frontend drag drop page builder. Create high-end, pixel perfect websites at record speeds. Any theme, any page, any design.项目地址: https://gitcode.com/GitHub_Trending/el/elementor创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考