javascript 使用 jQuery 计算字符/短信

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4705185/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 14:35:06  来源:igfitidea点击:

Count characters/sms using jQuery

javascriptjquery

提问by Upvote

I count characters using NobleCountand the following code:

我使用NobleCount和以下代码计算字符:

$('#message').NobleCount('#messageInfo',{
            max_chars: getMaxChars(),
            on_negative: function(t_obj, char_area, c_settings, char_rem){

            }
});

I want a feature like counting SMS, if the limit is reached the next 160 chars are for the second sms and so on. I can use parameters like on_update, on_positive, on_negative and block_negative.

我想要一个功能,比如计算 SMS,如果达到限制,接下来的 160 个字符将用于第二条短信,依此类推。我可以使用 on_update、on_positive、on_negative 和 block_negative 等参数。

I tried something using modulo but it does not work. Any ideas?

我尝试了一些使用模的东西,但它不起作用。有任何想法吗?

回答by Craig McQueen

Beware that SMS is more complicated than you seem to indicate.

请注意,短信比您似乎表示的要复杂。

Standard "160-character" SMS uses a strange 7-bit encodingthat covers most ASCII, some European accents, misc symbols such as , some capital Greek letters (the ones that don't look like Roman characters).

标准的“160 个字符”SMS 使用一种奇怪的 7 位编码,它涵盖了大多数 ASCII、一些欧洲口音、杂项符号,例如 、一些大写希腊字母(那些看起来不像罗马字符的字母)。

If your message uses other characters, it can instead be encoded as Unicode using UCS-2 (like UTF-16 but only BMP), for a limit of 70 characters. Actually, the specification saysUCS-2, but emoji (non-BMP Unicode) can be sent in SMS so that implies UTF-16 isbeing used, in which case each emoji must "use up" 2 characters out of the 70 total.

如果您的消息使用其他字符,则可以使用 UCS-2(如 UTF-16 但仅 BMP)将其编码为 Unicode,限制为 70 个字符。实际上,本说明书中表示UCS-2,但表情符号(非BMP Unicode)的可在SMS所以UTF-16暗示要发送被使用,在这种情况下,每个表情符号必须“用完” 2个字符出来的总共70个的。

But some languages can use "national language shift tables"which use an alternative7-bit encoding. Most notably Turkish, but also Spanish, Portuguese, and ten Indian sub-continent languages. These are relatively new additions to the standard.

但是有些语言可以使用“国家语言转换表”,它使用替代的7 位编码。最著名的是土耳其语,还有西班牙语、葡萄牙语和十种印度次大陆语言。这些是标准的相对较新的补充。

Even in the 7-bit encoding, a few characters are "escaped" which means they "use up" 2 characters. In the default 7-bit encoding, these are: {}[]\|^~.

即使在 7 位编码中,也有一些字符被“转义”,这意味着它们“用完”了 2 个字符。在默认的 7 位编码中,它们是:{}[]\|^~.

If your message goes beyond 160 characters, it can use "concatenated SMS", but then a small header is added to each message, meaning each segment only has room for something like 153 characters. There are two different versions of that header, of different sizes, thus it may not be 153 characters, but 152 (from memory). Similarly for Unicode concatenated SMS, the small header makes it 67 characters per segment.

如果您的消息超过 160 个字符,它可以使用“串联 SMS”,但随后会在每条消息中添加一个小标题,这意味着每个段只能容纳 153 个字符。该标题有两个不同版本,大小不同,因此它可能不是 153 个字符,而是 152 个(来自内存)。同样,对于 Unicode 串联 SMS,小标题使其每段 67 个字符。

Good luck with all that!

祝你一切顺利!

回答by lonesomeday

Firstly, character counting is very easy. You just need to use the lengthproperty on a string. To count the number of SMS messages needed, you'll need to divide by 160 and round up (because 161 characters requires 2 messages). Your code should probably look something like this:

首先,字符计数非常容易。您只需要length在字符串上使用该属性。要计算所需 SMS 消息的数量,您需要除以 160 并向上取整(因为 161 个字符需要 2 条消息)。您的代码可能看起来像这样:

HTML:

HTML:

<textarea name="message" value="" id="message"></textarea>
<p>
    <span id="remaining">160 characters remaining</span>
    <span id="messages">1 message(s)</span>
</p>

jQuery:

jQuery:

$(document).ready(function(){
    var $remaining = $('#remaining'),
        $messages = $remaining.next();

    $('#message').keyup(function(){
        var chars = this.value.length,
            messages = Math.ceil(chars / 160),
            remaining = messages * 160 - (chars % (messages * 160) || messages * 160);

        $remaining.text(remaining + ' characters remaining');
        $messages.text(messages + ' message(s)');
    });
});

See jsFiddle example.

请参阅 jsFiddle 示例。

回答by sulest

Here is small plugin for you. It is my first jQuery plugin i give it for free ;) you just need to start it with:

