关于javascript实时显示textarea剩余字符数

今天在百度的项目中碰到一个问题,就是实现javascript实时显示textarea剩余字符数的 功能,咋一看,这个功能也太简单了吧,一般都是只用keydown和keyup事件监听textarea的字符数就可以了,但是QA检测需要支持鼠标右键 的相关事件(包括粘贴,撤销,删除和剪切等),而且要求鼠标直接拖动文字至textarea中也要实时改变字数,由于这些方法没有直接按键盘,所以光 keydown和keyup事件监听是不够的。
此时就需要用onpropertychange事件了,该事件与onchange事件存在本质区别,onpropertychange事件是当控件里的内容一改变马上触发事件(注意:onpropertychange事件仅限于使用在普通的html上,使用过struts的html:textarea 标签的不包含该事件,否则会报错),但是onpropertychange是IE专享的,而且好像不能用attachEvent绑定,而要直接obj.onpropertychange = fun;其他浏览器需要用oninput事件替代。
一个简单的demo:

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>无标题文档</title>
</head>
<body>
<textarea name="" id="textarea"></textarea>
<p id="remain"></p>
<script type="text/javascript">
var textareaObj=document.getElementById("textarea"),
    remainObj=document.getElementById("remain"),
    num=0;
if(/msie/i.test(navigator.userAgent)){
    textareaObj.onpropertychange=function(){
        num=1000-this.value.length;
        remainObj.innerHTML="剩余"+num+"字";
    }    
}
else{
    textareaObj.oninput=function(){
        num=1000-this.value.length;
        remainObj.innerHTML="剩余"+num+"字";
    }
}
</script>
</body>
</html>

上面这个demo支持FF,chrome、ie7和safari所有的事件,包括键盘的输入、删除和直接鼠 标拖入,也可以鼠标右键里面的粘贴、删除、撤销和剪切等,opera也支持这些事件,但是不支持鼠标直接拖入,ie8,ie9不支持鼠标的右键事件(除了 粘贴)。ie9支持键盘输入,不支持键盘删除。
onpropertychange事件没法直接鼠标右键里面的删除和撤销等事件,而且也没办法直接监听这些事件,不像鼠标右键的剪切粘贴和直接拖动等能够用onpaste、oncut和ondrop监听,所以这方面还没找到有效的办法,如果有童鞋知道,请告知,万分感激!
demo:

/*计算剩余字符,base.remainWord("#textarea",10,"#wordsNum");*/
    remainWord:function(textareaId, totalNum, remainId) {
        /*
        textareaId:代表textarea的ID;
        totalNum:代表可输入的总共的字符数;
        remainId:显示剩余字符数的ID;
        */
        $(textareaId).each(function() {
            var self = $(this), remainObj = $(remainId), num = 0;
            function fun() {
                num = totalNum - self.val().length;
                if (num >= 0) {
                    remainObj.css("color", "#828181").html("剩余" + num + "个字");
                    self.removeClass("error");
                } else {
                    remainObj.css("color", "#f00");
                    self.addClass("error").val(self.val().substring(0, totalNum));
                }
                if (self.val() == "") {
                    self.prev("label").html("请输入想要说的问题,们会及时给您反馈。");
                } else {
                    self.prev("label").html("");
                }
            }
            //ie用onpropertychange事件,IE9不支持鼠标右键里面的删除,onpropertychange不支持很多事件,需要单独写
            if (/msie/i.test(navigator.userAgent)) {
                self[0].onpropertychange = fun;
                self.keydown(fun);
                self.keyup(fun);
                base.bindEvent(self[0], "paste", function() {
                    setTimeout(fun, 100);
                });
                base.bindEvent(self[0], "cut", function() {
                    setTimeout(fun, 100);
                });
            } else {
                base.bindEvent(self[0], "input", fun);
            }
            //opera和IE拖动事件
            if (/opera/i.test(navigator.userAgent) || /msie/i.test(navigator.userAgent)) {
                //防止用户拖动内容到输入框
                base.bindEvent(self[0], "drop", function() {
                    setTimeout(fun, 100);
                });
                base.bindEvent(self[0], "dragend", function() {
                    setTimeout(fun, 100);
                });
            }
        });
    },

最终解决方式如下:

