2012-02-07 44 views
15

Tôi muốn tìm hiểu và theo dõi 'số dòng' (hàng) của con trỏ trong vùng văn bản. ('Bức tranh lớn hơn' là phân tích cú pháp văn bản trên dòng mỗi khi một dòng mới được tạo/sửa đổi/được chọn, nếu dĩ nhiên văn bản không được dán. Điều này sẽ giúp phân tích toàn bộ văn bản không nhất thiết trong khoảng thời gian đã định).Tìm số 'dòng' (con trỏ) trong một văn bản

Có một vài bài đăng trên StackOverflow tuy nhiên không có câu trả lời cụ thể nào cho câu hỏi của tôi, hầu hết các câu hỏi dành cho vị trí con trỏ tính bằng pixel hoặc hiển thị số dòng bên cạnh vùng văn bản.

Nỗ lực của tôi ở bên dưới, nó hoạt động tốt khi bắt đầu ở dòng 1 và không rời khỏi vùng văn bản. Nó không thành công khi nhắp chuột ra khỏi vùng văn bản và quay lại nó trên một dòng khác. Nó cũng không thành công khi dán văn bản vào nó vì dòng bắt đầu không phải là 1.

Kiến thức JavaScript của tôi khá hạn chế.

<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

Bằng cách dòng, bạn có nghĩa chèo? Cột và dòng không giống nhau khi nói văn bản. Không có cột khi các phông chữ không đơn cách được sử dụng. – Anurag

+0

Xin lỗi, vâng, ý tôi là hàng. Tôi sẽ cập nhật bài đăng gốc của mình. – ethicalhack3r

Trả lời

23

Bạn muốn sử dụng selectionStart để thực hiện việc này.

<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> 

Điều này cũng hoạt động khi bạn thay đổi vị trí con trỏ bằng chuột.

+0

WOW. Không thể yêu cầu một giải pháp tốt hơn! Làm sạch và hoạt động hoàn hảo! Cảm ơn nhiều! – ethicalhack3r

+0

bạn được chào đón :) – caleb

+18

Giải pháp này sẽ không hoạt động nếu có các dấu ngắt dòng mềm trong vùng văn bản. Ví dụ: tạo một vùng văn bản có 10 cột, đặt trong một vài từ trong đó để văn bản tràn qua 2-3 dòng - nhưng KHÔNG thêm dòng mới trong đó. Mã ở trên sẽ luôn trả về 1 vì không có ký tự "\ n" trong vùng văn bản - nhưng người dùng thực sự thấy nhiều hơn 1 hàng. Đó là khó khăn thực sự với TEXTAREAs ... Tôi thực sự ngạc nhiên khi không có bất kỳ API chuẩn nào cho điều này trong các trình duyệt hiện đại ... –

16

Điều này là khó khăn vì quấn từ. Đó là một điều rất dễ dàng để đếm số lượng ngắt dòng hiện tại, nhưng điều gì sẽ xảy ra khi hàng mới là do quấn từ? Để giải quyết vấn đề này, việc tạo một tấm gương (credit: github.com/jevin) rất hữu ích. Dưới đây là ý tưởng:

  1. Tạo một tấm gương của textarea
  2. Gửi nội dung từ đầu của textarea để con trỏ đến gương
  3. Sử dụng chiều cao của gương để trích xuất các hàng hiện tại

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

Đây phải là câu trả lời được chấp nhận. Tôi đã không thử nghiệm mã nhưng nó ít nhất là cố gắng một giải pháp làm việc xử lý các ngắt dòng mềm. – ryandlf

+0

Tạo kiểu có phải là một phần bắt buộc của giải pháp không? Tôi thực hiện điều này mà không có CSS ​​và đặt thuộc tính bọc textarea của tôi thành 'off'. Nếu sau đó tôi nhập văn bản vào vùng văn bản sao cho nó chạy khỏi cạnh của vùng văn bản (buộc thanh cuộn ngang xuất hiện), số hàng báo cáo tăng lên mặc dù tôi chưa tạo hàng mới. – youcantryreachingme

Các vấn đề liên quan