Ограничение количества строк в текстовой области - PullRequest
34 голосов
/ 17 февраля 2009

Я ищу javascript, который может ограничивать количество строк (под строкой я имею в виду некоторый текст, заканчивающийся нажатием клавиши ввода на клавиатуре), который пользователь может вводить в текстовой области. Я нашел некоторые решения, но они просто не работают или ведут себя очень странно. Лучшим решением будет плагин jquery, который может выполнить эту работу - что-то вроде CharLimit , но он должен иметь возможность ограничивать количество строк текста, а не количество символов.

Ответы [ 8 ]

23 голосов
/ 17 февраля 2009

Это может помочь (вероятно, лучше всего использовать jQuery, onDomReady и незаметно добавлять событие keydown в текстовую область), но протестировано в IE7 и FF3:

<html>
  <head><title>Test</title></head>
  <body>
    <script type="text/javascript">
      var keynum, lines = 1;

      function limitLines(obj, e) {
        // IE
        if(window.event) {
          keynum = e.keyCode;
        // Netscape/Firefox/Opera
        } else if(e.which) {
          keynum = e.which;
        }

        if(keynum == 13) {
          if(lines == obj.rows) {
            return false;
          }else{
            lines++;
          }
        }
      }
      </script>
    <textarea rows="4" onkeydown="return limitLines(this, event)"></textarea>
  </body>
</html>

* Правка - объяснение: он ловит нажатие клавиши, если нажата клавиша ENTER, и просто не добавляет новую строку, если строки в текстовой области совпадают с номерами строк текстовой области. Иначе он увеличивает количество строк.

Редактировать # 2: Учитывая, что люди все еще приходят к этому ответу, я подумал, что я бы обновил его, чтобы обрабатывать вставку, удаление и вырезание, как можно лучше.

<html>

<head>
    <title>Test</title>
    <style>
        .limit-me {
            height: 500px;
            width: 500px;
        }
    </style>
</head>

<body>
<textarea rows="4" class="limit-me"></textarea>

<script>
    var lines = 1;

    function getKeyNum(e) {
        var keynum;
        // IE
        if (window.event) {
            keynum = e.keyCode;
            // Netscape/Firefox/Opera
        } else if (e.which) {
            keynum = e.which;
        }

        return keynum;
    }

    var limitLines = function (e) {
        var keynum = getKeyNum(e);

        if (keynum === 13) {
            if (lines >= this.rows) {
                e.stopPropagation();
                e.preventDefault();
            } else {
                lines++;
            }
        }
    };

    var setNumberOfLines = function (e) {
        lines = getNumberOfLines(this.value);
    };

    var limitPaste = function (e) {
        var clipboardData, pastedData;

        // Stop data actually being pasted into div
        e.stopPropagation();
        e.preventDefault();

        // Get pasted data via clipboard API
        clipboardData = e.clipboardData || window.clipboardData;
        pastedData = clipboardData.getData('Text');

        var pastedLines = getNumberOfLines(pastedData);

        // Do whatever with pasteddata
        if (pastedLines <= this.rows) {
            lines = pastedLines;
            this.value = pastedData;
        }
        else if (pastedLines > this.rows) {
            // alert("Too many lines pasted ");
            this.value = pastedData
                .split(/\r\n|\r|\n/)
                .slice(0, this.rows)
                .join("\n ");
        }
    };

    function getNumberOfLines(str) {
        if (str) {
            return str.split(/\r\n|\r|\n/).length;
        }

        return 1;
    }

    var limitedElements = document.getElementsByClassName('limit-me');

    Array.from(limitedElements).forEach(function (element) {
        element.addEventListener('keydown', limitLines);
        element.addEventListener('keyup', setNumberOfLines);
        element.addEventListener('cut', setNumberOfLines);
        element.addEventListener('paste', limitPaste);
    });
</script>
</body>
</html>
15 голосов
/ 27 июня 2011

Как это сделать с помощью jQuery:

Привязать к событию keyDown textarea.

function limitTextareaLine(e) {
    if(e.keyCode == 13 && $(this).val().split("\n").length >= $(this).attr('rows')) { 
        return false;
    }
}
4 голосов
/ 19 декабря 2012

Это решение работает:

<script type="text/javascript">
    function limitTextarea(textarea, maxLines, maxChar) {
        var lines = textarea.value.replace(/\r/g, '').split('\n'), lines_removed, char_removed, i;
        if (maxLines && lines.length > maxLines) {
            lines = lines.slice(0, maxLines);
            lines_removed = 1
        }
        if (maxChar) {
            i = lines.length;
            while (i-- > 0) if (lines[i].length > maxChar) {
                lines[i] = lines[i].slice(0, maxChar);
                char_removed = 1
            }
            if (char_removed || lines_removed) {
                textarea.value = lines.join('\n')
            }
        }
    }
</script>

и текстовая область будет

<asp:TextBox ID="myWishTB" runat="server" Height="185px" TextMode="MultiLine" 
             Style="overflow: auto;" Width="95%" 
             onkeyup="limitTextarea(this,10,80)">