/*检测字数通用fun*/
    checkWord: function(obj, fun, speed) {
        //部分ie中的onpropertychange事件并不能检测鼠标右键的删除和撤销等事件,opera的oninput事件不能检测直接拖动内容到textarea事件drop&&dragend,故这利用定时器解决
        if (base.browser() == "ie6" || base.browser() == "ie7" || base.browser() == "ie8" || base.browser() == "ie9" || base.browser() == "opera") {
            var timer;
            $(obj).focus(function() {
                timer = setInterval(fun, speed);
            });
            $(obj).blur(function() {
                clearInterval(timer);
            });
        }
        //FF,Chrome,safari等浏览器可以利用oninput事件监听所有的事件,包括keydown,keyup,鼠标右键中的cut,paste和删除,撤销等所有事件,包括直接拖动drop等也支持
        else {
            base.bindEvent(obj, "input", fun);
        }
    },
    /*计算剩余字符,base.remainWord("#textarea","#wordsNum");*/
    remainWord: function(textareaId, remainId) {
        /*
		textareaId:代表textarea的ID;
		remainId:显示剩余字符数的ID;
		*/
        $(textareaId).each(function() {
            var self = $(this),
            	remainObj = $(remainId),
            	num = 0;
            function fun() {
                num = base.totalNum - self.val().length;
                if (num > 0) {
                    remainObj.css("color", "#828181").html("剩余" + num + "个");
                    self.removeClass("error");
                    if (num == base.totalNum) {
                        remainObj.html("最多" + base.totalNum + "字");
                    }
                } else {
                    remainObj.css("color", "#f00").html("剩余0个");
                    self.addClass("error");
                    //防止ie下输入全部内容后不能ctrl+a全选
                    if (num != 0) {
                        self.val(self.val().substring(0, base.totalNum));
                        //防止输入全部内容后能在前面输入字符,同时删除了后面的字符
                        self.unbind("keydown");
                        self.keydown(function(event) {
                            //排除一些删除按钮和方向按钮等,getTextareaSelectVal是为了当选择textarea一部分内容后,就可以输入内容,否则不能输入,self.val().length >= base.totalNum是为了删除textarea一部分内容后,能够重新输入
                            if (! (event.keyCode == 8 || event.keyCode == 9 || event.keyCode == 46 || event.keyCode == 37 || event.keyCode == 38 || event.keyCode == 39 || event.keyCode == 40 || event.ctrlKey && event.keyCode == 65 || getTextareaSelectVal()) && self.val().length >= base.totalNum) {
                                return false;
                            }
                        });
                        //防止输入全部内容后用户拖动内容到输入框
                        self[0].ondrop = function() {
                            if (self.val().length >= base.totalNum) {
                                return false;
                            }
                        };
                        //防止输入全部内容后用户鼠标右键粘贴内容到输入框
                        self[0].onpaste = function() {
                            if (self.val().length >= base.totalNum && !getTextareaSelectVal()) {
                                return false;
                            }
                        };
                        //获取所选文本的开始和结束位置
                        function getPositions() {
                            var x = 0,
                            y = 0,
                            val = self[0].value;
                            x = self[0].selectionStart;
                            y = self[0].selectionEnd;
                            return {
                                "val": val,
                                "x": x,
                                "y": y
                            };
                        }
                        //获取textarea中选择的文本
                        function getTextareaSelectVal() {
                            if (window.getSelection) {
                                //Firefox,Chrome,Safari,opera etc
                                return getPositions().val.substring(getPositions().x, getPositions().y).length > 0;
                            } else if (document.selection) {
                                //IE,IE下可以直接获取,不必利用开始和结束位置截取
                                return document.selection.createRange().text.length > 0;
                            }
                        }
                    }
                }
                if (self.val() != "") {
                    self.prev("label").html("");
                }
            }
            base.checkWord(self[0], fun, 100);
        });
    },
时间: 2024-10-02 01:01:34

关于javascript实时显示textarea剩余字符数的相关文章

textarea限制字符数

html代码: 1 <div class="remark_edit J_Remark_Edit"> 2 <div class="tip-body"> 3 <h4>备注信息:</h4> 4 <textarea cols="44">请输入备注信息</textarea> 5 </div> 6 <div class="tip-ctrl">

JS(javascript)动态判断输入文本框剩余可输入字符数

一.描述 我们在空间中发表状态,当我们输入一个字符,上面的剩余可输入字符数就会减一,直到输入的字符数达到之前设定的最大数量为止,效果如下图所示: 二.实现方法 首先,我们先确定文本框内的最大可输入长度,其次在输入一个字符抬起键盘的时候对输入文本框中的字符长度进行验证,并在动态显示在剩余可输入字符数中. 三.源代码 <%@ page language="java" pageEncoding="UTF-8"%> <%@ taglib uri="

统计Textarea的输入字符数

HTML代码: <div class="item-textarea">     <textarea></textarea>     <span>还可以输入<i>500</i>个文字</span> </div> CSS代码: .item-textarea{     position: relative; } .item-textarea textarea{     width: 100%;  

文本域textarea显示输入剩余字数

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf

JS显示指定字符数,避免一个中文两个字符的情况

0x00 level: 0x01 0x01 代码如下: <html> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <body> <script type="text/javascript"> var txt = "Aa要a国a啊b不a"; document.write("&l

每天一个JavaScript实例-处理textarea中的字符成每一行

<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>每天一个JavaScript实例-处理textarea中的字符成每一行</title> <script> function clicka(){ console.log("aaa"); var aa = document.get

JavaScript实现页面实时显示时间

今天尝试了一下JavaScript实现页面实时显示时间 运用了 setInterval() 函数 setInterval() 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式 setInterval("getTime()",1000); 以1000毫秒间隔调用函数有一个问题就是刚打开页面时的1s会不显示 为此我们可以在之前先调用一遍函数 getTime(); 这样无论何时都能实时显示时间啦 .html代码如下 <!DOCTYPE html> <html lang

【Excle数据透视表】如何调整压缩形式显示下的缩进字符数

调整前:                                                                                                              调整后:                     解决办法: 通过数据透视表选项设置缩进字符数 步骤 单击数据透视表任意单元格→数据透视表工具→分析→选项→压缩表单中缩进标签设置为0→确定 当改变缩进字符数量时,仅影响当前数据透视表内所有行字段的缩进 以压缩表形式缩进行标

对于限制UITextView输入的字符数

对于限制UITextView输入的字符数.相信大家在网上见得最多的是实现UITextViewDelegate 摘自:方法 http://www.it165.net/pro/html/201505/39736.html 1.- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range 2.replacementText:(NSString *)text;//有输入时触但对于中文键盘出示的联想字选择时不会