用 JavaScript 给当前页面增加运行逻辑:Page Script 顶层变量、常量、类和函数可供本页动画与表达式引用;运行时用 ReadTag 系列读取 Tag,用 hqVisuDesigner 操作组件和跳转页面,hqVisuDesignerPageReady 在页面就绪时执行初始化。读单个位使用 "标签名[位号]" 方括号写法。
功能说明
脚本用于给当前页面增加运行逻辑,全部使用 JavaScript。插件不提供跨整个 PPT 的 Global Script / 全局脚本文档;功能区 Scripts 分组只有当前页 Page Script 入口,alarm.js 也是当前页固定的受保护文档。Page Script 顶层声明可供同一页行为引用,但不会自动出现在其他页面。ReadTag 系列读取 Tag,hqVisuDesigner 用于修改组件文本、颜色、显隐、布局和页面跳转。WriteTag 系列只允许在真实用户点击动作中调用,不能放在 Page Script、Definition 或 Hover Script。行为里的 Definition / Condition / Value / Text 与页面脚本使用同一套现代 ECMAScript 2022 语法边界;表达式位只返回一个同步结果。
Script Workspace 从新建到保存
点击功能区 Scripts → Page Script。左侧 Scripts 树管理当前页的脚本文档,右侧编辑当前选中文档。先从树中选文档;需要新增时点 New,填写 Folder 和 Name;在 Code 中写 JavaScript;需要暂时不导出时取消 Enabled;最后点击 Save。Save 会一次校验并保存当前页全部启用文档。
- Scope:先确认正在编辑的是当前目标页面。
- New 或 Ctrl+N:创建新脚本文档。
- Folder:可选,用斜杠分隔文件夹路径。
- Name:脚本文档名,不填写 .js 扩展名。
- Enabled:取消后文档保留,但不导出也不参与 Save 校验。
- Script Library 或 Ctrl+J:在当前光标处插入方法或模板。
- Save 或 Ctrl+S:校验并保存整个脚本工作区。
- Help 或 F1:查看脚本帮助。
删除文档和 alarm.js 的区别
在左侧树选择自建脚本文档后点击 Delete,并按确认提示删除。alarm.js 是当前页受保护文档,不能删除;需要停用页面报警显示时,应编辑 alarm.js 中的页面报警配置,而不是尝试删除文件。
- 删除前确认其他脚本和行为没有引用该文档里的函数或变量。
- Delete 只对可删除的自建文档生效。
- alarm.js 不可删除,应修改其配置内容。
- 误删或不想保存当前改动时点击 Cancel,不要点击 Save。
使用方法:常用方法和写法
按位置选择入口,再使用下面几类运行时方法。生命周期:在页面脚本里挂载 window.hqVisuDesignerPageReady;页面运行时就绪后调用一次。
- 读标签 ReadTag 系列:ReadTagBoolean / ReadTagInteger / ReadTagDouble / ReadTagString,第二个参数是读不到时的回退值
- 日期时间:GetCurrentDate() 返回 yyyy-MM-dd,GetCurrentDateTime() 返回 yyyy-MM-dd HH:mm:ss,FormatDateTime(value, "yyyy/MM/dd HH:mm:ss") 可把时间值格式化成指定显示格式;搜索关键字包括时间、日期、time、date、datetime
- 读单个位(重点):在完整标签名后面加方括号位号,例如 "PLC_LINE01.PUMP01.STATUS[3]",用 ReadTagBoolean 读;位号 0 起算、范围 0-31、方括号里不能有空格
- 标签质量:ReadTagQuality(name, "bad") 取质量文本,ReadTagQualityGood(name) 直接判断是否为 good(质量只有 good / bad,不是工艺值)
- 写标签 WriteTag 系列:仅在真实用户点击脚本中使用;最终是否写成由宿主机决定,可能有权限、确认、原因、异步
- 操作组件 hqVisuDesigner:setComponentText(名或ID, 值)、setComponentFill、setComponentBorder、setComponentVisible、setComponentLayout、findComponent
- 跳转 hqVisuDesigner:openPage("页名") 同包跳页、openWebsite(url, 是否新窗口) 开外链
// 页面脚本:页面就绪时初始化
window.hqVisuDesignerPageReady = function (ctx) {
// 读一个整数标签里的第 0 位(方括号写法,无空格)
const pumpRun = ReadTagBoolean("PLC1.PUMP.STATUS[0]", false);
hqVisuDesigner.setComponentText("Title 1", pumpRun ? "运行" : "停止");
hqVisuDesigner.setComponentFill("Lamp 1", pumpRun ? "#22C55E" : "#EF4444");
hqVisuDesigner.refreshView();
};
常用 JS 写法:日期时间、状态文本和安全默认值
这些片段适合放在 Page Script、Click Script 或行为的 Definition 区域里。Condition / Value / Text 位置通常只放最后一句能立即返回的表达式;较长的判断、格式化和变量准备放在 Definition 或脚本体里。
- 三元表达式:condition ? trueValue : falseValue,适合把布尔值转成文本、颜色或数值。
- 安全默认值:ReadTagBoolean / ReadTagDouble 等第二个参数是回退值,读不到时不让脚本报错。
- 日期时间文本:当前日期用 GetCurrentDate(),当前日期时间用 GetCurrentDateTime(),已有时间值用 FormatDateTime(...) 改显示格式。
- 多条件判断:简单场景用三元表达式,复杂场景用 if / else 先算出变量,再写到组件或返回给行为。
// 日期 / 时间 / time / date
const today = GetCurrentDate(); // yyyy-MM-dd
const nowText = GetCurrentDateTime(); // yyyy-MM-dd HH:mm:ss
const displayTime = FormatDateTime(nowText, "yyyy/MM/dd HH:mm:ss");
// 布尔状态转文本(三元表达式)
const currentValue = ReadTagBoolean("A1.Tset.1", false);
let text = currentValue ? "OK" : "异常";
// 数值分段
const speed = ReadTagDouble("Line01.MainMotor.SpeedPV", 0);
const levelText = speed >= 80 ? "高" : (speed >= 40 ? "中" : "低");
// 质量保护:质量不好时优先显示通讯异常
if (!ReadTagQualityGood("Line01.MainMotor.SpeedPV")) {
text = "通讯异常";
}
hqVisuDesigner.setComponentText("StatusText", `${text} / ${displayTime}`);
hqVisuDesigner.setComponentText("LevelText", levelText);
常用 JS 语法:字符串拼接、数字格式化、数组和对象
画面脚本里最常见的不是复杂算法,而是把 Tag 值整理成现场人员看得懂的文字。字符串拼接、模板字符串、数字格式化、数组查找和对象配置都可以放在 Definition 或 Page Script 中,最后再把结果写到组件或返回给行为。
- 字符串拼接:简单场景用 '速度: ' + speed,多变量推荐模板字符串
速度: ${speed}。
- 数字格式化:用 Number(value).toFixed(1) 控制小数位,避免显示太长。
- 数组:用数组维护状态映射、报警列表或多个组件名,再用循环统一处理。
- 对象:用对象保存配置表,例如状态码到文本、颜色和优先级的映射。
// 字符串拼接和模板字符串
const speed = ReadTagDouble('Line01.MainMotor.SpeedPV', 0);
const unit = ' rpm';
const speedText = `速度: ${Number(speed).toFixed(1)}${unit}`;
const timeText = `更新时间: ${GetCurrentDateTime()}`;
// 对象映射:状态码转文本和颜色
const state = ReadTagInteger('Line01.MainMotor.State', 0);
const stateMap = {
0: { text: '停止', color: '#94A3B8' },
1: { text: '运行', color: '#22C55E' },
2: { text: '故障', color: '#EF4444' }
};
const stateInfo = stateMap[state] ?? { text: '未知', color: '#F59E0B' };
// 数组和循环:批量更新多个组件
const targetNames = ['SpeedText', 'SpeedTextCopy'];
targetNames.forEach((name) => hqVisuDesigner.setComponentText(name, speedText));
hqVisuDesigner.setComponentText('StateText', `${stateInfo.text} / ${timeText}`);
hqVisuDesigner.setComponentFill('StateLamp', stateInfo.color);
适用场景
两种典型场景。一是同一页的多个动画或表达式共用换算函数、常量与 Tag 前缀:把它们放进该页 Page Script 顶层。二是某一页的初始化或联动逻辑:在 hqVisuDesignerPageReady 里拼好文本、设置组件初始颜色或显隐。确实需要跨页高级复用时,交给宿主 runtime、自写 SDK 或模板。需要按钮或状态灯跟一个布尔位走时,用方括号位读把整数 Tag 的某一位当布尔量取出来驱动显示。
- 同页共享方法、常量和 Tag 前缀放当前页 Page Script
- 同包跳页用 hqVisuDesigner.openPage(...);跨画面包走宿主 SDK,不要写 ../../other-screen/index.html 这种磁盘相对路径
边界与易错点
常见注意事项:① 位读必须用精确的 "标签名[位号]" 方括号写法、方括号里不能有空格,位号只支持 0-31;位写使用父整数 Tag + BitIndex,不能把 Tag[3] 当普通写入 Tag。② 写 Tag 只允许在真实用户点击动作中执行,且不要假设调用后必然同步成功。③ 异步方法只能放在脚本体位置;await 只能写在 async 函数内部,不支持顶层 await。④ import/export 属于模块语法,动画表达式与页面脚本文档不支持;高级能力走自写 SDK。