Подтвердить что ты не робот

Ограничение количества символов в элементе contentEditable

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

var content_id = 'editable_div';

//binding keyup/down events on the contenteditable div
$('#'+content_id).keyup(function(){ check_charcount(content_id, max); });
$('#'+content_id).keydown(function(){ check_charcount(content_id, max); });

function check_charcount(content_id, max)
{   
    if($('#'+content_id).text().length > max)
    {
        $('#'+content_id).text($('#'+content_id).text().substring(0, max));
    }
}

Это ограничивает количество символов числом, указанным "max", однако, как только текст области задается функцией jquery.text(), курсор сбрасывается до начала области. Поэтому, если пользователь продолжает печатать, введенные символы будут вставлены в начале текста, и последний символ текста будет удален. Так что, действительно, мне нужен какой-то способ держать курсор в конце текста, пригодного для контента.

4b9b3361

Ответ 1

Как насчет передачи объекта event вашей функции и вызова e.preventDefault(), если max достигнут?

var content_id = 'editable_div';  

max = 10;

//binding keyup/down events on the contenteditable div
$('#'+content_id).keyup(function(e){ check_charcount(content_id, max, e); });
$('#'+content_id).keydown(function(e){ check_charcount(content_id, max, e); });

function check_charcount(content_id, max, e)
{   
    if(e.which != 8 && $('#'+content_id).text().length > max)
    {
       // $('#'+content_id).text($('#'+content_id).text().substring(0, max));
       e.preventDefault();
    }
}

Хотя вам может понадобиться сделать немного больше, чтобы позволить пользователю делать что-то вроде "delete".


EDIT:

Добавлена ​​поддержка клавиши "delete".


ИЗМЕНИТЬ 2:

Кроме того, вы могли бы избавиться от обработчика keyup. keydown должно быть достаточно.

Ответ 2

Простой способ добиться этого:

<div onkeypress="return (this.innerText.length <= 256)" contenteditable="true">

Ответ 3

Во-первых, это раздражает пользователя: я бы предложил вместо этого сделать что-то похожее на поле комментария StackOverflow, которое позволяет вам вводить столько или меньше, как вам нравится, показывает вам сообщение о том, сколько персонажей вы 'напечатано и слишком ли много или слишком мало, и отказывается предоставить вам комментарий, длина которого недействительна.

Во-вторых, если вам действительно нужно ограничить длину текста, заменив все содержимое <div> на каждое нажатие клавиши, если содержимое слишком длинное, излишне дорого и сделает редактор невосприимчивым к более медленным машинам. Я предлагаю обработать событие keypress и просто запретить вставку символа с помощью preventDefault() в событие (или в IE, установив событие returnValue на true, при условии, что вы используете attachEvent). Это не помешает пользователю вставлять текст, поэтому вам нужно обработать событие paste (которого нет в Opera или Firefox < 3, так что вам понадобится какое-то решение на основе опроса для тех). Поскольку вы не сможете получить доступ к предварительно вставленному контенту, у вас не будет никакого способа узнать, приведет ли паста к личным ограничениям, поэтому вам нужно будет установить таймер, чтобы снова проверить длину после пасты. Все, что имеет место, первый вариант кажется мне предпочтительным.

Ответ 4

В следующем решении также рассматриваются управляющие ключи (которые соответствуют непечатаемым символам).

//Maximum number of characters
var max = 200;

$('#editable_div').keydown(function(e) {
    var keycode = e.keyCode;

    //List of keycodes of printable characters from:
    //http://stackoverflow.com/questions/12467240/determine-if-javascript-e-keycode-is-a-printable-non-control-character
    var printable = 
        (keycode > 47 && keycode < 58)   || // number keys
        keycode == 32 || keycode == 13   || // spacebar & return key(s) (if you want to allow carriage returns)
        (keycode > 64 && keycode < 91)   || // letter keys
        (keycode > 95 && keycode < 112)  || // numpad keys
        (keycode > 185 && keycode < 193) || // ;=,-./` (in order)
        (keycode > 218 && keycode < 223);   // [\]' (in order)

    if (printable) {
        //Based on the Bala Velayutham answer
        return $(this).text().length <= max; 
    }
});

Ответ 5

Это лучший способ сделать эту наиболее обобщенную форму и просто отлично работать для меня!

<div contenteditable="true" name="choice1" class="textfield" max="255"></div>
    $('.textfield').on("keypress paste", function (e) {
        if (this.innerHTML.length >= this.getAttribute("max")) {
            e.preventDefault();
            return false;
        }
    });

Ответ 6

Так я сделал это с помощью привязки jQuery, что упростило для меня, просто добавив длину данных свойства-данных в элемент редактирования контента. Просто добавьте код javascript в любом месте документа.

