# 动作(Action)
# 概念简介
PDF 的 "动作 (Action)" 是一种指令,可在特定事件发生时自动执行,例如打开文档、点击链接或操作表单等。动作可以实现页面跳转、表单提交、脚本运行、文件操作等功能,大幅提升 PDF 的交互性与自动化能力。
动作分为两大类:
动作 (Action):PDF 1.1 引入。可绑定在注释(如 Link、Screen、Widget)、书签(outline item)等对象的字典的 A 条目上,或绑定在文档目录(catalog)的 OpenAction 条目上。动作用于在对象被激活(如点击、选择、文档打开)时,由查看器自动执行特定操作,如跳转、启动应用、播放声音、改变注释外观等。
附加动作(Additional Action):PDF 1.2 引入。可绑定在文档(catalog)、页面、注释或表单域等对象的 AA 条目上。附加动作用于响应多种特定事件(Trigger Events),如进入、离开、按下、释放、获得/失去焦点、字段值变更等。每个事件可单独指定要执行的动作,实现更细粒度的事件驱动行为。
⚠️ 注意:
Action
(opens new window) 类及其相关子类已被废弃,所有与 Action 相关的操作请改用各对象(如 Annot、Widget、PDFFormField、PDFDoc)提供的专属接口。
# 典型使用场景
- 页面跳转:通过点击链接或按钮等跳转到指定页面或位置(GoTo、GoToR、GoToE)。
- 表单交互:包括提交表单(SubmitForm)、重置表单(ResetForm)、导入数据(ImportData),以及隐藏/显示字段(Hide)。
- 脚本自动化:在特定事件(如字段值变更、页面打开、文档保存等)时,自动执行 JavaScript 脚本。
- 多媒体与外部操作:启动外部应用(Launch)、打开 URI(URI),以及多媒体渲染(Rendition)。
# 支持的动作类型
动作类型 | 功能描述 | 可编辑(UI) | 可触发 | 接口支持 |
---|---|---|---|---|
GoTo | 跳转到当前文档的指定页面/位置/缩放 | Y | Y | Y |
GoToR | 跳转到其他 PDF 文件的指定位置(非嵌入文件) | Y | N | Y |
GoToE | 跳转到嵌入在其他 PDF 文件中的 PDF 文件的指定目标位置 | N | N | Y |
Hide | 隐藏或显示指定的表单字段 | Y | Y | Y |
ImportData | 向 PDF 导入 FDF 文件以更新表单字段 | Y | N | Y |
JavaScript | 执行 JavaScript 脚本 | Y | Y | Y |
Launch | 启动外部应用程序,通常用于打开文件 | Y | N | Y |
ResetForm | 将表单字段重置为默认值 | Y | Y | Y |
SubmitForm | 提交表单数据到指定 URL | Y | N | Y |
URI | 打开指定的 URI 地址 | Y | N | Y |
Rendition | 多媒体渲染动作 | N | Y | N |
详细动作类型及其数据结构请参考 ActionType (opens new window) 和 ActionSpecification (opens new window) 类型定义。
# 触发事件(Trigger Events)
动作的执行依赖于触发事件(Trigger Events),不同对象支持的事件类型不同。常见触发事件包括:
- 文档级(DocActionTriggerEvents (opens new window)):如文档关闭、保存、打印等。
- 页面级(PageActionTriggerEvents (opens new window)):如页面打开、关闭。
- 注释/表单域级(AnnotActionTriggerEvents (opens new window)):如鼠标进入、离开、按下、释放。
- 表单字段级(FieldActionTriggerEvents (opens new window)):如键入、格式化、值变更、重新计算。
# Action 数据结构
- ActionSpecification (opens new window):描述动作类型及其参数(如跳转目标、脚本内容等)。
- ActionHierarchy (opens new window):描述动作的层级结构,支持嵌套子动作。
- ActionData (opens new window):具体动作的数据载体。
# 主要接口说明
# 动作(Action)相关
Annot.getAllActionData()
:获取注释的所有动作数据,包括主动作和附加动作。Annot.getActionData()
:获取注释的主动作数据。Annot.setAction(actionSpec)
:设置注释的主动作。Annot.appendAction(actionSpec)
:向注释追加主动作。Annot.updateAction(actionObjNumber, actionData)
:更新注释的主动作。Annot.removeAction(actionObjNumber)
:移除注释的主动作。Annot.supportsAction()
:判断当前注释类型是否支持动作(支持类型包括:screen、link、sound、widget)。
# 附加动作(Additional Action)相关
getAdditionalAction
: 获取附加动作实例。Widget.getAdditionalAction()
:获取表单域上的附加动作实例。PDFPage.getAdditionalAction()
:获取页面上的附加动作实例。PDFFormField.getAdditionalAction()
:获取表单字段上的附加动作实例。PDFDoc.getAdditionalAction()
:获取文档上的附加动作实例。
AdditionalAction.setAction(trigger, actionSpec)
:设置指定事件的附加动作。AdditionalAction.addAction(trigger, actionSpec)
:追加附加动作。AdditionalAction.updateActionData(trigger, actionObjNumber, actionData)
:更新附加动作。AdditionalAction.removeAction(trigger, actionObjNumber)
:移除附加动作。AdditionalAction.getActions([triggers])
:获取指定事件的附加动作列表。
# 文档级动作
PDFDoc.setOpenAction(actionType, actionData)
:设置文档打开时自动执行的动作。PDFDoc.getOpenAction()
:获取文档打开动作。PDFDoc.removeOpenAction()
:移除文档打开动作。
# Action 的使用注意事项
仅部分注释类型支持动作,包括 screen、link、sound 和 widget。
仅部分注释类型支持附加动作,包括 screen 和 widget。
附加动作的触发事件类型需与对象类型匹配,否则无效(AnnotActionTriggerEvents (opens new window), DocActionTriggerEvents (opens new window), FieldActionTriggerEvents (opens new window), PageActionTriggerEvents (opens new window))。 PageActionTriggerEvents (opens new window):适用于页面)。
某些动作类型(如 GotoR、GoToE、Rendition)受 SDK 的支持情况限制,仅支持触发或仅支持通过接口设置。
# Action 与 Additional Action
# Action(动作)
Action 是 PDF 中的一种核心动作机制,最早在 PDF 1.1 版本中引入,并通过对象的 A 条目(Action entry)定义。其具备以下主要特点:
- 直接绑定:直接绑定在注释(Annotation)或书签(Bookmark)的字典中。
- 单一触发:通常在对象被 "激活" 时触发,例如点击链接注释或选择书签项。
- 链式执行:支持通过
Next
条目构建动作链,实现树状结构的复杂动作序列。 - 文档级支持:通过文档目录的
OpenAction
条目,可以指定文档打开时执行的动作。
# Additional Action(附加动作)
Additional Action 是 PDF 中的一种扩展动作机制,最早在 PDF 1.2 版本中引入,并通过对象的 AA 条目(Additional Action entry)定义。其具备以下主要特点:
- 事件驱动:基于特定的触发事件(Trigger Events),而非简单的 "激活"。
- 多事件支持:单个对象可为不同事件类型绑定不同的动作。
- 广泛的适用性:支持文档、页面、注释、表单域等多种对象类型。
- 精细化控制:支持细粒度的事件管理,例如鼠标进入/离开、获得/失去焦点等。
# 主要区别
特性 | Action(动作) | Additional Action(附加动作) |
---|---|---|
引入版本 | PDF 1.1 | PDF 1.2 |
绑定方式 | A 条目 | AA 条目 |
触发机制 | 对象激活(如点击) | 特定事件驱动 |
事件类型 | 单一(激活) | 多种(进入、离开、按下、释放等) |
适用对象 | 注释、书签、文档 | 文档、页面、注释、表单域 |
复杂度 | 相对简单 | 更加灵活和复杂 |
典型用途 | 页面跳转、链接点击 | 表单验证、动态交互、状态变更 |
# 触发事件体系
Additional Action 的强大之处在于其丰富的触发事件体系。根据 Foxit PDF SDK for Web 的 ActionTriggerEvents
定义,触发事件主要分为以下四大类。
# 文档级事件(DocActionTriggerEvents)
- DOC_WILL_CLOSE:文档关闭前触发 JavaScript 动作。
- DOC_WILL_SAVE:文档保存前触发 JavaScript 动作。
- DOC_SAVED:文档保存后触发 JavaScript 动作。
- DOC_WILL_PRINT:文档打印前触发 JavaScript 动作。
- DOC_PRINTED:文档打印后触发 JavaScript 动作。
# 页面级事件(PageActionTriggerEvents)
- PAGE_OPENED:页面打开时触发动作。
- PAGE_CLOSED:页面关闭时触发动作。
# 注释/表单域级事件(AnnotActionTriggerEvents)
- ANNOT_CURSOR_ENTER:光标进入注释活动区域时触发动作。
- ANNOT_CURSOR_EXIT:光标离开注释活动区域时触发动作。
- ANNOT_MOUSE_BUTTON_PRESSED:鼠标按钮在注释活动区域内按下时触发动作。
- ANNOT_MOUSE_BUTTON_RELEASED:鼠标按钮在注释活动区域内释放时触发动作。
- ANNOT_RECEIVE_INPUT_FOCUS:注释(仅限 Widget 注释)获得输入焦点时触发动作。
- ANNOT_LOSE_INPUT_FOCUS:注释(仅限 Widget 注释)失去输入焦点时触发动作。
- ANNOT_PAGE_OPENED:包含注释的页面打开时触发动作(在
PAGE_OPENED
和文档打开动作之后执行)。 - ANNOT_PAGE_CLOSED:包含注释的页面关闭时触发动作(在
PAGE_CLOSED
之后执行)。 - ANNOT_PAGE_VISIBLE:包含注释的页面在查看器 UI 中变为可见时触发动作。
- ANNOT_PAGE_INVISIBLE:包含注释的页面在查看器 UI 中变为不可见时触发动作。
# 表单字段级事件(FieldActionTriggerEvents)
FIELD_KEY_STROKE:当用户在文本字段或组合框中键入,或修改滚动列表框选择时触发 JavaScript 动作。可用于验证或修改击键。
FIELD_WILL_FORMAT:字段值被格式化显示之前,会触发 JavaScript 动作。可用于对字段值进行修改。
FIELD_VALUE_CHANGED:字段值发生变更时触发 JavaScript 动作。可用于验证新值。
FIELD_RECALCULATE_VALUE:当其他字段值发生变更时触发 JavaScript 动作,以重新计算当前字段值。计算顺序可通过
PDFForm.getFieldsInCalculationOrder
函数确定。
# 实际应用场景
# Action 的典型应用
// 设置链接注释的跳转动作
linkAnnot.setAction({
type: "GoTo",
dest: { page: 5, view: "FitH" },
});
// 设置文档打开动作
pdfDoc.setOpenAction(PDF.actions.ActionType.javaScript, {
script: 'app.alert("欢迎使用本文档!");',
});
# Additional Action 的典型应用
// 表单域值变更时的验证
const additionalAction = formField.getAdditionalAction();
additionalAction.setAction(PDF.actions.ActionTriggerEvents.FIELD_VALUE_CHANGED, {
type: PDF.actions.ActionType.javaScript,
data: {
javascript: 'if (event.value < 0) { app.alert("值不能为负数"); event.rc = false; }'
},
});
// 页面打开时的初始化动作
const pageAdditionalAction = pdfPage.getAdditionalAction();
pageAdditionalAction.setAction(PDF.actions.ActionTriggerEvents.PAGE_OPENED, {
type: PDF.actions.ActionType.javaScript,
data: {
javascript: 'console.log("页面已打开");',
}
});
// 光标进入注释活动区域时触发的动作。
const annotAdditionalAction = annotation.getAdditionalAction();
annotAdditionalAction.setAction(PDF.actions.ActionTriggerEvents.ANNOT_CURSOR_ENTER, {
type: PDF.actions.ActionType.javaScript,
data: {
javascript: "this.highlight = true;",
}
});
// 文档保存前的数据验证
const docAdditionalAction = pdfDoc.getAdditionalAction();
docAdditionalAction.setAction(PDF.actions.ActionTriggerEvents.DOC_WILL_SAVE, {
type: PDF.actions.ActionType.javaScript,
data: {
javascript: 'if (!validateFormData()) { event.rc = false; app.alert("请完善必填信息"); }',
}
});