这是给你的小插件。这是我免费提供的第一个 jQuery 插件;) 你只需要启动它:

$('#smsText').smsArea();

The HTML:

HTML:

 <b id="smsCount"></b> SMS (<b id="smsLength"></b>) Characters left
 <textarea id="smsText"></textarea>

The Javascript (updated 18.8.2014):

Javascript(2014 年 8 月 18 日更新):

(function($){
    $.fn.smsArea = function(options){

    var
    e = this,
    cutStrLength = 0,

    s = $.extend({

        cut: true,
        maxSmsNum: 3,
        interval: 400,

        counters: {
            message: $('#smsCount'),
            character: $('#smsLength')
        },

        lengths: {
            ascii: [160, 306, 459],
            unicode: [70, 134, 201]
        }
    }, options);


    e.keyup(function(){

        clearTimeout(this.timeout);
        this.timeout = setTimeout(function(){

            var
            smsType,
            smsLength = 0,
            smsCount = -1,
            charsLeft = 0,
            text = e.val(),
            isUnicode = false;

            for(var charPos = 0; charPos < text.length; charPos++){
                switch(text[charPos]){
                    case "\n": 
                    case "[":
                    case "]":
                    case "\":
                    case "^":
                    case "{":
                    case "}":
                    case "|":
                    case "":
                        smsLength += 2;
                    break;

                    default:
                        smsLength += 1;
                }


                if(text.charCodeAt(charPos) > 127 && text[charPos] != "") isUnicode = true;
            }

            if(isUnicode){
                smsType = s.lengths.unicode;

            }else{
                smsType = s.lengths.ascii;
            }

            for(var sCount = 0; sCount < s.maxSmsNum; sCount++){

                cutStrLength = smsType[sCount];
                if(smsLength <= smsType[sCount]){

                    smsCount = sCount + 1;
                    charsLeft = smsType[sCount] - smsLength;
                    break
                }
            }

            if(s.cut) e.val(text.substring(0, cutStrLength));
            smsCount == -1 && (smsCount = s.maxSmsNum, charsLeft = 0);

            s.counters.message.html(smsCount);
            s.counters.character.html(charsLeft);

        }, s.interval)
    }).keyup()
}}(jQuery));

DEMO: http://jsfiddle.net/t32h0gj4/1/

演示:http: //jsfiddle.net/t32h0gj4/1/

NOTE: there are some basic options

注意:有一些基本选项

$('#smsText').smsArea({cut:false}); //Do not cut the SMS
$('#smsText').smsArea({maxSmsNum:2}); //2 SMS Max

回答by TechNyquist

Once the message has been decoded as Craig McQueen stated in a this thread post and you have your actual character count, to count the needed SMS amount the following is enough:

一旦消息按照 Craig McQueen 在此线程帖子中所述被解码并且您拥有实际字符数,要计算所需的 SMS 数量,以下内容就足够了:

function cntsms(len){ return len<=0? 0: (len>160? Math.ceil(len/153): 1); }

...I like one-row solutions so much.

...我非常喜欢单排解决方案。

回答by Osama Abdulsattar

I think the following script can produce more accurate calculation of SMS parts:

我认为以下脚本可以更准确地计算 SMS 部分:

