2

我们需要为 html 页面中的一些关键字/句子添加锚点和高亮。事实证明,在 Firefox 中突出显示真的很慢。

在以下代码中,所有需要突出显示的范围都存储在数组中hiliteRanges

for (var i = 0; i < hiliteRanges.length; i++){
    document.designMode = "on";

    var selHilites = window.getSelection();

    if (selHilites.rangeCount > 0)
        selHilites.removeAllRanges();

    selHilites.addRange(hiliteRanges[i]);

    var anchorId = 'index'+i;
    var insertedHTML = '<span id="' + anchorId + '" style="background-color: #FF8C00;" >'+hiliteRanges[i].toString()+'</span>';

    document.execCommand('inserthtml', false, insertedHTML);                                                                                    
    document.designMode = "off";
}

有什么方法可以加快处理速度吗?我们可以在数组中有数百个范围hiliteRanges。我们曾经尝试将designMode设置移到循环之外,但是当循环运行时,我们可以看到 html 页面中的某些部分是可编辑的。

4

2 回答 2

2

这是我的默认突出显示片段,在每个浏览器中都可以正常工作。试试看。

演示:http: //jsbin.com/adeneh/1/edit

function highlight(text, words, tag) {

  // Default tag if no tag is provided
  tag = tag || 'span';

  var i, len = words.length, re;
  for (i = 0; i < len; i++) {
    // Global regex to highlight all matches
    re = new RegExp(words[i], 'g');
    if (re.test(text)) {
      text = text.replace(re, '<'+ tag +' class="highlight">$&</'+ tag +'>');
    }
  }

  return text;
}

// Usage:
var el = document.getElementById('element');
el.innerHTML = highlight(
  el.innerHTML, 
  ['word1', 'word2', 'phrase one', 'phrase two', ...]
);

并取消突出显示:

function unhighlight(text, tag) {
  // Default tag if no tag is provided
  tag = tag || 'span';
  var re = new RegExp('(<'+ tag +'.+?>|<\/'+ tag +'>)', 'g');
  return text.replace(re, '');
}
于 2012-09-20T03:19:21.523 回答
0

没有必要为此使用document.execCommand()。只需使用 range 方法,然后就不需要designMode.

var anchorId, hiliteTextNode, hiliteSpan;
for (var i = 0; i < hiliteRanges.length; i++){
    // Create the highlight element
    hiliteSpan = document.createElement("span");
    hiliteSpan.id = anchorId;
    hiliteSpan.style.backgroundColor = "#FF8C00";

    hiliteTextNode = document.createTextNode(hiliteRanges[i].toString());
    hiliteSpan.appendChild(hiliteTextNode);

    // Replace the range content
    hiliteRanges[i].deleteContents();
    hiliteRanges[i].insertNode(hiliteSpan);
}

此外,由于范围受 DOM 突变的影响,我建议您在收集范围的同时执行此部分window.find()。这是一个例子:

http://jsfiddle.net/YgFjT/

于 2012-09-20T08:50:56.840 回答