$(document).ready(function(){
	// Excempt keys(arrows, del, backspace, home, end);
	var excempt = [37,38,39,40,46,8,36,35];
	// Loop through every editiable thing
	$("[contenteditable='true']").each(function(index,elem) {
	    var $elem = $(elem);
	    // Check for a property called data-input-length="value" (<div contenteditiable="true" data-input-length="100">)
	    var length = $elem.data('input-length');
	    // Validation of value
	    if(!isNaN(length)) {
	    	// Register keydown handler
	        $elem.on('keydown',function(evt){
	        	// If the key isn't excempt AND the text is longer than length stop the action.
	            if(excempt.indexOf(evt.which) === -1 && $elem.text().length > length) {
	               evt.preventDefault();
	               return false;
	            }
	        });
	    }
	});
});
div {
  background-color:#eee;
  border: 1px solid black;
  margin:5px;
  width:300px;
  height:100px;
  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div contenteditable="true" data-input-length="100">
You can type a 100 characters here
</div>
<div contenteditable="true" data-input-length="150">
You can type a 150 characters here
</div>
<div contenteditable="true" data-input-length="10">
You can type a 10 characters here
</div>

Ответ 7

$("[contenteditable=true]").keydown(function(e) {
    var max = $(this).attr("maxlength");
    if (e.which != 8 && $(this).text().length > max) {
        e.preventDefault();
    }
});

Ответ 8

var onKeyPress = function () {
    var keyCode = window.event.keyCode,
        isNumeric = (keyCode > 47 && keyCode < 58),
        isNotEnterKey = !!(window.event.keyCode !== 13);

        (isNotEnterKey) || (this.blur());

        return (isNumeric && this.innerText.length < 3);
};

Ответ 9

Более обобщенная ревизия ответа @user113716, которая не работает для нескольких допустимых для контента полей (она подсчитывает общее количество символов для всех элементов, соответствующих данному идентификатору, поэтому вы можете вводить только макс. количество символов на странице).

Это решение позволяет использовать общий класс и независимо ограничивает количество символов в каждом разрешенном для контента поле.

html:

<div contenteditable="true" name="choice1" class="textfield"></div>

И JavaScript:

MAX_TEXTINPUT = 10;
TEXTFIELD_CLASS = "textfield"

$(document).ready(function() {

    //binding keyup/down events on the contenteditable div
    $('.'+TEXTFIELD_CLASS).keydown(function(e){ check_charcount(TEXTFIELD_CLASS, MAX_TEXTINPUT, e); });

})

function check_charcount(inputclass, max, e) {   
    var focused = $(document.activeElement)

    if(focused.hasClass(inputclass) && e.which != 8 && $(focused).text().length >= max)
    {
        e.preventDefault();
    }
}

Ответ 10

Если вы хотите, чтобы он работал с классами. Другими словами, элемент сможет совместно использовать имена классов и по-прежнему иметь свой собственный уникальный счет:

var content_id = '.myclass';  

max = 1;
//binding keyup/down events on the contenteditable div
$(content_id).keyup(function(e){ check_charcount(this, max, e); });
$(content_id).keydown(function(e){ check_charcount(this, max, e); });

function check_charcount(elem, max, e){   
    if(e.which != 8 && $(elem).text().length >= max){       
        e.preventDefault();
    }
}

Ответ 11

Другая версия ответа @user113716. Поддерживает событие "вставка" и некоторые текстовые горячие клавиши, такие как CTRL + A.

$('#'+content_id).on('keydown paste', function (e) { maxLimitForContenteditableDiv(e, 140) });

function maxLimitForContenteditableDiv(e, limit) {
    var allowedKeys = false;

    if (e.type === 'keydown') {
        allowedKeys = (
            e.which === 8 ||  /* BACKSPACE */
            e.which === 35 || /* END */
            e.which === 36 || /* HOME */
            e.which === 37 || /* LEFT */
            e.which === 38 || /* UP */
            e.which === 39 || /* RIGHT*/
            e.which === 40 || /* DOWN */
            e.which === 46 || /* DEL*/
            e.ctrlKey === true && e.which === 65 || /* CTRL + A */
            e.ctrlKey === true && e.which === 88 || /* CTRL + X */
            e.ctrlKey === true && e.which === 67 || /* CTRL + C */
            e.ctrlKey === true && e.which === 86 || /* CTRL + V */
            e.ctrlKey === true && e.which === 90    /* CTRL + Z */
        )
    }

    if (e.type === 'paste') {
        setTimeout(function () {
            $(e.target).text($(e.target).text().slice(0, limit));
        });
    }

    if (!allowedKeys && $(e.target).text().length >= limit) {
        e.preventDefault();
    }

Ответ 12

<div id="test" contenteditable="true" tabIndex="-1"></div>
  <p><span id="sy">0</span>/120</p> 
var flag = true;
 $('#test').on('compositionstart', function() {
        flag = false;
    });
    $('#test').on('compositionend', function() {
        flag = true;
    });
    $('#test').on('input', function() {
      setTimeout(function() {
        if (flag) {
          if($('#test').text().length>= 120) {
            setTimeout(() => {
              $('#test').text($('#test').text().substring(0, 120));
              var range = window.getSelection(); //创建range
              range.selectAllChildren(document.getElementById('test')); //range 选择obj下所有子内容
              range.collapseToEnd();
              $("#sy").text($('#test').text().length)
            }, 0);
          } else {
            $("#sy").text($('#test').text().length)
          }

        }
      }, 0);
    });