//field: a text box that contains the SMS Text
//cntField: a text box that will contain the remaining count of characters for each part
//smsCntfield: a text box that will contain the count of parts
//lang: 0 for English, 2 for Arabic
//maxLimit: Maximum count of characters to limit the TextBox, (ex: for 5 SMS in Arabic 331, in English 762
function textCounter(field, cntfield, smsCntfield, lang, maxlimit) {

    part1Count = 0;
    part2Count = 0;
    part3Count = 0;
    part4Count = 0;
    part5Count = 0;
    if (lang == 2) {
        // Arabic
        part1Count = 70;
        part2Count = 63;
        part3Count = 66;
        part4Count = 66;
        part5Count = 66;
    } else if (lang == 0) {
        // English
        part1Count = 160;
        part2Count = 145;
        part3Count = 152;
        part4Count = 152;
        part5Count = 152;
    }

    smsCount = 0;
    smsCharCnt = 0;
    smsTotalCount = 0;

    if (field.value.length <= part1Count) {
        smsCount = 1;
        smsCharCnt = part1Count;
        smsTotalCount = part1Count;
    } else if (field.value.length <= (part1Count + part2Count)) { 
        smsCount = 2;
        smsCharCnt = part2Count;
        smsTotalCount = (part1Count+part2Count);
    } else if (field.value.length <= (part1Count+part2Count+part3Count)) {
        smsCount = 3;
        smsCharCnt = part3Count;
        smsTotalCount = (part1Count+part2Count+part3Count);
    } else if (field.value.length <= (part1Count+part2Count+part3Count+part4Count)) { 
        smsCount = 4;
        smsCharCnt = part4Count;
        smsTotalCount = (part1Count+part2Count+part3Count+part4Count);
    } else if (field.value.length <= (part1Count+part2Count+part3Count+part4Count+part5Count)) { 
        smsCount = 5;
        smsCharCnt = part5Count;
        smsTotalCount = (part1Count+part2Count+part3Count+part4Count+part5Count);
    }

    if (field.value.length > maxlimit) {
        // if too long...trim it!
        field.value = field.value.substring(0, maxlimit);
    } else {
        cntfield.value = smsTotalCount - field.value.length;
        smsCntfield.value = smsCount;
    }

}

example use:

示例使用:

<html:textarea cols="30" rows="5" property="textEn"
                                                    title="Text English"
                                                    onkeydown="textCounter(document.form.textEn,document.form.remLen2,document.form.smsCount2,0,762)"
                                                    onkeyup="textCounter(document.form.textEn,document.form.remLen2,document.form.smsCount2,0,762)" />
                                                                                                <br>
                                                <input type="text" readonly="readonly" name="remLen2"
                                                    size="3" maxlength="3" value="160"
                                                    title="Char Count">

                                                (
                                                <input type="text" readonly="readonly" name="smsCount2"
                                                    size="1" maxlength="1" value="1"
                                                    title="SMS Parts' />">
                                                )

回答by peshis

Every character from the extension table (GSM Extended Alphabet) is represented by two characters the actual maximum length is dynamically calculated as: 160 - k, where k is the number of extended characters used in the message.

扩展表(GSM 扩展字母表)中的每个字符由两个字符表示,实际最大长度动态计算为:160 - k,其中 k 是消息中使用的扩展字符数。

You also have to consider the message length is 153 characters when concatenating messages with a 8bit reference number.

在连接具有 8 位参考号的消息时,您还必须考虑消息长度为 153 个字符。

Unicode length is 70 characters, while concatenated 63 characters.

Unicode 长度为 70 个字符,而串联 63 个字符。

回答by Satriya Agus

Based on the problems here, I try to write better solution. Adopted from several best answer here.

基于这里的问题,我尝试编写更好的解决方案。从这里的几个最佳答案中采用。

Javascript

Javascript

<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script>
$(document).ready(function(){

    part1Count = 160;
    part2Count = 145;
    part3Count = 152;

    $('#message').keyup(function(){
        var chars = $(this).val().length;
            messages = 0;
            remaining = 0;
            total = 0;
        if (chars <= part1Count) {
            messages = 1;
            remaining = part1Count - chars;
        } else if (chars <= (part1Count + part2Count)) { 
            messages = 2;
            remaining = part1Count + part2Count - chars;
        } else if (chars > (part1Count + part2Count)) { 
            moreM = Math.ceil((chars - part1Count - part2Count) / part3Count) ;
            remaining = part1Count + part2Count + (moreM * part3Count) - chars;
            messages = 2 + moreM;
        }
        $('#remaining').text(remaining);
        $('#messages').text(messages);
        $('#total').text(chars);
        if (remaining > 1) $('.cplural').show();
            else $('.cplural').hide();
        if (messages > 1) $('.mplural').show();
            else $('.mplural').hide();
        if (chars > 1) $('.tplural').show();
            else $('.tplural').hide();
    });
    $('#message').keyup();
});
</script>

