web-dev-qa-db-ja.com

HTMLテキストエリアの行数を見つける

デバイスのブラウザにスクロールバーが表示されないモバイルWebアプリケーションを作成しています。このため、textareaの高さを動的に変更して大きくしようとしていますが、実際にhtmltextareaの行数を取得する方法がわかりません。どんな助けでも大歓迎です!

編集

だから私は今、それ自体が改行ではなく、実際の行の折り返しであることに気づきました。したがって、1行が終了すると、テキストが次の行に折り返されます。改行のように見えます。これらの数を数える方法はありますか?ありがとう!

23
Kyle

私はこのブログで説明されている機能を使用したことはありませんが、便利な場合があります。

http://kirblog.idetalk.com/2010/03/calculating-cursor-position-in-textarea.html

基本的に、divを作成し、同じdivに同じ幅とフォント特性でテキストをコピーすると、行数などの必要な情報を取得できます。この例の行数は簡単です。1行の高さが何ピクセルかわかっている場合は、テストdivの幅を見つけるだけで、何行あるかについてかなり正確なアイデアを得ることができます。あなたのtextarea

7
James Black

Textareaの行数は次のようになります

textarea.value.match(/\n/g).length + 1
16
Delan Azabani

<textarea>で行カウントとラップ検出を処理するプラグインを作成しました。
誰かがそれを使用できることを願っています。

BitBucketのコード

使用例

var result = $.countLines("#textarea");

result.actual   // The number of lines in the textarea.
result.wraps    // The number of lines in the textarea that wrap at least once.
result.wrapped  // The total number of times all lines wrap.
result.blank    // The number of blank lines.
result.visual   // The approximate number of lines that the user actually sees in the textarea  

実演

/*! Textarea Line Count - v1.4.1 - 2012-12-06
 * https://bitbucket.org/MostThingsWeb/textarea-line-count
 * Copyright (c) 2012 MostThingsWeb (Chris Laplante); Licensed MIT */

(function($) {
  $.countLines = function(ta, options) {
    var defaults = {
      recalculateCharWidth: true,
      charsMode: "random",
      fontAttrs: ["font-family", "font-size", "text-decoration", "font-style", "font-weight"]
    };

    options = $.extend({}, defaults, options);

    var masterCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
    var counter;

    if (!ta.jquery) {
      ta = $(ta);
    }

    var value = ta.val();
    switch (options.charsMode) {
      case "random":
        // Build a random collection of characters
        options.chars = "";
        masterCharacters += ".,?!-+;:'\"";
        for (counter = 1; counter <= 12; counter++) {
          options.chars += masterCharacters[(Math.floor(Math.random() * masterCharacters.length))];
        }
        break;
      case "alpha":
        options.chars = masterCharacters;
        break;
      case "alpha_extended":
        options.chars = masterCharacters + ".,?!-+;:'\"";
        break;
      case "from_ta":
        // Build a random collection of characters from the textarea
        if (value.length < 15) {
          options.chars = masterCharacters;
        } else {
          for (counter = 1; counter <= 15; counter++) {
            options.chars += value[(Math.floor(Math.random() * value.length))];
          }
        }
        break;
      case "custom":
        // Already defined in options.chars
        break;
    }

    // Decode chars
    if (!$.isArray(options.chars)) {
      options.chars = options.chars.split("");
    }

    // Generate a span after the textarea with a random ID
    var id = "";
    for (counter = 1; counter <= 10; counter++) {
      id += (Math.floor(Math.random() * 10) + 1);
    }

    ta.after("<span id='s" + id + "'></span>");
    var span = $("#s" + id);

    // Hide the span
    span.hide();

    // Apply the font properties of the textarea to the span class
    $.each(options.fontAttrs, function(i, v) {
      span.css(v, ta.css(v));
    });

    // Get the number of lines
    var lines = value.split("\n");
    var linesLen = lines.length;

    var averageWidth;

    // Check if the textarea has a cached version of the average character width
    if (options.recalculateCharWidth || ta.data("average_char") == null) {
      // Get a pretty good estimation of the width of a character in the textarea. To get a better average, add more characters and symbols to this list
      var chars = options.chars;

      var charLen = chars.length;
      var totalWidth = 0;

      $.each(chars, function(i, v) {
        span.text(v);
        totalWidth += span.width();
      });

      // Store average width on textarea
      ta.data("average_char", Math.ceil(totalWidth / charLen));
    }

    averageWidth = ta.data("average_char");

    // We are done with the span, so kill it
    span.remove();

    // Determine missing width (from padding, margins, borders, etc); this is what we will add to each line width
    var missingWidth = (ta.outerWidth() - ta.width()) * 2;

    // Calculate the number of lines that occupy more than one line
    var lineWidth;

    var wrappingLines = 0;
    var wrappingCount = 0;
    var blankLines = 0;

    $.each(lines, function(i, v) {
      // Calculate width of line
      lineWidth = ((v.length + 1) * averageWidth) + missingWidth;
      // Check if the line is wrapped
      if (lineWidth >= ta.outerWidth()) {
        // Calculate number of times the line wraps
        var wrapCount = Math.floor(lineWidth / ta.outerWidth());
        wrappingCount += wrapCount;
        wrappingLines++;
      }

      if ($.trim(v) === "") {
        blankLines++;
      }
    });

    var ret = {};
    ret["actual"] = linesLen;
    ret["wrapped"] = wrappingLines;
    ret["wraps"] = wrappingCount;
    ret["visual"] = linesLen + wrappingCount;
    ret["blank"] = blankLines;

    return ret;
  };
}(jQuery));



