统计字数oninput?keyup?onchange?

在开发中,经常会遇到实时统计文本框或文本域中输入字符的个数,超过规定位数后禁止再输入。

输入字符限制

<div>
    <textarea name="content" id="content" cols="30" rows="10"></textarea>
    <p>剩余输入字符个数:<span>140</span></p>
</div>
// 字符输入区域
var content = document.querySelector("#content");
// 统计剩余字符数
var words = document.querySelector("p span");

首先我们可能想到onchange事件。

一、onchange事件

当元素的值发生改变时,会触发change事件。该事件仅适用于<input>, <select><textarea> 元素。当用于<select>元素时,change 事件会在选择某个选项时发生。当用于<input><textarea>时,该事件会在元素失去焦点时发生。

content.addEventListener("change", function(e){
    var numbers = this.value.length;
    if(numbers >= 140){
        e.preventDefault();
    }
    words.innerHTML = 140 - numbers;
});

结果:并不是我们想要的,因为只有失去焦点时,才能触发该事件!

二、keypress、keydown、keyup事件

用户按下键盘上的字符键(释放键盘上的键)时触发,任何可以获得焦点的元素都可以触发keypress事件,且按下任何能够影响文本显示的键时就会触发(例如回车键)。

content.addEventListener("keypress/keydown/keyup", function(e){
    console.log("被触发了!!!");
    var numbers = this.value.length;
    if(numbers >= 140){
        e.preventDefault();
    }
    words.innerHTML = 140 - numbers;
});

说明:在chrome51下测试结果

  • 按住某一字符键不放时,“keydown”会被重复触发,而“keypress”并不会触发;
  • esc、删除键、ctrl、shift等只会触发“keydown”事件,而“keypress”并不会触发;
  • 回车会同时触发“keydown”和“keypress”事件;
方法字数统计准确性是否可以控制个数是否限制粘贴情况
keydown不准确可以不完全可以
keypress不准确可以不可以(不触发)
keyup准确不可以不可以

问题
(1)keypress和keydown是在键盘按下时触发,此时var numbers = this.value.length;长度为0,所以会导致统计时差一个字符。
(2)粘贴情况下,keydown一次性超过指定位数(140)无法控制,keypress不会被触发;而keyup已后知后觉!!

三、oninput事件

oninput是HTML5的标准事件,对于检测<input><textarea>元素通过用户界面发生的内容变化非常有用,在内容修改后立即被触发。

The change event is fired for <input>, <select>, and <textarea> elements when a change to the element’s value is committed by the user. Unlike the input event, the change event is not necessarily fired for each change to an element’s value.

即oninput实时触发,onchange事件需要失去焦点才触发!!!

content.addEventListener("input", function(e){
    var numbers = this.value.length;
    if(numbers >= 140){
        // e.preventDefault();
        this.value = this.value.slice(0, 140);
    }
    words.innerHTML = 140 - numbers < 0 ? 0 : 140 - numbers;
});

e.preventDefault()不能取消input的行为,因为其e.cancelable为false,只有true的情况下才可以取消行为。

bool = event.cancelable

The result is a Boolean, which is true if the event can be canceled. bool contains true or false, depending on whether the event can have its default action prevented.

注意:IE下使用onpropertychange代替onchange。

$('textarea').bind('input propertychange', function() {}

四、textInput事件

只有可编辑区域才有该事件,用户按下能够输入实际字符的键时才会被触发(例如退格键不会触发)。在文本插入文本框之前触发,通常用于过滤敏感词。

content.addEventListener("textInput", function(e){
    var numbers = this.value.length;
    if(numbers >= 140){
        e.preventDefault();
    }
    words.innerHTML = 140 - numbers < 0 ? 0 : 140 - numbers;
}, false);

对粘贴控制不是很好!但textInput事件对于过滤敏感词汇很有作用!

content.addEventListener("textInput", function(event){
    // event.data的值是用户输入的字符
    console.log(event.data);
    var sensitiveWordAry = ["李", "刚"];
    if(sensitiveWordAry.indexOf(event.data) >= 0){
        // 输入的字符存在于敏感数组中,则禁止输入
        event.preventDefault();
    }
});

关于事件,请查看:事件

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奋飛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值