2012-02-07 3 views
15

텍스트 영역에서 커서의 '행 번호'(행)를 찾아서 추적하고 싶습니다. ('더 큰 그림'은 물론 텍스트가 붙여 넣어지지 않은 경우 새로운 줄이 생성/수정/선택 될 때마다 줄의 텍스트를 구문 분석하는 것입니다. 이렇게하면 설정된 간격으로 전체 텍스트를 반드시 구문 분석하지 않아도됩니다.)텍스트 영역에서 커서의 '행'(행) 번호를 확인하십시오.

StackOverflow에는 몇 가지 게시물이 있지만 아무도 특별히 내 질문에 대답하지 않습니다. 대부분의 질문은 픽셀 단위의 커서 위치 또는 텍스트 영역 외의 줄 번호 표시입니다.

내 시도는 1 행부터 시작하여 텍스트 영역을 벗어날 때 잘 동작합니다. textarea를 클릭하고 다른 줄에 다시 올리면 실패합니다. 시작 줄이 1이 아니기 때문에 텍스트를 붙여 넣을 때도 실패합니다.

내 JavaScript 지식이 제한되어 있습니다.

<html> 

<head> 
<title>DEVBug</title> 

<script type="text/javascript"> 

    var total_lines = 1; // total lines 
    var current_line = 1; // current line 
    var old_line_count; 

    // main editor function 
    function code(e) { 

     // declare some needed vars 
     var keypress_code = e.keyCode; // key press 
     var editor = document.getElementById('editor'); // the editor textarea 
     var source_code = editor.value; // contents of the editor 

     // work out how many lines we have used in total  
      var lines = source_code.split("\n"); 
      var total_lines = lines.length; 

    // do stuff on key presses 
    if (keypress_code == '13') { // Enter 
     current_line += 1; 
    } else if (keypress_code == '8') { // Backspace 
     if (old_line_count > total_lines) { current_line -= 1; } 
    } else if (keypress_code == '38') { // Up 
     if (total_lines > 1 && current_line > 1) { current_line -= 1; } 
    } else if (keypress_code == '40') { // Down 
     if (total_lines > 1 && current_line < total_lines) { current_line += 1; } 
    } else { 
     //document.getElementById('keycodes').innerHTML += keypress_code; 
    } 

    // for some reason chrome doesn't enter a newline char on enter 
    // you have to press enter and then an additional key for \n to appear 
    // making the total_lines counter lag. 
    if (total_lines < current_line) { total_lines += 1 }; 

    // putput the data 
    document.getElementById('total_lines').innerHTML = "Total lines: " + total_lines; 
    document.getElementById('current_line').innerHTML = "Current line: " + current_line; 

    // save the old line count for comparison on next run 
    old_line_count = total_lines; 

} 

</script> 

</head> 

<body> 

<textarea id="editor" rows="30" cols="100" value="" onkeydown="code(event)"></textarea> 
<div id="total_lines"></div> 
<div id="current_line"></div> 

</body> 

</html> 
+1

, 당신은 행 의미합니까? 텍스트를 말할 때 줄과 줄이 같지 않습니다. 고정 폭 글꼴이 아닌 경우 열이 없습니다. – Anurag

+0

죄송합니다. 예, 행을 의미합니다. 원래 게시물을 업데이트 할 것입니다. – ethicalhack3r

답변

23

이렇게하려면 selectionStart을 사용하고 싶습니다.

<textarea onkeyup="getLineNumber(this, document.getElementById('lineNo'));" onmouseup="this.onkeyup();"></textarea> 
<div id="lineNo"></div> 

<script> 

    function getLineNumber(textarea, indicator) { 

     indicator.innerHTML = textarea.value.substr(0, textarea.selectionStart).split("\n").length; 
    } 

</script> 

마우스를 사용하여 커서 위치를 변경할 때도 작동합니다.

+0

와우. 더 나은 해결책을 요구하지 못했습니다! 깨끗하고 완벽하게 작동합니다! 고마워요! – ethicalhack3r

+0

당신은 환영합니다 :) – caleb

+18

