Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Контроль количества вводимых в форму символов (https://javascript.ru/forum/events/42334-kontrol-kolichestva-vvodimykh-v-formu-simvolov.html)

y0uix 22.10.2013 16:15

Контроль количества вводимых в форму символов
 
Здравствуйте, уважаемые форумчане!
Пишу форму обратной связи и хочу прикрутить счетчик вводимых символов. Найти и подключить jquery-плагин не проблема, - хочу сделать лаконично, производительно и с полным пониманием процесса. В главе про события клавиатуры тут в учебнике (пользуясь случаем хочу выразить глубокую благодарность его автору и переводчику) указан пример кода для простейшего случая -хочу его адаптировать для своего и не совсем получается.
Вот выдержки из кода с комментариями:
/* объявляю массив подстрок для последующей генерации айдишников полей формы (3 инпута и одна текстария), переменнную для текущего элемента и переменную для айдишников полей вывода числа символов */
var listTypes = ['name', 'email', 'theme', 'text'], currentElem, idCount;
function showCount(idCount, currentElem) {
        document.getElementById(idCount).innerHTML = currentElem.value.length;
    }
for ( var k = 0; k < 4; k++ ) {
        idCount = 'symbols_' + listTypes[k];
        currentElem = document.getElementById(listTypes[k] + '_item');
        currentElem.oncut = currentElem.onkeyup = currentElem.oninput = showCount(idCount, currentElem);
// закомментированный код тоже не работает, его пробовал 
// подставлять в выражение выше
//            function(idCount, currentElem) {
//            document.getElementById(idCount).innerHTML = currentElem.value.length;
//        };
        currentElem.onpropertychange = function(idCount, currentElem) {
            if (event.propertyName == "value") showCount(idCount, currentElem);
        };
    }

Причем в финальном варианте работает но очень криво, не происходит измменений счетчика по мере введения символов.

Подскажите пожалуйста что я делаю не так и как лучше сделать, спасибо.

danik.js 22.10.2013 16:31

1) Нужно навешивать обработчик на oninput (остальные события, такие как oncut onkeyup и тд будут удваивать / утраивать обработку), а при отсутсвтии (IE8) - onpropertychange
2) В свойство oninput нужно записать ссылку на функцию-обработчик. А ты чего делаешь?

Цитата:

Сообщение от y0uix
currentElem.oninput = showCount(idCount, currentElem);

Ты вызываешь функцию showCount и присваиваешь ее результат, то есть undefined (так как она ничего не возвращает). Какой в этом прок?
Во втором варианте уже лучше, но функция-обработчик не получает такие аргументы, какие ты предположил. Ты получишь только один аргумент - объект события типа Event)

danik.js 22.10.2013 17:29

Цитата:

Сообщение от Poznakomlus
файлы называйте image1.jpg, image2.jpg... до 20

А это к чему тут?
Цитата:

Сообщение от Poznakomlus
Даниил, а так

А так не все методы ввода обрабатываются. Хотя в большинстве случаев это не критично. Ну и непонятно зачем preventDefault() звать.

y0uix 22.10.2013 18:51

danik.js, Poznakomlus спасибо, ваши выкладки прояснили для меня ситуацию. Проблему кажется решил, вот код, может кому-то поможет (не без примеси jQuery, связанное однако с тем, что ее я все равно подключаю и хотелось поиск элемента сделать кроссбраузерно).
// у меня четыре текстовых элемента, как я уже писал
objInputElems = {
            inputElemName: document.getElementById('name_item'),
            inputElemEmail: document.getElementById('email_item'),
            inputElemTheme: document.getElementById('theme_item'),
            inputElemText: document.getElementById('text_item')
        };
function showCount() {
        $(this).prev().find('span').text(this.value.length);
    }
    for ( var key in objInputElems ) {
        if (objInputElems.hasOwnProperty(key)) {
            objInputElems[key].oninput = showCount;
            objInputElems[key].onpropertychange = function() {
                if (event.propertyName == "value") showCount();
            };
        }
    }

Хотелось бы услышать еще дельных советов, может быть по оптимизации кода... Спасибо этому сайту.

danik.js 22.10.2013 19:12

Раз пошла такая пьянка...

var selectors = ['#name_item', '#email_item', '#theme_item', '#text_item'];
$(selectors.join()).on('input propertychange', function(event){
  $(this).prev().find('span').text(this.value.length);
});


Думаю ничего страшного если не проверять propertyName, тем более что в IE9+ обработка все равно будет вызываться дважды (input+propertychange)


Часовой пояс GMT +3, время: 04:29.