5

我正在寻找清除代码镜像文本的所有标记。标记已创建调用

ret = codemirror.markText(..);
histMarks.push(ret);

要删除所有标记,我们将单独清除每个标记:

foreach( histMarks, i.clear() );  // this is pseudocode

有没有更有效的方法来删除所有标记?

4

3 回答 3

10

如果您真的在寻找“clearAllMarks”类型的功能,有一种更有效的方法。您甚至被迫自己捕获所有标记并将其存储在数组中的全部原因是因为它们没有存储在 codemirror 实例中的任何位置。这表明他们在 .clear 上所做的任何事情都是自包含的(也就是说,每个 TextMarker 都将清除所需的所有信息存储在自身上。)。确定后,我们可以看一下 markText() 和 .clear 函数:

function markText(from, to, className, options) {
      from = clipPos(from); to = clipPos(to);
      var marker = new TextMarker("range", className);
      if (options) for (var opt in options) if (options.hasOwnProperty(opt))
        marker[opt] = options[opt];
      var curLine = from.line;
      doc.iter(curLine, to.line + 1, function(line) {
        var span = {from: curLine == from.line ? from.ch : null,
                    to: curLine == to.line ? to.ch : null,
                    marker: marker};
        line.markedSpans = (line.markedSpans || []).concat([span]);
        marker.lines.push(line);
        ++curLine;
      });
      changes.push({from: from.line, to: to.line + 1});
      return marker;
    }
TextMarker.prototype.clear = operation(function() {
      var min, max;
      for (var i = 0; i < this.lines.length; ++i) {
        var line = this.lines[i];
        var span = getMarkedSpanFor(line.markedSpans, this);
        if (span.from != null) min = lineNo(line);
        if (span.to != null) max = lineNo(line);
        line.markedSpans = removeMarkedSpan(line.markedSpans, span);
      }
      if (min != null) changes.push({from: min, to: max + 1});
      this.lines.length = 0;
      this.explicitlyCleared = true;
    });

我没有包含所有代码,因此请随意阅读它(codemirror.js),但您应该注意的是,所有方法真正做的是确保如果您调用 clear 它会删除标记正确的地方,因为没有理由你不能使用不同的标记将相同的 css 类添加到不同的行......并且清除一个不应该清除两者。该方法还更新更改数组,该数组只是更改了哪些行的记录。

由于我们正在执行“全部清除”,因此我们并不真正关心删除一些而不是其他一些,因此无需确定跨越标记影响的内容。此外,由于 markText 没有任何副作用,因此无需重置任何其他内容,因此您所做的一切就是删除 css 类。

因此,为了稍微加快清除速度,您仍然必须存储标记或使用标记应用的类,以便您可以依次执行以下操作之一:

如果您仍然存储标记:

for (var i = 0;i<markers.length;i++)
    $('.handleToCodeMirrorEditor').removeClass(markers[i].style);

如果您只存储类:

$('.handleToCodeMirrorEditor').removeClass(classes.join(" "));

基准测试:虽然我很清楚有效的基准测试通常是一项棘手的任务,但我认为至少对各种方法进行几次测试是值得的。我设置了一个测试,其中我添加了一定数量的标记,每个标记应用不同的类(按索引递增)。然后我运行并计时了 3 种不同的方法来分别删除这些标记。我以不同的顺序多次运行每个测试,以确保结果一致。我比较了3种方法:

  • 存储标记并在每个标记上调用 clear。
  • 存储标记并在每个人的特定样式上调用 removeClass
  • 存储样式并在所有样式上调用 removeClass (classes.join(" "))。

对于 100 个标记,去除结果如下:

297ms .clear
160ms .removeClass on each markerStyle
153ms .removeClass single call

对于 1000 个标记:

4891ms .clear
2677ms .removeClass on each markerStyle
2572ms .removeClass single call
于 2012-12-06T18:36:16.103 回答
1

最干净的解决方案是提取所有标记,然后清除它们

editor.doc.getAllMarks().forEach(marker => marker.clear());

或在上述情况下

this.instance.doc.getAllMarks().forEach(marker => marker.clear());
于 2021-07-28T19:31:18.247 回答
0
//for marking a text and storing it
var cursor = this.instance.getSearchCursor(val);
var scopedInstance = this;

while (cursor.findNext()) 
{
    this.histMarks.push(scopedInstance.instance.markText(cursor.from(), cursor.to(), { className: 'highlight' }));
}


//for removing a marked text by specific intention
for (var i = 0;i < this.histMarks.length;i++)
{
  for (var j = 0;j < this.histMarks[i].lines.length;j++)
  {
    if(this.histMarks[i].lines[j].text.includes(val))
    {
      this.histMarks[i].clear();
      this.histMarks.splice(i, 1);
    }
  }
}
于 2020-03-02T18:58:23.917 回答