</asp:TextBox>

в обычном HTML:

<textarea id="textareaID" onkeyup="limitTextarea(this,5,100)" cols="20" rows="5">   </textarea>
3 голосов
/ 07 сентября 2013

jQuery пример. Это работает как для набора текста, так и для вставки.

  //Limit to # of rows in textarea or arbitrary # of rows
  $('#yourtextarea').bind('change keyup', function(event) {
    //Option 1: Limit to # of rows in textarea
    rows = $(this).attr('rows');
    //Optiion 2: Limit to arbitrary # of rows
    rows = 6;

    var value = '';
    var splitval = $(this).val().split("\n");

    for(var a=0;a<rows && typeof splitval[a] != 'undefined';a++) {
      if(a>0) value += "\n";
      value += splitval[a];
    }
    $(this).val(value);
  });
3 голосов
/ 09 августа 2011

(сделано с помощью jquery). Это не идеально, но заботится об упаковке. Не зависит только от конца строки (\ n).
У события jquery scroll возникают проблемы в mozilla и firefox, если свойство переполнения css в textarea не установлено автоматически, в противном случае удалите соответствующие строки и установите скрытое переполнение. Может помочь CSS изменить размер: нет и фиксированной высоты.

$('#textarea').scroll(function () {
    $(this).css("overflow", "hidden");      /* for the mozilla browser problem */
    $(this).animate({scrollTop: $(this).outerHeight()});
    while ($(this).scrollTop() > 0) {       /* for the copy and paste case */               
        lines=$(this).val().slice(0,-1);
        $(this).val(lines);
    }
    $(this).css("overflow", "auto");        /* For the mozilla browser problem */
});
3 голосов
/ 17 февраля 2009

Количество видимых / отображаемых строк для данного блока текста будет варьироваться в зависимости от различных браузеров, используемых шрифтов и т. Д. Чтобы иметь возможность полу -надежно считать строки дисплея.

ОБНОВЛЕНИЕ: я вижу редактирование. Тогда что-то вроде кода kevchadders должно подойти вам. Вам понадобится js, который подсчитывает символы и '\ r \ n's и проверяет пользовательский лимит. Кроме того, если вы не используете его скрипт, убедитесь, что вы используете тот, который включает проверку временного интервала и / или события onKeyDown / onKeyUp текстовой области. Возможно, поэтому некоторые протестированные вами скрипты «ведут себя странно».

1 голос
/ 31 марта 2009

Это в основном то же самое, что и ответ Ивана с использованием jQuery Я проверил это для собственного проекта; кажется, работает нормально.

<script type="text/javascript" charset="utf-8">
  $(function() 
  {
    function getLines(id)
    {
      return $('#' + id).val().split("\n").length
    }

  $('#testing').keyup(function() 
  {
    var allowedNumberOfLines = 4;

    if(getLines('testing') > allowedNumberOfLines)
    {
      modifiedText = $(this).val().split("\n").slice(0, allowedNumberOfLines);
      $(this).val(modifiedText.join("\n"));
    }
  });
});
</script>
0 голосов
/ 04 декабря 2011

Я немного его расширил, чтобы обнаружить даже переполнение без переноса строки вручную. Это для текстового поля фиксированного размера с «переполнением: скрытый».

В настоящее время мое решение уменьшает размер шрифта, если он не соответствует текстовой области. И делает его снова больше, если это возможно.

var keynum, allowedLines = 5, defaultFontSize = 13/*px*/;

$(document).ready(function() {
    $("textarea").keydown(function(e, obj) {
        if(window.event)
            keynum = e.keyCode;
        else if (e.which)
            keynum = e.which;

        if (keynum == 13 && allowedLines <= $(this).val().split("\n").length)
            return false;
    });
    $("textarea").keyup(function(e, obj) {
        // Avoid copy-paste
        if (allowedLines < $(this).val().split("\n").length) {              
            lines = $(this).val().split("\n").slice(0, allowedLines);
            $(this).val( lines.join('\n') );
        }

        // Check overflow
        if ((this.clientHeight < this.scrollHeight)) {
            while ((this.clientHeight < this.scrollHeight)) {
                currFontSize = $(this).css('font-size');
                finalNum = parseFloat(currFontSize, 11);
                stringEnding = currFontSize.slice(-2);
                $(this).css('font-size', (finalNum-1) + stringEnding);
            }
        } else if ($(this).css('fontSize') != defaultFontSize+'px')  {
            while ($(this).css('font-size') != defaultFontSize+'px') {
                // First lets increase the font size
                currFontSize = $(this).css('font-size');
                finalNum = parseFloat(currFontSize, 11);
                stringEnding = currFontSize.slice(-2);
                $(this).css('font-size', (finalNum+1) + stringEnding);
                // lets loop until its enough or it gets overflow again
                if(this.clientHeight < this.scrollHeight) {
                    // there was an overflow and we have to recover the value
                    $(this).css('font-size', currFontSize);
                    break;
                }
            }
        }
    });
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...