텍스트 영역에 부드러운 줄 바꿈이 있으면이 솔루션은 작동하지 않습니다. 예 : 10 개의 열이있는 텍스트 영역을 만들고 그 안에 몇 단어를 넣으면 텍스트가 2-3 줄까지 오버플로되지만 그 안에 줄 바꿈을 추가하지 마십시오. 텍스트 영역에 "\ n"문자가 없기 때문에 위의 코드는 항상 1을 반환하지만 사용자는 실제로 두 개 이상의 행을 봅니다. 그게 TEXTAREAs의 진짜 어려움입니다 ... 나는 현대적인 브라우저에서 이것을위한 표준 API가 없다는 것에 정말로 놀랐습니다 ... –

16

단어 감싸기 때문에 어렵습니다. 줄 바꿈 수를 계산하는 것은 매우 쉬운 일이지만, 줄 바꿈 때문에 새 줄이 생기면 어떻게됩니까? 이 문제를 해결하려면 미러 (신용 : github.com/jevin)를 만드는 것이 좋습니다. 여기에 아이디어 :

  1. 는 현재 행을 추출하기 위해 거울
  2. 를 사용하여 미러의 높이로 커서를 텍스트 영역의 시작 부분에서 콘텐츠를 보내기 텍스트 영역
  3. 의 거울 만들기
  4. 선으로

On JSFiddle

jQuery.fn.trackRows = function() { 
    return this.each(function() { 

    var ininitalHeight, currentRow, firstIteration = true; 

    var createMirror = function(textarea) { 
     jQuery(textarea).after('<div class="autogrow-textarea-mirror"></div>'); 
     return jQuery(textarea).next('.autogrow-textarea-mirror')[0]; 
    } 

    var sendContentToMirror = function (textarea) { 
     mirror.innerHTML = String(textarea.value.substring(0,textarea.selectionStart-1)).replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/'/g, '&#39;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\n/g, '<br />') + '.<br/>.'; 
     calculateRowNumber(); 
    } 

    var growTextarea = function() { 
     sendContentToMirror(this); 
    } 

    var calculateRowNumber = function() { 
     if(firstIteration){ 
      ininitalHeight = $(mirror).height(); 
      currentHeight = ininitalHeight; 
      firstIteration = false; 
     } else { 
      currentHeight = $(mirror).height(); 
     } 
     // Assume that textarea.rows = 2 initially 
     currentRow = currentHeight/(ininitalHeight/2) - 1; 
     //remove tracker in production 
     $('.tracker').html('Current row: ' + currentRow); 
    } 

    // Create a mirror 
    var mirror = createMirror(this); 

    // Style the mirror 
    mirror.style.display = 'none'; 
    mirror.style.wordWrap = 'break-word'; 
    mirror.style.whiteSpace = 'normal'; 
    mirror.style.padding = jQuery(this).css('padding'); 
    mirror.style.width = jQuery(this).css('width'); 
    mirror.style.fontFamily = jQuery(this).css('font-family'); 
    mirror.style.fontSize = jQuery(this).css('font-size'); 
    mirror.style.lineHeight = jQuery(this).css('line-height'); 

    // Style the textarea 
    this.style.overflow = "hidden"; 
    this.style.minHeight = this.rows+"em"; 

    var ininitalHeight = $(mirror).height(); 

    // Bind the textarea's event 
    this.onkeyup = growTextarea; 

    // Fire the event for text already present 
    // sendContentToMirror(this); 

    }); 
}; 

$(function(){ 
    $('textarea').trackRows(); 
}); 
+2

이것은 받아 들여진 대답이어야합니다. 코드를 테스트하지는 않았지만 최소한 소프트 줄 바꿈을 처리하는 작업 솔루션을 시도합니다. – ryandlf

+0

스타일링은 솔루션의 필수 부분입니까? 나는 이것을 CSS없이 구현하고 textarea wrap 속성을 'off'로 설정했다. 그런 다음 텍스트 영역에 텍스트를 입력하여 텍스트 영역의 가장자리에서 벗어나면 (가로 스크롤 막대가 표시되도록), 새 행을 만들지 않았는데도 행 번호 보고서가 증가합니다. – youcantryreachingme

관련 문제