使用OfficeExtension.TrackedObjects跨Word.run上下文操作Range求助
Word加载项:跨上下文选中搜索结果实现方案
问题描述
需要实现Word任务窗格展示搜索结果,点击列表项时选中文档内对应的搜索结果(JavaScript)。尝试使用OfficeExtension.TrackedObjects类跨Word.run上下文访问Range对象,但运行代码时出现ReferenceError: Can't find variable: results错误。
用户原代码:
var items = []; function basicSearch() { Word.run(function (context) { const results = context.document.body.search("Online"); results.load("length, text, items"); return context.sync().then(function () { context.trackedObjects.add(results); for (let i = 0; i < results.items.length; i++) { let x = results.items[i].text; createtable("TestList", i, x, x); items.push(results.items[i]); } }); return context.sync(); }); } function createtable(id, x, y, z) { var table = document.getElementById(id); var row = table.insertRow(-1); var cell1 = row.insertCell(0); var cell2 = row.insertCell(1); var cell3 = row.insertCell(2); cell1.type = "button"; cell1.onclick = function () { selectrange(x) }; cell2.type = "button"; cell2.onclick = function () { selectrange(x) }; cell3.type = "button"; cell3.onclick = function () { selectrange(x) }; cell1.innerHTML = x; cell2.innerHTML = y; cell3.innerHTML = z; } function selectrange(x) { results.load("text"); results.items[x].select(); results.context.sync(); }
代码问题分析
- 变量作用域错误:
results是Word.run回调内部的局部变量,外部的selectrange函数无法访问,导致ReferenceError。 - TrackedObjects使用不当:
- 跟踪时机错误:应该在加载对象前就添加到跟踪集合,而非
sync之后。 - 跟踪对象错误:仅跟踪
results集合无法确保其内部的items(Range对象)被跨上下文保留,需要逐个跟踪单个Range对象。
- 跟踪时机错误:应该在加载对象前就添加到跟踪集合,而非
- 跨上下文操作逻辑错误:
selectrange未在新的Word.run上下文中执行操作,直接访问未跟踪的对象会失效。 - 存储未跟踪对象:
items数组存储的是未被跟踪的Range对象,跨上下文访问时会丢失与Office文档的关联。
完整可运行示例
<!-- 任务窗格HTML部分 --> <table id="TestList"> <tr> <th>索引</th> <th>文本</th> <th>操作</th> </tr> </table> <script> // 全局变量存储被跟踪的Range对象数组 var trackedRanges = []; function basicSearch() { Word.run(function (context) { // 执行搜索 const results = context.document.body.search("Online"); results.load("items"); return context.sync().then(function () { // 逐个跟踪每个搜索结果的Range对象 for (let i = 0; i < results.items.length; i++) { const range = results.items[i]; // 加载需要的属性(比如text) range.load("text"); // 添加到跟踪集合,确保跨上下文有效 context.trackedObjects.add(range); // 存储到全局数组 trackedRanges.push(range); // 生成列表项 createTableItem("TestList", i, range.text); } }); }) .catch(function (error) { console.log(error); if (error instanceof OfficeExtension.Error) { console.log("Debug info: " + JSON.stringify(error.debugInfo)); } }); } function createTableItem(tableId, index, text) { const table = document.getElementById(tableId); const row = table.insertRow(-1); const indexCell = row.insertCell(0); const textCell = row.insertCell(1); const actionCell = row.insertCell(2); indexCell.textContent = index; textCell.textContent = text; // 创建按钮并绑定点击事件 const selectBtn = document.createElement("button"); selectBtn.textContent = "选中"; selectBtn.onclick = function() { selectRange(index); }; actionCell.appendChild(selectBtn); } function selectRange(index) { // 在新的Word.run上下文中操作跟踪的Range对象 Word.run(function (context) { // 获取全局数组中被跟踪的Range const targetRange = trackedRanges[index]; // 执行选中操作 targetRange.select(); return context.sync(); }) .catch(function (error) { console.log(error); if (error instanceof OfficeExtension.Error) { console.log("Debug info: " + JSON.stringify(error.debugInfo)); } }); } // 可选:当不再需要跟踪对象时,清理跟踪集合 function cleanupTrackedObjects() { Word.run(function (context) { trackedRanges.forEach(range => { context.trackedObjects.remove(range); }); trackedRanges = []; return context.sync(); }); } </script>
关键说明
- TrackedObjects核心作用:将Office.js对象(如Range)与上下文解绑,允许在多个
Word.run调用中保持对象有效性,避免"对象已失效"错误。 - 逐个跟踪单个对象:集合对象(如SearchResults)的跟踪不会自动应用到其内部元素,必须单独跟踪每个需要跨上下文使用的Range对象。
- 全局存储跟踪对象:通过全局数组保存被跟踪的Range,确保点击事件触发时能访问到有效对象。
- 错误处理:所有
Word.run调用都应添加catch块,便于调试Office.js相关错误。 - 资源清理:当不再需要使用跟踪对象时,调用
context.trackedObjects.remove清理,避免内存泄漏。
内容的提问来源于stack exchange,提问作者FelixKing
相关产品推荐
相关产品推荐

