Skip to content

自定义 UI

自定义导航栏

Web 平台的自定义 UI,很重要的一个部分是对导航栏的自定义。对导航栏进行自定义,您可能会用到几个操作,比如:

  • 添加自定义保存按钮。
  • 删除导航栏现有工具。
  • 重新排序功能区。
  • 隐藏表单功能区的文本域工具,并将其放至导航栏右侧。

ComPDFKit for Web 的 WebViewer UI 提供了灵活的 API 来轻松自定义导航栏。

要了解导航栏的结构和不同类型的工具项,您可以阅读本章节的导航栏组成导航栏工具项部分。您也可以直接跳到例子部分,查看自定义导航栏的示例。

导航栏组成

导航栏主要分成三个部分:导航工具、功能区和对应功能的二级菜单栏(包含子工具栏)。

  • 导航工具: 下图(导航栏)左右两侧的图标按钮属于导航工具。

    How Digital Signatures Work

  • 功能区: 在导航栏中间、框内的部分,称为功能区(如下图所示)。每个功能都有不同的二级菜单栏。不论是功能区还是二级菜单栏的按钮,都是可以单独修改的。

  • 二级菜单栏: 在不同的功能区下有其对应的二级菜单栏,二级菜单栏中会显示对应功能的一组工具。ComPDFKit for Web 提供多种 API 来自定义该二级菜单栏的工具。下面展示的是注释和表单功能的二级菜单栏:

    数字签名的工作原理和验证原理

切换功能区

可调用setActiceToolMode,来切换功能区中的功能模式。

javascript
ComPDFKitViewer.init(...)
  .then(instance => {
    const { UI } = instance;
    UI.setActiceToolMode('toolMenu-Annotation');
  });

隐藏/显示导航栏元素

查找导航栏数据元素属性值

要隐藏/显示导航栏元素,首先必须从 DOM 检查器中找到元素的data-element属性。

例如:

我们可以发现它的data-element值为themeMode。现在我们可以使用该值来隐藏/显示它。

下图是功能区的data-element属性:

How Digital Signatures Work

隐藏/显示导航栏元素

  • 隐藏/显示功能区的注释功能按钮:
javascript
// 隐藏功能区的注释功能按钮。
UI.disableElements('toolMenu-Annotation');
// 显示功能区的注释功能按钮。
UI.enableElements('toolMenu-Annotation');
  • 隐藏/显示多个导航栏元素:
javascript
// 隐藏左侧面板按钮和右侧面板按钮。
UI.disableElements(['leftPanelButton', 'rightPanelButton']);
// 显示左侧面板按钮和右侧面板按钮。
UI.enableElements(['leftPanelButton', 'rightPanelButton']);

导航栏工具属性与类型

导航栏工具项是具有某些属性的对象。我们可以通过调用setHeaderItems来添加、删除、移动导航栏的按钮。如果您希望在导航栏添加自定义工具,了解您需要添加的自定义工具是什么类型以及应使用哪些属性非常重要。下面将介绍导航栏工具项的属性和类型。

1. 设置 Header

setHeaderItems回调函数的参数:header对象,可以调用getgetItemsshiftunshiftpushpopdeleteupdate来对导航工具和功能区进行对应的操作。

javascript
UI.setHeaderItems(function(header) {
  // 获取所有功能区。
  const items = header.getHeader('tools').getItems();
  console.log(items);
});

2. 动作按钮

动作按钮可以触发一个操作。该按钮没有跃状态。其属性包含:

  • name(字符串) - 必须设置为customButton
  • type(字符串) - 必须设置为actionButton
  • img(字符串) - 图像或 base64 数据的路径。
  • onClick(函数) - 单击时触发的函数。
  • title (字符串,可选) - 按钮的工具提示。
  • dataElement(字符串,可选) - 设置data-element按钮元素值的选项。它可用于显示/隐藏该元素。
  • dropItem(布尔值,可选)- 设置是否为下拉框的选项。
  • text(字符串,可选)- 当dropItem为 true 时有效。设置下拉框选项展示的文本。
javascript
const newActionButton = {
  name: 'customButton',
  type: 'actionButton',
  img: 'path/to/image',
  onClick: () => {
    alert('Hello world!');
  },
  dataElement: 'alertButton'
};

3. 状态按钮

状态按钮是一个可自定义的按钮。您可以决定它有多少个状态、什么状态是活跃的以及何时更新状态。其属性包含:

  • name(字符串) - 必须设置为customButton
  • type(字符串) - 必须设置为statefulButton
  • initialState(字符串) - 作为states对象的键之一的字符串。
  • states(对象) - 为此形式的对象:{ nameOfState1: state1, nameOfState2: state2, ... }。states 的属性包括:
    • img (字符串,可选):图像或 base64 数据的路径。
    • getContent(函数,可选):更新状态时调用的函数。如果您不使用此按钮的 img 属性,请定义此属性。getContent 参数有activeStateactiveStatestates 中对应的 initialState 值的对象。
    • onClick(函数):点击时触发的函数。onClick 参数有activeStateactiveStatestates 中对应的 initialState 值的对象
    • 您需要的任何其他属性。
  • mount(函数) - 按钮挂载到 DOM 后调用的函数。
  • unmount(函数, 可选) - 在按钮从 DOM 卸载之前调用的函数。
  • title (字符串,可选) - 按钮的悬浮文案提示。
  • dataElement(字符串,可选) - 它可用于显示/隐藏该data-element的功能按钮。
  • dropItem(布尔值,可选)- 设置是否为下拉框的选项。
  • text(字符串,可选)- 当dropItem为 true 时有效。设置下拉框选项展示的文本。