result = jQuery.countLines("#textarea");

jQuery('#display').html(
  '<span>Actual: ' + result.actual + '</span>' +
  '<span>Blank: ' + result.blank + '</span>' +
  '<span>Visual: ' + result.visual + '</span>' +
  '<span>Wrapped: ' + result.wrapped + '</span>' +
  '<span>Wraps: ' + result.wraps + '</span>'
);
#textarea {
  width: 150px;
  height: 80px;
}
#display span {
  display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="textarea">text
here
  
this is a longer line so that it will wrap in the box longer longer longer</textarea>

<div id="display"></div>
10
Chris Laplante

これは、折り返された行を含むテキスト領域の行数を数える効率的で正確な方法です。

/** @type {HTMLTextAreaElement} */
var _buffer;

/**
* Returns the number of lines in a textarea, including wrapped lines.
*
* __NOTE__:
* [textarea] should have an integer line height to avoid rounding errors.
*/
function countLines(textarea) {
    if (_buffer == null) {
        _buffer = document.createElement('textarea');
        _buffer.style.border = 'none';
        _buffer.style.height = '0';
        _buffer.style.overflow = 'hidden';
        _buffer.style.padding = '0';
        _buffer.style.position = 'absolute';
        _buffer.style.left = '0';
        _buffer.style.top = '0';
        _buffer.style.zIndex = '-1';
        document.body.appendChild(_buffer);
    }

    var cs = window.getComputedStyle(textarea);
    var pl = parseInt(cs.paddingLeft);
    var pr = parseInt(cs.paddingRight);
    var lh = parseInt(cs.lineHeight);

    // [cs.lineHeight] may return 'normal', which means line height = font size.
    if (isNaN(lh)) lh = parseInt(cs.fontSize);

    // Copy content width.
    _buffer.style.width = (textarea.clientWidth - pl - pr) + 'px';

    // Copy text properties.
    _buffer.style.font = cs.font;
    _buffer.style.letterSpacing = cs.letterSpacing;
    _buffer.style.whiteSpace = cs.whiteSpace;
    _buffer.style.wordBreak = cs.wordBreak;
    _buffer.style.wordSpacing = cs.wordSpacing;
    _buffer.style.wordWrap = cs.wordWrap;

    // Copy value.
    _buffer.value = textarea.value;

    var result = Math.floor(_buffer.scrollHeight / lh);
    if (result == 0) result = 1;
    return result;
}

デモはこちら

6
Kin

scrollHeight を取得し、上下のパディングを減算し​​、lineHeightで除算します。

3
Tgr

たぶん、「生の」数の「ビジュアル」ラインを取得する方法があるでしょう。 textareaのscrollHeightプロパティを読み取り、それを行の高さで割る必要があります。やってみよう。

このHTMLから始めます。

<textarea id="ta" cols="50" rows="10"></textarea>

次に:

var line_height = Math.floor($("#ta").height() / parseInt($("#ta").attr("rows")));
var dirty_number_of_lines = Math.ceil($("#ta")[0].scrollHeight / line_height);

それが本当にうまくいくかどうかはわかりませんが、狂った理論です。

1
Daniel O'Hara

行数を数える合理的な方法がないと確信していますブラウザに表示されるとおり特に、一部のブラウザ(Safari)でユーザーがテキスト領域のサイズを変更できることを考慮してください。

ハッキーですが、最善の策は、合計文字数を1行あたりの平均文字数で割った値に基づいて見積もることです。 :-/

1
tfe

あなたはそう計算することができます:

var length = $('#textarea').val().split("\n").length;
0
HelpNeeder