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

Вот пример:

<code>$(function() {
  $('#test').change(function() {
    $('#length').html($('#test').val().length)
  })
})</code>
<code><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></code>

Заполните текстовое поле строками (по одному символу в строке), пока браузер не разрешит. Когда вы закончите, оставьте textarea, и js code будет также вычислять символы.

Так что в моем случае я мог ввести только 7 символов (включая пробелы), прежде чем Chrome остановил меня. Хотя значение атрибута maxlength равно 10:

imgur

 styfle31 окт. 2012 г., 01:06
 Tats_innit26 сент. 2013 г., 02:09
ИЛИ или может быть это:stackoverflow.com/questions/11839413/…

Ответы на вопрос(10)

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

Carriage return

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

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

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

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

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

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

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

Binary: 00001101 00001010

Hex: 0D0A

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

HTML-сущности могут быть

1) Создано из кода JavaScript:

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

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

2) Разобрано с содержания текстовой области:

Ansi code: &#13;&#10;

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

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

4) Определяется какmultiline содержание текстового поля

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

Character Encoding

Кодировка символов поля ввода, такого как 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-кодировка теряется при чтении атрибута из поля ввода

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

Chrome и Firefox считают длину<textarea> теги таким же образом для целей "maxlength".

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

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

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

 05 апр. 2012 г., 17:07
 29 окт. 2014 г., 22:07
Похоже, вы говорите.val() возвращает его неправильно (1 символ), но браузер правильно видит его как 2 символа, поэтомуmaxlength будет принимать во внимание 2 символа для каждой новой строки. Если это так, и ваша база данных имеет фиксированный максимум, я не вижу, какmaxlength бесполезен, потому что он правильно подсчитывает количество символов по мере их сохранения в базе данных.
 30 окт. 2014 г., 17:14
@ Pointy Это противоречит этому вопросу. ОП говорит, что у него есть текстовая область, сmaxlength из 10, но он может печатать только 7 символов (включая 1 символ для каждой новой строки), когда набирает текстовую область. Это ясно показывает, чтоmaxlength учитывает 2 символа для каждой новой строки. Мое собственное тестирование подтверждает это ...
 30 окт. 2014 г., 05:32
@wired_in снова привет :) Проблема в том, что встроенныйmaxlength проверка делаетnot принять во внимание символы CR. Это означает, что встроенныйmaxlength позволит текстовой области содержать большеactual символы в клиенте, чем allo, wed. Итак, если у вас есть поле базы данных длиной 500 символов, и вы говоритеmaxlength=500опубликованная форма может содержать значение сmore than 500 characters.  Атрибут поэтому бесполезен.

Вот как сделать так, чтобы ваш код 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 к числу символов для каждого.

 05 февр. 2018 г., 01:02
@Tim, хотя скрипт правильно отображает длину, что позволяет вводить больше символов, если возврат каретки уже существует. Я смог ввести 12 символов после ввода двух символов возврата каретки.
 10 мар. 2014 г., 18:57
Также может быть написано как:$('#length').html(x.replace(/(\r\n|\n|\r)/g, '--').length);
 28 апр. 2014 г., 12:36
jsfiddle.net/FjXgA/53  ссылка выше полезна. Спасибо
 23 янв. 2017 г., 21:22
@Stalinko Я только что проверил это в Firefox, Chrome, IE, Edge и Opera. Похоже, работает одинаково во всех из них. Новые строки добавляют 2 к длине. Это то, что вы видели, или вы имели в виду что-то еще?
 10 дек. 2015 г., 06:10
Это работает неправильно в Firefox, потому что он считает перевод строки как 1 символ
Решение Вопроса

Ваши возвраты каретки считаются 2 символами каждый, когда дело доходит до длины.

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

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

 05 апр. 2012 г., 17:01
@ Позади, я понятия не имею ...
 Roman Pominov05 апр. 2012 г., 17:00
Да, я тоже так думаю. Но почему js не считает возврат каретки как 2 символа? Есть ли способ заставить это сделать это?
 05 апр. 2012 г., 16:57
Я зарегистрировал ошибки по этому вопросу как в Chrome, так и в Firefox; похоже, это исправлено в последней версии Chrome.
 05 апр. 2012 г., 17:02
Когда содержимое текстовой области на самом делеposted, встроенные переводы строкmust передаваться как пары CR LF. Таким образом, правильно сделать так, чтобы браузер сообщал о длине содержимого, как если бы переводы строки стоят 2 символа.
 05 апр. 2012 г., 16:59
@Pointy Я в версии Chrome для разработчиков (19.0.1084.1) и у меня еще есть эта проблема.

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

HTML:

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

JS:

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

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

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

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

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

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

Вот более универсальное решение, которое переопределяет jQuery 'val'. функция. В скором времени сделаем эту проблему в сообщении в блоге и разместим ссылку здесь.

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);
    }
};
 22 мар. 2017 г., 19:14
Спасибо чувак. Я ценю благодарность.
 22 мар. 2017 г., 19:08
Потрясающее сообщение в блоге между прочим

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

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


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

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

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

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

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

отлично работает на Google уже в IE должны избегать сценария! В IE «разрывная строка»; считается только один раз, поэтому избегайте этого решения в IE!

 29 июл. 2015 г., 18:43
Это не удается при вставке.

Ваш ответ на вопрос