HTML

HTML

<textarea name="message" value="" id="message"></textarea>
<div>
    <div><span id="remaining">160</span>&nbsp;Character<span class="cplural">s</span> Remaining</div>
    <div>Total&nbsp;<span id="messages">1</span>&nbsp;Message<span class="mplural">s</span>&nbsp;<span id="total">0</span>&nbsp;Character<span class="tplural">s</span></div>
</div>

You can get the code here http://www.mindrestingplace.com/2012/07/18/sms-character-counter/

您可以在此处获取代码http://www.mindrestingplace.com/2012/07/18/sms-character-counter/

Hope this will solve your problems. Thanks

希望这能解决您的问题。谢谢

回答by Eamonn

This is late to the game, but here's what I'm currently putting together.

这是游戏的后期,但这是我目前正在整理的内容。

The character limit is set to 459 to allow for concatenated messages (as set by my service provider), with a text unit tot-up per 160 characters used. Bear in mind this aspect is incomplete as each unit after the initial one would comprise of less than the 160 character template due to message headers and whatnot. I just havent gotten the exact breakdown from the provider yet.

字符限制设置为 459 以允许连接消息(由我的服务提供商设置),每使用 160 个字符添加一个文本单元。请记住,这方面是不完整的,因为初始单元之后的每个单元将包含少于 160 个字符的模板,这是由于消息标题和诸如此类的原因。我只是还没有从供应商那里得到确切的细分。

The crucial difference in this script is that the character count is sensitive to non-standard GSM characters, their ascii values specified in the included array. Where a non-standard character is typed, the count is 2, otherwise 1.

此脚本的关键区别在于字符数对非标准 GSM 字符敏感,它们的 ascii 值在包含的数组中指定。输入非标准字符时,计数为 2,否则为 1。

$('#sms-message').keyup(function(){
var     chars = $(this).val(),
        arr_chars = chars.split(''),
        remaining = $('#remaining'),
        messages = $('#messages'),
        count = 0;

    $.each(arr_chars, function(i, l){
        var     ascii = l.charCodeAt(0),
                ascii_val = parseInt(ascii),
                //array of special chars
                arr = [13, 47, 92, 123, 124, 125, 126, 128];

        if($.inArray(ascii_val, arr) !== -1) { count = count + 2; }
        else { count = count + 1; }
    });

            //inaccurate count, will have to be finetuned to provider specs
    var     units = Math.ceil(count / 160),
            remaining_chars = 459 - count;

        remaining.text(remaining_chars + ' characters remaining');
        messages.text(units + ' text unit(s)');

        if(remaining_chars < 0) {
            $(remaining).css('color', 'red');
        }
        else {
            $(remaining).css('color', 'black');
        }
});

回答by Rashedul Islam Sagor

For SMS sending character count

用于短信发送字符数

逻辑/要求:
  1. if len <= 160 than send (1 SMS)
  2. if len > 160 and after every 153 character/len, than send (1++)
  1. 如果 len <= 160 则发送(1 条短信)
  2. 如果 len > 160 并且在每 153 个字符/len 之后,则发送 (1++)
用例:
  1. len 1 to 160 = SMS send 1
  2. len 161 to 313 = SMS send 2
  3. len 314 to 466 = SMS send 3
  1. len 1 到 160 = SMS 发送 1
  2. len 161 到 313 = SMS 发送 2
  3. len 314 到 466 = SMS 发送 3

And so on...

等等...

Script :

脚本 :

function cntsms(len) { 
   return len <= 0 ? 0 : ( len > 160 ? Math.ceil((len-7)/153) : 1);
}

回答by S.Maina

  $(function() {        
          $('#message').keydown(function() {
                  var mychars = $('#message').val().length; 
                  var mysms = Math.ceil(mychars / 160);

                           console.log (mysms); 
                           console.log (mychars +'' + ' characters'); 
           });
      });