logologo
开始
教程
手册
开发
插件
API
首页
English
简体中文
日本語
한국어
Español
Português
Deutsch
Français
Русский
开始
教程
手册
开发
插件
API
首页
logologo
RunJS 概述
导入模块
容器内渲染

全局变量

window
document
navigator

ctx

ctx.blockModel
ctx.collection
ctx.collectionField
ctx.dataSource
ctx.dataSourceManager
ctx.element
ctx.exit()
ctx.exitAll()
ctx.filterManager
ctx.form
ctx.getModel()
ctx.getValue()
ctx.getVar()
ctx.i18n
ctx.importAsync()
ctx.initResource()
ctx.libs
ctx.location
ctx.logger
ctx.makeResource()
ctx.message
ctx.modal
ctx.model
ctx.notification
ctx.off()
ctx.on()
ctx.openView()
ctx.render()
ctx.request()
ctx.requireAsync()
ctx.resource
ctx.route
ctx.router
ctx.setValue()
ctx.sql
ctx.t()
ctx.view
Previous Pagectx.dataSourceManager
Next Pagectx.exit()

#ctx.element

指向沙箱 DOM 容器的 ElementProxy 实例,作为 ctx.render() 的默认渲染目标。在 JSBlock、JSField、JSItem、JSColumn 等有渲染容器的场景下可用。

#适用场景

场景说明
JSBlock区块的 DOM 容器,渲染区块自定义内容
JSField / JSItem / FormJSFieldItem字段/表单项的渲染容器(通常为 <span>)
JSColumn表格单元格的 DOM 容器,渲染自定义列内容

注意:ctx.element 仅在存在渲染容器的 RunJS 上下文中可用;无 UI 上下文的场景(如纯后端逻辑)可能为 undefined,使用前建议做空值判断。

#类型定义

element: ElementProxy | undefined;

// ElementProxy 对原始 HTMLElement 的代理,对外暴露安全 API
class ElementProxy {
  __el: HTMLElement;  // 内部持有的原生 DOM 元素(仅个别场景需访问)
  innerHTML: string;  // 读写时经 DOMPurify 清洗
  outerHTML: string; // 同上
  appendChild(child: HTMLElement | string): void;
  // 其他 HTMLElement 方法透传(不推荐直接使用)
}

#安全要求

推荐:所有渲染通过 ctx.render() 完成。 不要直接使用 ctx.element 的 DOM API(如 innerHTML、appendChild、querySelector 等)。

#为何推荐 ctx.render()

优势说明
安全集中安全控制,避免 XSS 与不当 DOM 操作
React 支持完整支持 JSX、React 组件与生命周期
上下文继承自动继承应用 ConfigProvider、主题等
冲突处理自动管理 React 根创建/卸载,避免多实例冲突

#❌ 不推荐:直接操作 ctx.element

// ❌ 不推荐:直接使用 ctx.element 的 API
ctx.element.innerHTML = '<div>内容</div>';
ctx.element.appendChild(node);
ctx.element.querySelector('.class');

ctx.element.innerHTML 已废弃,请使用 ctx.render() 替代。

#✅ 推荐:使用 ctx.render()

// ✅ 渲染 React 组件
const { Button, Card } = ctx.libs.antd;
ctx.render(
  <Card title={ctx.t('欢迎')}>
    <Button type="primary">点击</Button>
  </Card>
);

// ✅ 渲染 HTML 字符串
ctx.render('<div style="padding:16px;">' + ctx.t('内容') + '</div>');

// ✅ 渲染 DOM 节点
const div = document.createElement('div');
div.textContent = ctx.t('你好');
ctx.render(div);

#特例:作为弹窗锚点

在需要以当前元素为锚点打开 Popover 时,可访问 ctx.element?.__el 获取原生 DOM 作为 target:

// ctx.viewer.popover 需要原生 DOM 作为 target
await ctx.viewer.popover({
  target: ctx.element?.__el,
  content: <div>弹出内容</div>,
});

仅在此类「将当前容器作为锚点」的场景下使用 __el;其他情况请勿直接操作 DOM。

#与 ctx.render 的关系

  • ctx.render(vnode) 若无传入 container,默认渲染到 ctx.element 容器内
  • 若同时无 ctx.element 且未传入 container,会抛出错误
  • 可显式指定容器:ctx.render(vnode, customContainer)

#注意事项

  • ctx.element 仅作为 ctx.render() 的内部容器使用,不建议直接访问或修改其属性/方法
  • 在无渲染容器的上下文中 ctx.element 为 undefined,调用 ctx.render() 前需确保容器可用或手动传入 container
  • ElementProxy 的 innerHTML/outerHTML 虽经 DOMPurify 清洗,仍推荐使用 ctx.render() 统一管理渲染

#相关

  • ctx.render:渲染内容到容器
  • ctx.view:当前视图控制器
  • ctx.modal:模态框快捷 API