jQuery字符计数异常:keyup不兼容弹窗,keydown计数错误
字符计数功能的问题修复方案
问题说明
为应用中所有带字符限制的input[type="text"]和textarea实现字符计数时,遇到两个问题:
- 使用
keyup事件时,计数显示正常,但应用内弹窗向导中的输入框无法触发该功能 - 改用
keydown事件后,输入过程中计数数值错误(总是慢一步)
原代码
<div> <input type="text" /> <textarea></textarea><label class="input_label w-100 text-right" style="font-size:11px ;"></label> </div> <hr/> <div> <input type="text" /> <textarea></textarea><label class="input_label w-100 text-right" style="font-size:11px ;"></label> </div> <hr/>
$(document).on('keydown','input[type="text"],textarea ',function(){ tag_name = $(this).prop("tagName") if(tag_name == 'TEXTAREA'){ limit = 200 limit_warning = 179 $(this).attr('maxlength',200,) } else{ limit = 20 limit_warning = 15 $(this).attr('maxlength',20,) } this_vall = $(this).val() length_count = this_vall.length var text_field = length_count + "/" + limit; label_tag = $(this).siblings('label') is_label_exist = label_tag.length if(is_label_exist <1){ x = ` <label class="input_label w-100 text-right" style="font-size:11px ;">${text_field}</label>` $(this).parent().append(x) $(label_tag).text(text_field) } else{ $(label_tag).text(text_field) } })
问题原因
- keydown事件计数错误:
keydown在按键按下时触发,此时输入的字符还未写入输入框的value属性,计算的是输入前的长度,导致计数比实际少1 - keyup事件弹窗失效:若弹窗是动态生成的,未用事件委托的
keyup绑定无法监听动态元素;同时keyup无法覆盖粘贴、拖拽输入等非键盘触发的输入行为
修复方案
改用input事件,它能监听所有输入内容变化(键盘输入、粘贴、拖拽等),且在value更新后触发,计数准确;保留事件委托确保动态弹窗元素生效,同时优化代码逻辑:
修正后的代码
// 绑定输入事件,覆盖所有输入场景 $(document).on('input', 'input[type="text"], textarea', function() { const $input = $(this); const tagName = $input.prop('tagName').toUpperCase(); // 定义字符限制参数,仅首次设置maxlength let limit, limitWarning; if (tagName === 'TEXTAREA') { limit = 200; limitWarning = 179; !$input.attr('maxlength') && $input.attr('maxlength', limit); } else { limit = 20; limitWarning = 15; !$input.attr('maxlength') && $input.attr('maxlength', limit); } const currentLength = $input.val().length; const countText = `${currentLength}/${limit}`; // 处理计数标签的生成与更新 let $label = $input.siblings('.input_label'); if (!$label.length) { $label = $(`<label class="input_label w-100 text-right" style="font-size:11px;">${countText}</label>`); $input.parent().append($label); } else { $label.text(countText); } // 可选:接近限制时添加警告样式 $label.css('color', currentLength > limitWarning ? '#dc3545' : ''); }); // 页面初始化时触发一次,确保已有内容的输入框显示正确计数 $(function() { $('input[type="text"], textarea').trigger('input'); });
优化点说明
- 用
input事件替代keyup/keydown,覆盖所有输入场景且计数准确 - 仅在元素无
maxlength属性时才设置,避免重复DOM操作 - 缓存jQuery对象,减少重复DOM查询
- 加入警告样式逻辑,提升用户体验
- 页面初始化时触发事件,确保已有内容的输入框计数正确
内容的提问来源于stack exchange,提问作者thrinuu
相关产品推荐
相关产品推荐

