我尝试制作插件,将段落分成句子然后说出来,句子在阅读时会突出显示。在大多数情况下,我有这个工作,但当我想突出显示当前正在阅读的句子时问题就出现了。
我有一个函数,根据用户光标所在的位置将段落分成句子:
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) {
...
我希望突出显示“原始范围”上的文字。对象,以便突出显示正确的句子,如下所示:
function highlightSentence(id, colour) {
Word.run(function (context) {
var paragraphs = originalRange.paragraphs;
context.load(paragraphs, 'text');
context.load(originalRange, 'text');
...
但是这会产生一个错误,因为原始范围是'正在多个上下文中使用。有没有办法让我使用原始范围'在多个上下文或其他解决方案?
更新:
我尝试使用' context.trackedObjects.add'在函数内再次获得段落的句子。对于原始范围。在尝试获取“'段落”时,这会导致同样的错误。它的财产。
我意识到我可能需要的只是段落的句子,而不是使用原始范围来再次获得句子。相反,我实施了一个不同的解决方案:
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);
});
}
但是,我现在收到以下错误: "对象路径' _reference()'并不是为了你正在努力做的事情而努力。如果您在多个\" context.sync \"中使用该对象调用和外部顺序执行\" .run \"批处理,请使用\" context.trackedObjects.add()\"和\" context.trackedObjects.remove()\"管理对象生命周期的方法。"
更新:
我设法解决了上述问题。但是,现在,在突出显示功能期间,由于' gSentences'变量尚未在上下文中加载,其属性如' font'不可用,所以我无法更改突出显示颜色。如果我尝试在上下文中加载它,则原始错误“'”不能跨上下文使用对象'出现。我现在不知道该怎么做。
更新:
这是我用来检索段落中相同位置或光标之后的句子。将这些句子推送到要说出的数组中。我发现我不得不用回调来搞乱这件事。
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);
});
}
我希望在说出句子时突出显示句子,这就是下一个函数的用途(在音频元素的第一个事件监听器上调用)
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);
});
}
答案 0 :(得分:4)
非常好的问题!这听起来很像我在这里回答的问题:How can a range be used across different Word.run contexts?
如果这没有用,请发表评论,说明您的方案有何不同之处,我可以尝试提供帮助。
~Michael Zlatkovsky,Office Extensibility团队的开发人员,MSFT
P.S。:请用 office-js 标记您的问题,以确保我们(产品组和社区)看到它们。
根据更新的问题/代码进行更新:
说实话,有些不清楚你的回调是做什么的......但是,让我给你一些一般指导,看看是否有帮助:
对于在Word.run(function(ctx) { ... })
期间创建的任何对象,只要Word.run
执行完毕,该对象就会变为无效。我并不是说它在JS垃圾收集意义上,而是在“将不再受限于文档”的意义上。因此,即使您在Word.run
内创建了一个试图捕获范围的回调函数,这本身也不起作用。
如果您希望在执行之间保留对象(或者更确切地说,让它超出Excel.run
),则必须将其添加到ctx.trackedObjects
。您需要在.run
内执行此操作,否则为时已晚。
要在此后使用该对象,您不能再使用Word.run
,而是直接使用上下文。
savedObject.doSomething(); //或savedObject.load(“someProperty”); savedObject.context.sync() .then(...)//可选 .catch(...);
顺便说一下:我们正在积极努力使这种模式更容易,敬请关注......
目前,您需要使用How can a range be used across different Word.run contexts?中描述的TrackedObjects变通方法(额外代码),尽管我们应该很快使用此修复程序更新Office.js。
这有助于您解锁吗?
〜迈克尔