Chrome считает неправильные символы в textarea с атрибутом maxlength

Вот пример:

$(function() {
  $('#test').change(function() {
    $('#length').html($('#test').val().length)
  })
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id=test maxlength=10></textarea>
length = <span id=length>0</span>

Ответ 1

Возврат каретки считается по 2 символа, когда дело доходит до maxlength.

1\r\n
1\r\n
1\r\n
1

Но похоже, что javascript мог только один из \r\n (я не уверен, какой), который добавляет только 7.

Ответ 2

Здесь, как получить код javascript в соответствии с количеством символов, которое браузер считает в текстовом поле:

http://jsfiddle.net/FjXgA/53/

$(function () {
    $('#test').keyup(function () {
        var x = $('#test').val();

        var newLines = x.match(/(\r\n|\n|\r)/g);
        var addition = 0;
        if (newLines != null) {
            addition = newLines.length;
        }

        $('#length').html(x.length + addition);
    })
})

В основном вы просто считаете общие разрывы строк в текстовом поле и добавляете 1 к числу символов для каждого из них.

Ответ 3

По неизвестным причинам jQuery всегда преобразует все символы новой строки в значение a <textarea> в один символ. То есть, если браузер дает ему \r\n для новой строки, jQuery делает это как раз \n в возвращаемом значении .val().

Chrome и Firefox оба подсчитывают длину тегов <textarea> одинаково для целей "maxlength".

Однако спецификация HTTP настаивает на том, что символы новой строки будут представлены как \r\n. Таким образом, jQuery, webkit и Firefox все ошибаются.

В результате получается, что "maxlength" в тегах <textarea> в значительной степени бесполезно, если ваш серверный код действительно имеет фиксированный максимальный размер для значения поля.

edit — на данный момент (конец 2014 года) похоже, что Chrome (38) ведет себя правильно. Однако Firefox (33) все равно не считает каждый жесткий возврат как 2 символа.

Ответ 4

Кажется, что правильный метод, основанный на ответе Pointy выше, состоит в том, чтобы считать все новые строки двумя символами. Это будет стандартизировать его в браузерах и сопоставить то, что будет отправлено при его публикации.

Таким образом, мы могли бы следовать спецификации и заменять все вхождения возврата каретки, за которым не следует Новая строка, и все новые строки, за которыми не следует возврат каретки, с парой возвратной линии каретки.

var len = $('#test').val().replace(/\r(?!\n)|\n(?!\r)/g, "\r\n").length;

Затем используйте эту переменную, чтобы отобразить длину значения textarea или ограничить ее и т.д.

Ответ 5

Похоже, что javascript также рассматривает длину нового символа строки.

Попробуйте использовать:


var x = $('#test').val();

x = x.replace(/(\r\n|\n|\r)/g,"");    

$('#length').html(x.length);

Я использовал его в своей скрипке, и он работал. Надеюсь, это поможет.

Ответ 6

Это потому, что новая строка на самом деле составляет 2 байта и, следовательно, 2 длинных. JavaScript не видит этого, и поэтому он будет считать только 1, в результате чего общее количество 7 (3 новых строки)

Ответ 7

Здесь более универсальное решение, которое переопределяет функцию "val" jQuery. В ближайшее время эта проблема будет опубликована в блоге.

var originalVal = $.fn.val;
$.fn.val = function (value) {
    if (typeof value == 'undefined') {
        // Getter

        if ($(this).is("textarea")) {
            return originalVal.call(this)
                .replace(/\r\n/g, '\n')     // reduce all \r\n to \n
                .replace(/\r/g, '\n')       // reduce all \r to \n (we shouldn't really need this line. this is for paranoia!)
                .replace(/\n/g, '\r\n');    // expand all \n to \r\n

            // this two-step approach allows us to not accidentally catch a perfect \r\n
            //   and turn it into a \r\r\n, which wouldn't help anything.
        }

        return originalVal.call(this);
    }
    else {
        // Setter
        return originalVal.call(this, value);
    }
};

Ответ 8

var value = $('#textarea').val();
var numberOfLineBreaks = (value.match(/\n/g)||[]).length;
$('#textarea').attr("maxlength",500+numberOfLineBreaks);

отлично работает на google уже в IE, чтобы избежать script! В IE "break-line" подсчитывается только один раз, поэтому избегайте этого решения в IE!

Ответ 9

Если вы хотите получить оставшуюся длину содержимого текстовой области, вы можете использовать совпадение в строке, содержащей разрывы строк.

HTML:

<textarea id="content" rows="5" cols="15" maxlength="250"></textarea>

JS:

var getContentWidthWithNextLine = function(){
    return 250 - content.length + (content.match(/\n/g)||[]).length;
}

Ответ 10

Текстовые области по-прежнему не полностью синхронизированы между браузерами. Я заметил две основные проблемы: возврат каретки и кодировка символов

Возврат каретки

По умолчанию обрабатываются как 2 символа \r\n (стиль Windows).

Проблема в том, что Chrome и Firefox будут считать его одним символом. Вы также можете выбрать его, чтобы наблюдать, что в качестве пробела выбран невидимый символ.

Обходной путь можно найти здесь:

var length = $.trim($(this).val()).split(" ").join("").split('\n').join('').length;

Слово Jquery подсчитывается при разрыве строки пользовательского типа

Internet explorer, с другой стороны, будет считать его как 2 символа.

Их представление:

Двоичный: 00001101 00001010

Hex: 0D0A

и представлены в UTF-8 как 2 символа и считаются для maxlength как 2 символа.

Объекты HTML могут быть

1) Создано из javascript-кода:

<textarea id='txa'></textarea>

document.getElementById("txa").value = String.fromCharCode(13, 10);

2) Разбирается из содержимого текстового поля:

Код Ansi: & # 13; & # 10;

<textarea>Line one.&#13;&#10;Line two.</textarea>

3) Вставка с клавиатуры Введите клавишу

4) Определено как многострочный контент в текстовом поле

<textarea>Line one.
Line two.</textarea>

Кодировка символов

Кодировка символов для поля ввода, такого как textarea, не зависит от кодировки символа страницы. Это важно, если вы планируете считать байты. Итак, если у вас есть мета-заголовок для определения ANSI-кодировки вашей страницы (с 1 байт на символ), содержимое вашего текстового поля по-прежнему остается UTF-8 с 2 байтами на символ.

Обходной путь для кодировки символов приведен ниже:

function htmlEncode(value){
  // Create a in-memory div, set its inner text (which jQuery automatically encodes)
  // Then grab the encoded contents back out. The div never exists on the page.
  return $('<div/>').text(value).html();
}

function htmlDecode(value){
  return $('<div/>').html(value).text();
}

HTML-кодирование потеряно, если атрибут прочитан из поля ввода