示例:

显示计数的状态按钮。当你点击它时,它会将计数器加 1。

javascript
const countButton = {
  name: 'customButton',
  type: 'statefulButton',
  initialState: 'Count',
  states: {
    Count: {
      number: 1,
      getContent: activeState => {
        return activeState.number;
      },
      onClick: activeState => {
        activeState.number += 1;
      }
    }
  },
  dataElement: 'countButton'
};

显示当前页码的状态按钮。当您单击它时,文档将转到下一页。如果您已经翻到最后一页,文档将转到第一页。

javascript
const nextPageButton = {
  name: 'customButton',
  type: 'statefulButton',
  initialState: 'Page',
  states: {
    Page: {
      getContent: Core.getCurrentPage,
      onClick: activeState => {
        const currentPage = Core.getCurrentPage();
        const totalPages = Core.getPagesCount();
        const atLastPage = currentPage === totalPages;

        if (atLastPage) {
          Core.previousPage();
        } else {
          Core.nextPage();
        }
        activeState.getContent = Core.getCurrentPage();
      }
    }
  },
  mount: () => {
    // 挂载后执行。
    console.log('Mounted.');
  },
  unmount: () => {
    // 销毁前执行。
    console.log('Destroyed.');
  },
  dataElement: 'nextPageButton'
};

4. 切换元素按钮

切换元素按钮可用来打开/关闭指定的 UI 元素。当 UI 元素打开时,该按钮处于活跃状态。

其属性包含:

  • name(字符串) - 必须设置为customButton

  • type(字符串) - 必须设置为toggleButton

  • img(字符串) - 图像或 base64 数据的路径。

  • element(字符串) - data-element要打开/关闭的 UI 元素的属性值。

  • title (字符串,可选) - 按钮的悬浮文案提示。

  • dataElement(字符串,可选) - 设置data-element按钮元素值的选项。它可用于显示/隐藏该元素。

javascript
const newToggleButton = {
  name: 'customButton',
  type: 'toggleButton',
  img: `path/to/image`,
  element: 'pageModePanel',
  dataElement: 'pageModePanelButton'
};

5. 工具按钮

工具按钮是功能模块下的二级菜单栏中的工具。例如,在 Form 功能模式下,自定义一个工具按钮,并指定该工具按钮的元素值为textfield时,即可创建一个文本框的功能按钮。可将您需要自定义的的工具按钮放置在任意位置。当工具被激活时,该按钮处于活跃状态。

属性:

  • name(字符串) - 必须设置为customButton

  • type(字符串) - 必须设置为toolButton

  • toolName(字符串) - 目标工具的data-element按钮元素值。

javascript
const newToolButton = {
  name: 'customButton',
  type: 'toolButton',
  toolName: 'textfield'
};

6. 间隔器

间隔器只是一个具有flex: 1 CSS 属性的div,用来占据任何剩余空间的工具。它用于将按钮推到默认标题的每一侧。

间隔器属性包括:

  • type(字符串) - 必须设置为spacer
javascript
const newSpacer = {
  type: 'spacer'
};

7. 分隔线

分隔线呈现一个带有一定边距的垂直条来分隔项目组。

分隔线属性包括:

  • type(字符串) - 必须设置为divider
javascript
const newDivider = {
  type: 'divider'
};

自定义 UI 示例

添加自定义保存按钮:

javascript
UI.setHeaderItems(function(header) {
  const mySavaButton = {
    name: 'customButton',
    type: 'actionButton',
    dataElement: 'mySaveButton',
    img: `<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
            <path d="M13 1L1 13" stroke="#BABABA" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
            <path d="M1 1L13 13" stroke="#BABABA" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
          </svg>`,
    onClick: function() {
      Core.download();
    }
  }
  header.push(myCustomButton);
});

隐藏表单功能区的文本域工具,并将其放至导航栏右侧:

javascript
UI.setHeaderItems(header => {
  header.headers.toolItems.form.splice(0, 1);

  const myTextFieldButtom = {
    name: 'customButton',
    type: 'toolButton',
    toolName: 'textfield'
  }
  header.getHeader('rightHeaders').unshift(myTextFieldButtom);
});

重新排序功能区:

javascript
UI.setHeaderItems(header => {
  // 翻转功能区的顺序。
  header.headers.tools.reverse();
  // 按照功能区名称字母顺序进行排序。
  header.headers.tools.sort((a, b) => a.element.localeCompare(b.element));
});

删除导航栏现有工具:

javascript
UI.setHeaderItems(header => {
  // 删除导航栏左侧工具。
  header.getHeader('headers');
  header.update([]);
  // 删除功能区。
  header.getHeader('tools').update([]);
});