one*_*dan 2 javascript ms-office office365 office-js
我正在尝试制作一个插件,将一个段落分成句子然后说出,并在阅读时突出显示句子。在大多数情况下,我可以完成此操作,但当我想突出显示当前正在阅读的句子时,问题就出现了。
我有一个函数,可以根据用户光标的位置将段落分成句子:
function selectionTest() {
Word.run(function (context) {
originalRange = context.document.getSelection();
var paragraphs = originalRange.paragraphs;
context.load(paragraphs, 'text');
context.load(originalRange, 'text');
return context.sync().then(function () {
//Range should only be present in a single paragraph, rather than spanning multiple
if (paragraphs.items.length === 1) {
var paragraph = paragraphs.items[0];
var ranges = paragraph.getTextRanges(['.'], true);
context.load(ranges, 'text');
return context.sync(ranges);
}
}).then(function (sentences) {
...
Run Code Online (Sandbox Code Playgroud)
我想在“originalRange”对象上突出显示文本,以便突出显示正确的句子,如下所示:
function highlightSentence(id, colour) {
Word.run(function (context) {
var paragraphs = originalRange.paragraphs;
context.load(paragraphs, 'text');
context.load(originalRange, 'text');
...
Run Code Online (Sandbox Code Playgroud)
但这会产生错误,因为“originalRange”正在多个上下文中使用。有没有办法让我在多个上下文或其他解决方案中使用“originalRange”?
更新:
我尝试在函数中再次获取段落的句子,使用“context.trackedObjects.add”作为原始范围。当尝试从中获取“paragraphs”属性时,这会导致相同的错误。
我意识到我可能需要的只是段落中的句子,而不是使用原始范围再次获取句子。相反,我实施了不同的解决方案:
function highlightSentence(id, colour) {
Word.run(function (context) {
context.trackedObjects.add(gSentences);
return context.sync().then(function () {
gSentences.items[id].font.highlightColor = colour;
}).then(context.sync);
}).then(function(){
gSentences.context.trackedObjects.remove(gSentences);
gSentences.context.sync();
}).catch(function(error) {
console.log(error.message);
});
}
Run Code Online (Sandbox Code Playgroud)
但是,我现在收到以下错误: “对象路径 '_reference()' 不适用于您想要执行的操作。如果您在多个“context.sync”调用和外部使用该对象顺序执行“.run”批处理,请使用“context.trackedObjects.add()”和“context.trackedObjects.remove()”方法来管理对象的生命周期。
更新:
我设法解决了上面的问题。但是,现在,在突出显示功能期间,由于“gSentences”变量尚未在上下文中加载,因此其“字体”等属性不可用,因此我无法更改突出显示颜色。如果我尝试在上下文中加载它,则会出现“无法跨上下文使用对象”的原始错误。我不知道此时该怎么办。
更新:
这就是我用来检索段落中位于相同位置或光标之后的句子的方法。这些句子被推送到一个数组中以供说出。我发现我必须用回调来搞乱才能做到这一点。
function selectionTest() {
Word.run(function (context) {
var range = context.document.getSelection();
var paragraphs = range.paragraphs;
context.load(paragraphs, 'text');
return context.sync().then(function () {
if (paragraphs.items.length === 1) {
var paragraph = paragraphs.items[0];
gSentences = paragraph.getTextRanges(['.'], true);
context.load(gSentences);
return context.sync();
}
}).then(function () {
if (gSentences.items) {
var sentencesResult = '';
var callbacklist = [];
currentSentence = 0;
sentencesToSpeak = [];
function isSentenceinRange(idx, fn) {
var rangeLoc = gSentences.items[idx].compareLocationWith(range);
return context.sync().then(function () {
if (rangeLoc.value === Word.LocationRelation.contains || rangeLoc.value === Word.InsertLocation.after) {
return fn(gSentences.items[idx].text);
}
return fn('');
});
}
for (var i = 0; i < gSentences.items.length; i++) {
callbacklist.push(
(function (i) {
return function () {
isSentenceinRange(i, function (result) {
if (result) {
sentencesToSpeak.push({ id: i, text: result });
if (i === gSentences.items.length - 1) {
sentencesFinialised();
}
}
});
}
})(i)
);
}
for (var callback in callbacklist) {
callbacklist[callback].call(this);
}
}
});
}).catch(function (error) {
console.log(error.message);
});
}
Run Code Online (Sandbox Code Playgroud)
我想在说话时突出显示句子,这就是下一个函数将用来执行的操作(在音频元素的 onend 事件侦听器上调用)
function highlightSentenceTest(id, colour) {
Word.run(function (context) {
context.trackedObjects.add(gSentences);
//Causes error, but need to load to get access?
context.load(gSentences);
return context.sync().then(function () {
gSentences.items[id].font.highlightColor = colour;
}).then(context.sync)
}).catch(function(error) {
console.log(error.message);
});
}
Run Code Online (Sandbox Code Playgroud)
非常好的问题!这听起来很像我在这里回答的问题: How can a range be used across different Word.run contexts?
如果这没有帮助,请留下评论,说明您的情况有何不同,我可以尽力提供帮助。
~ Michael Zlatkovsky,MSFT Office 可扩展性团队开发人员
PS:请使用Office-js标记您的问题,以确保我们(产品组和社区)能够看到它们。
根据更新的问题/代码进行更新:
说实话,有些不清楚你的回调在做什么......但让我给你一些一般指导,看看是否有帮助:
对于在 a 期间创建的任何对象Word.run(function(ctx) { ... }),一旦Word.run执行完毕,该对象将变得无效。我的意思并不是 JS 垃圾收集意义上的,而是“将不再绑定到文档”的意义上。因此,即使您在Word.run尝试捕获范围内创建回调函数,它本身也不起作用。
当您确实希望在执行之间保留对象(或者更确切地说,让它存在于 之外Excel.run)时,您必须将其添加到ctx.trackedObjects. 您需要在 之内执行此操作.run,否则就太晚了。
此后要使用该对象,就不能再使用Word.run,而是直接使用上下文。
保存对象.doSomething(); // 或savedObject.load("someProperty"); saveObject.context.sync() .then(...) // 可选 .catch(...);
顺便说一句:我们正在积极努力使这种模式变得更容易,所以请继续关注......
目前,您需要使用如何在不同的 Word.run 上下文中使用范围?中描述的 TrackedObjects 解决方法(额外代码)。,不过我们应该很快就会通过修复来更新 Office.js。
这能帮助你解锁吗?
〜迈克尔
| 归档时间: |
|
| 查看次数: |
1929 次 |
| 最近记录: |