You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Office-js中点击内容控件或高亮文本触发函数的实现方法

实现Word文档反向交互功能(点击文本/内容控件联动加载项面板)

核心逻辑

要完成文档到加载项面板的反向联动,需分两步:监听文档内目标元素的选中/点击事件,再通过事件回调同步更新React面板的滚动与高亮状态。

具体实现步骤

1. 监听文档内的目标元素事件

针对Content Control的监听

利用Word JS API的ContentControlSelectionChanged事件绑定全局监听:

// 加载项初始化时注册事件
async function registerContentControlListeners() {
  await Word.run(async (context) => {
    context.document.contentControls.onSelectionChanged.add(onContentControlSelected);
    await context.sync();
  });
}

// 选中事件回调
async function onContentControlSelected(event: Word.ContentControlSelectionChangedEventArgs) {
  const contentControl = event.contentControl;
  await Word.run(async (context) => {
    contentControl.load('tag'); // 用tag存储与面板列表项对应的唯一标识
    await context.sync();
    
    // 给React组件发送通知
    window.postMessage({
      type: 'CONTENT_CONTROL_SELECTED',
      id: contentControl.tag
    }, '*');
  });
}

针对高亮文本的监听

高亮文本一般通过字体背景色标记,需监听文档SelectionChanged事件并判断选中区域是否为高亮文本:

// 注册选中事件监听
async function registerSelectionListeners() {
  await Word.run(async (context) => {
    context.document.onSelectionChanged.add(onDocumentSelectionChanged);
    await context.sync();
  });
}

// 文档选中变化回调
async function onDocumentSelectionChanged(event: Word.SelectionChangedEventArgs) {
  const selection = event.selection;
  await Word.run(async (context) => {
    selection.load('font/highlightColor');
    await context.sync();
    
    // 假设高亮色为黄色#FFFF00,判断选中区域是否为高亮文本
    if (selection.font.highlightColor === '#FFFF00') {
      // 读取高亮文本绑定的自定义属性(提前存储面板项标识)
      const customProps = selection.getRange().customProperties;
      customProps.load('items');
      await context.sync();
      
      const targetId = customProps.items.find(prop => prop.key === 'panelItemId')?.value;
      if (targetId) {
        window.postMessage({
          type: 'HIGHLIGHT_TEXT_SELECTED',
          id: targetId
        }, '*');
      }
    }
  });
}

2. React面板接收事件并更新状态

在React组件中监听message事件,收到通知后滚动到对应列表项并高亮:

import { useEffect, useRef } from 'react';

function PanelList({ items }) {
  const itemRefs = useRef<Record<string, HTMLDivElement | null>>({});

  useEffect(() => {
    const handleMessage = (event: MessageEvent) => {
      if (['CONTENT_CONTROL_SELECTED', 'HIGHLIGHT_TEXT_SELECTED'].includes(event.data.type)) {
        const targetId = event.data.id;
        const targetElement = itemRefs.current[targetId];
        
        if (targetElement) {
          // 平滑滚动到目标项
          targetElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
          // 添加高亮样式
          targetElement.classList.add('highlighted');
          // 3秒后自动移除高亮(可选)
          setTimeout(() => targetElement.classList.remove('highlighted'), 3000);
        }
      }
    };

    window.addEventListener('message', handleMessage);
    return () => window.removeEventListener('message', handleMessage);
  }, []);

  return (
    <div className="panel-list">
      {items.map(item => (
        <div
          key={item.id}
          ref={el => itemRefs.current[item.id] = el}
          className="list-item"
        >
          {item.title}
        </div>
      ))}
    </div>
  );
}

3. 关键注意事项

  • 标识同步:必须保证文档内的Content Control/高亮文本,与面板列表项有一一对应的唯一标识(如tag或自定义属性),这是联动的核心依据。
  • 上下文规范:所有Word API操作必须包裹在Word.run异步函数中,确保获取正确的文档上下文。
  • 事件清理:加载项卸载时要移除注册的事件监听器,避免内存泄漏:
async function unregisterListeners() {
  await Word.run(async (context) => {
    context.document.contentControls.onSelectionChanged.remove(onContentControlSelected);
    context.document.onSelectionChanged.remove(onDocumentSelectionChanged);
    await context.sync();
  });
}

内容的提问来源于stack exchange,提问作者Pooja M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 17:50:35