转载--经验总结:应对中文输入法的字符串截断方案(带代码示例)

本文转自:http://www.cnblogs.com/chyingp/p/3599641.html

遇到这么个需求,允许用户修改自己的名片,名片最大长度支持8个汉字(24个字节),当用户输入超过8个汉字,则不允许用户继续输入。

最初的思路:oninput你好

很常见的需求,觉得驾轻就熟,监听input事件,当输入内容发生变化的时候,获得用户输入内容,并进行截断操作(如果超出的话)。主要代码如下。一切显得那么美好,直到中文输入法出现。

ps:本文用例均在 chrome 版本 33.0.1750.146下测试

$(‘#text‘).on(‘input‘, function() {
    var value = $(this).val();
    if(Str.byteLen(value, 3)>24){
        $(this).val(Str.getMaxlen(value, 24));
    }
});

完整代码如下,有兴趣可以看下:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>demo</title>

</head>
<body>
    <input id="text" placeHolder="最大支持24个字节" />
    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript">
     var Str = {
         byteLen : function (str, len){
            //正则取到中文的个数,然后len*count+原来的长度。不用replace
            var factor = len || 2;
            str += ‘‘;
            var tmp = str.match(/[^\x00-\xff]/g) || [];

            var count = tmp.length;
            return str.length + (factor-1)*count;
        },
        getMaxlen : function(str,maxlen){
            var sResult = ‘‘, L=0, i=0, stop = false, sChar;
            if(str.replace(/[^\x00-\xff]/g,‘xxx‘).length <= maxlen){
                return str;
            }
            while(!stop){
                sChar = str.charAt(i);
                //sResult+=sChar;
                L+= sChar.match(/[^\x00-\xff]/) !== null ? 3 : 1;

                if(L > maxlen){
                    stop = true;
                }else{
                    sResult+=sChar;
                    i++;
                }
            }
            return sResult;
        }
    };
    $(‘#text‘).on(‘input‘, function() {
        var value = $(this).val();
        if(Str.byteLen(value, 3)>24){
            $(this).val(Str.getMaxlen(value, 24));
        }
    });
    </script>
</body>
</html>

oninput的局限:中文输入法带来的难题

上面的解决方案对于普通的文本输入,如英文字母、数字等的输入是ok的。但当用户通过中文输入法(比如QQ拼音)时,就会遇到一些问题,我们简单改下上面的代码,看看究竟会有什么问题。就加多了个log打印。

$(‘#text‘).on(‘input‘, function() {
    var value = $(this).val();
    console.log(‘当前输入:‘+value);  // 打印当前输入的值
    if(Str.byteLen(value, 3)>24){
        $(this).val(Str.getMaxlen(value, 24));
    }
});

下面是输入过程中的截图。可以看到,用户使用中文输入法输入的过程中,“input”事件被不断地触发着,这会带来什么问题呢?相信你已经想到了——会导致程序对当前用户输入字符实际长度的误判。比如用户输入“程序猿”三个汉子,实际占用9个字节,但对上面的程序来说,取到的字节数为"chengxuyuan".length == 11。在用户输入达到边界值时,就会莫名其妙地将用户的输入截断,导致中文输入无法接续(感兴趣的同学可以自己试下)

解决思路一:compositionstart、compositionend

在万能的幼稚园群里抛出问题后,有个兄弟提出了个方案:可以采用compositionstart、compositionend来捕获IME(input method editor)的启动和关闭事件。说实话,这两事件听都没听过,但既然有这么个解决方案,暂且试一下,再次修改代码

$(‘#text‘).on(‘input‘, function() {
    if($(this).prop(‘comStart‘)) return;    // 中文输入过程中不截断

    var value = $(this).val();
    console.log(‘当前输入:‘+value);
    if(Str.byteLen(value, 3)>24){
        $(this).val(Str.getMaxlen(value, 24));
    }
}).on(‘compositionstart‘, function(){
    $(this).prop(‘comStart‘, true);
    console.log(‘中文输入:开始‘);
}).on(‘compositionend‘, function(){
    $(this).prop(‘comStart‘, false);
    console.log(‘中文输入:结束‘);
});

输入过程截图如下,可以看到,当compositionstart事件触发,就停止对输入字符的截断操作,而是耐心等待用户输入的结束

按下空格键,中文输入结束,此时再去进行字符长度的判读和截断

未完的探索

正如正文最前面强调的,本文的用例都是在chrome特定版本下进行测试,显然compositionstart、compositionend并不是一个兼容所有浏览器的方案。包括jQuery的“input”事件都是内部做了一堆兼容性处理的。假如这个需求是要兼容所有主流浏览器的话就真跪了,虽然这个迟早有一天会变成残酷的现实。

所以呢,探索还将继续:是否有兼容所有主流浏览器的方案,求路过的兄弟们支招。

