2015-10-24 99 views
0

我期望通過指定背景顏色和一系列索引來突出顯示textarea中的文本。然後,我將不斷更改並隨着用戶輸入動態更新突出顯示的文本。動態突出顯示textarea

jquery.highlightTextarea幾乎是完美的。問題在於它看起來並不是真正旨在像這樣即時更新突出顯示的文本。除此之外,作者現在已經停產,不再更新它。

我甚至去看Ace Code Editor,但基於簡單索引進行高亮顯示的能力並不是真的存在於那個(你必須根據行/列高亮顯示)。再加上它看起來對我所做的事情來說是過度殺傷力。

所以我正在尋找替代品。除了我提到的功能之外,我的優先級列表中的性能也很高。我想編譯一個需要考慮的庫列表。有什麼建議麼?

+0

@charlietfl - 我的意思是能在每次按鍵之後發送新的索引範圍。所以拆除DOM對象並重新初始化並不理想(現在我可以這樣做)。最好我只是發送新的索引範圍,突出顯示會改變。 –

+0

定義突出顯示的索引從哪裏來?他們是否在文本中綁定到關鍵字? –

+0

@MartinStaufcik - 來自正則表達式的AJAX調用。因此,例如,您可以突出顯示一個句子中的所有e,但我提供的所有索引都是索引範圍。 –

回答

0

我終於想出了一些對我來說很好的東西。我正在使用Ace Editor。我在Ace和CodeMirror之間來回奔波,最終決定了Ace,因爲我覺得這個特定的任務更直接一點,文檔也更好。我直截了當地說,但複雜的是,我不得不將索引範圍轉換爲列/行範圍,因爲這是Ace中Range對象所期望的格式。

但這裏是我想出了:

function HighlightMatches(matches) { 
    var matchClass = "myMarker"; 
    var oldMarkers = inputEditor.session.$backMarkers; 

    // clear out old markers 
    for (var prop in oldMarkers) { 
     if (oldMarkers[prop].clazz == matchClass) { 
      inputEditor.session.removeMarker(oldMarkers[prop].id); 
     } 
    } 

    if (matches && matches.length > 0) { 
     var ranges = NormalizedRanges(GetInput(), matches); 

     // add new markers 
     for (var i = 0; i < ranges.length; i++) { 
      inputEditor.session.addMarker(new Range(ranges[i].startRow, ranges[i].startCol, ranges[i].endRow, ranges[i].endCol), matchClass); 
     } 
    } 
}  

function NormalizedRanges(input, matches) { 
    var ranges = []; 

    var startCol = 0; 
    var endCol = 0; 
    var startRow = 0; 
    var endRow = 0; 
    var currentMatch = 0; 

    var matchStart = 0; 
    var matchLength = 0; 
    var matchEnd = 0; 

    for (var i = 0; i < input.length; i++) { 
     matchStart = matches[currentMatch].index; 
     matchLength = matches[currentMatch].length; 
     matchEnd = matchStart + matchLength;    

     // process match 
     if (i >= matchStart && i <= matchEnd) { 
      endCol = startCol; 
      endRow = startRow; 

      for (var k = 0; k < matchLength; k++) { 
       endCol++; 
       var advanceNewLine = AdvanceNewLine(input.substr(i + k, 2)) 
       if (advanceNewLine > 0) { 
        endRow++; 
        endCol = 0; 
        if (advanceNewLine == 2) 
         k++; 
       } 
      } 

      ranges.push(new IndexRange(startCol, endCol, startRow, endRow)); 

      startCol = endCol; 
      startRow = endRow; 

      // set index to end of match 
      i = matchEnd - 1; 

      // advance current match 
      currentMatch++; 
      if (currentMatch == matches.length) 
       return ranges; 
     } 
     else { 
      // advance range 
      startCol++; 
      var advanceNewLine = AdvanceNewLine(input.substr(i, 2)); 
      if (advanceNewLine > 0) { 
       startRow++; 
       startCol = 0; 
       if (advanceNewLine == 2) 
        i++; 
      } 
     } 
    } 

    return ranges; 
} 

function AdvanceNewLine(text) { 
    if (text == '\r\n') 
     return 2; 
    else { 
     var char = text.charAt(0); 
     if (char == '\n' || text == '\r') 
      return 1; 
     else 
      return 0; 
    }   
} 

function IndexRange(startCol, endCol, startRow, endRow) { 
    this.startCol = startCol; 
    this.endCol = endCol; 
    this.startRow = startRow; 
    this.endRow = endRow; 
} 

您只需撥打HighlightMatches,並在matches JSON對象傳遞,可能是這個樣子:

{"matches":[{"index":0,"length":1},{"index":4,"length":1}]}