在Firefox中慢慢突出显示

时间:2012-09-20 03:11:18

标签: javascript html firefox range highlighting

我们需要在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页面中的某些部分是可编辑的。

2 个答案:

答案 0 :(得分: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, '');
}

答案 1 :(得分:0)

没有必要使用document.execCommand()。只需使用范围方法,然后就不需要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/