我需要在文本中突出显示一些逗号。为此,我首先获取所有逗号的索引:
for (let i = 0; i < text.length; i++) {
if (text[i] == ',')
commaIndexes.push(i);
}
在好吧,我想这里缺少一些逗号了,对吧?,这些索引分别是4和42。
然后将这段文本包装在我从diff算法获得的跨度中:
<span>Well</span>
<span>,</span>
<span> I guess there's a few commas missing</span>
<span>,</span>
<span> right?</span>
我想使用Rangy通过索引选择逗号:
// Create a Rangy range at the index that should contain a comma
let range = rangy.createRange();
// I'd expect the range to include the comma and only the comma.
range.selectCharacters(fragment, index, index + 1);
这仅适用于文本中的第一个逗号。将文本换成跨度似乎可以改变索引,我可以弄清楚一个系统:对于每个逗号,我需要在每个其他逗号的索引中加上2:
for (let i = 0; i < text.length; i++) {
if (text[i] == ',')
commaIndexes.push(i + 2 * commaIndexes.length);
}
我的代码现在可以正常工作,但是我想了解发生了什么。据我了解,Rangy的range.selectCharacters
方法应根据可见文本的索引选择字符,而文本是否用跨距包裹也没关系。
编辑:我的第二个代码示例中有换行符。我从Chrome的开发人员工具复制了此内容。换行符可能会引起我的问题,但是,我不确定是DOM的一部分还是仅显示在开发工具中。这是我要做的所有将文本换成跨距的操作:
// Create new span to host the segment
let span = document.createElement('span');
// Set text and append span
span.innerText = 'some text';
fragment.appendChild(span);
第二次修改:代码段
rangy.init();
// A sample text. Commas should be at (zero-based) indexes 4 and 42.
let text = "Well, I guess there's a few commas missing, right?";
// Store zero-based comma indexes
let commaIndexes = [];
for (let i = 0; i < text.length; i++) {
if (text[i] == ',')
commaIndexes.push(i);
}
// Simulate diff output
let substrings = [
'Well',
',',
" I guess there's a few commas missing",
',',
' right?'
];
// Create a DOM fragment to hold all spans created in the next step
let fragment = document.createDocumentFragment();
// Create new span for each substring
substrings.forEach(substring => {
let span = document.createElement('span');
// Set text and append span
span.innerText = substring;
fragment.appendChild(span);
});
commaIndexes.forEach(index => {
// Create a Rangy range
let range = rangy.createRange();
// I guess selectCharacters is one-based, left index including, right index excluding?
range.selectCharacters(fragment, index + 1, index + 2);
// I get the first comma and the 'g' preceding the second one
console.log(range.text());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/rangy/1.3.0/rangy-core.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/rangy/1.3.0/rangy-selectionsaverestore.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/rangy/1.3.0/rangy-textrange.js"></script>