时间: 2024-08-10 23:13:40

转载--经验总结:应对中文输入法的字符串截断方案(带代码示例)的相关文章

[转载]IE6、IE7、IE8、Firefox兼容性CSS HACK代码+示例 —— 浏览器

1.区别IE和非IE浏览器CSS HACK代码  #divcss5{background:blue; /*非IE 背景藍色*/background:red \9; /*IE6.IE7.IE8背景紅色*/} 2.区别IE6,IE7,IE8,FF CSS HACK [区别符号]:「\9」.「*」.「_」[示例]:  #divcss5{background:blue; /*Firefox 背景变蓝色*/background:red \9; /*IE8 背景变红色*/*background:black;

输入框文本输入限制问题以及中文输入法下字符阶段的处理

输入框文本字数限制问题以及中文输入法下字符截断处理 上次博文写过处理实时获取输入表单的值,传送门: 博文地址.这次又需要处理输入框文本字数限制问题,前期的步骤思想其实就是要先实时获取输入框的值然后得到长度. 使用onkeyup判断字符长度 可以参考我前面写的博文,地址如上.onkeyup确实是可以做到实时获取的效果,因此我就是使用键盘事件来达到效果.HTML代码: <div class="content"> <textarea name="complain&

Ubuntu14.04安装中文输入法以及解决Gedit中文乱码问题[转载]

转载自:http://www.cnblogs.com/zhcncn/p/4032321.html 写在前面:解决gedit 在txt文件格式出现乱码的问题,在我自己的操作中是需要把系统设置成中文显示环境的,不然这个问题没有解决.----tips by chsry. 1 设置中文显示环境 1. 打开System Settings 2. 打开Personal-> Language Support. 会弹出如下对话框,提示你“语言支持没安装完整”. 点击“Remind Me Later”. 3. 在“

centos6.4中文输入法安装和切换(转载)

centos6.4中文输入法安装和切换(转载) 1.用root登录,或者切换到root账户(su root): 2.yum install "@Chinese Support"; 3.exit: 4.System→preferences→input method:(如果没有,注销用户重新登录系统重试) 5.在input method中,使用add选项选择合适的中文输入法: 6.注销账户,重新登录. over 中英文输入法切换快捷键为Ctrl+Space

ubuntu14.04英文环境下安装中文输入法(转载)

ubuntu14.04英文环境下安装中文输入法(转载) 摘要 搭建ubuntu用作开发,所以不想用中国定制的麒麟版,定制了太多东西,虽然已经装好中文输入法.下面总结在ubuntu14.04英文环境下安装中文输入法. ubuntu ubuntu拼音输入法 pinyin ubuntu默认的输入法是ibus,综合网上评论,fcitx的支持者更多,而且个人感觉fcitx也的确不错,可以满足日常输入. STEP1: 在Ubuntu Software Center 搜索fcitx,安装fcitx输入法框架,

Ubuntu 12.04 LTS 中文输入法的安装 (转载)

第一步:安装语言包 进入 “System Settings” 找到 “Language Support” 那一项,点击进入 选择 “Install/Remove Languages” 找到 “Chinese (simplified)” 那一项,把后面到勾打上 然后点击 “Apply Changes” 等待一段时间即可 第二步:安装 Ibus 框架 调出 terminal 终端,输入命令: sudo apt-get install ibus ibus-clutter ibus-gtk ibus-g

Ubuntu 17.04安装安装ibus中文输入法[转载]

Ubuntu 16.04安装安装ibus中文输入法 Ubuntu16.04安装时,当初觉得自己英文还行,就安装了英文版的:结果安装完后,发现并没有中文输入功能.于是搜索一些安装中文输入法的方法.看网上很多都是安装的ibus pinyin输入法. 步骤: 1.安装Chinese语言包 鼠标依次点击System Settings–>Language Support–>Install/Remove Languages选中Chinese,点击Apply应用即可,等待下载安装完成.如下图: 这里完成的只

【转载】Ubuntu 12.04 LTS 中文输入法的安装

原文地址 :  http://www.cnblogs.com/zhj5chengfeng/archive/2013/06/23/3150620.html 我装的是英文版的 Ubuntu12.04,如果安装中文版,会自动安装中文输入法,这篇文章也是为了以后重装 Ubuntu 做一个准备 废话不多说,进入正题: 第一步:安装语言包 进入 “System Settings” 找到 “Language Support” 那一项,点击进入 选择 “Install/Remove Languages” 找到

Ubuntu 14.04 DNS 丢失 | 中文输入法配置 (转载)

1)彻底解决Ubuntu 14.04 重启后DNS配置丢失的问题: http://www.tuicool.com/articles/RVZn2y 2)Ubuntu 14.04中文输入法的安装   http://sixipiaoyang.blog.163.com/blog/static/623235882014450916276/