统计字数oninput?keyup?onchange?

Posted 奋飛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了统计字数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();
    }
});

关于事件,请查看:事件

以上是关于统计字数oninput?keyup?onchange?的主要内容,如果未能解决你的问题,请参考以下文章

oninput,onpropertychange,onchange的用法和区别

input的onchange 和oninput事件

oninput与onchange比较

input输入框的oninput和onchange事件

如何制作使用 oninput 而不是 onchange 绑定的 EditForm 输入?

[TimLinux] JavaScript input框的onfocus/onblur/oninput/onchange事件介绍