JavaScript Unicode的长度(星号符号)

3
我有一个HTML中的< input type="text" >,每次添加一个字符时我会做一个if text.length < x {...}(在JavaScript中)。问题是Unicode特殊字符/星体符号(\u{.....},具有超过4个十六进制/非BMP字符的字符)“被存储为两个代码单元,因此长度属性将返回2而不是1。”(来源:https://mixmax.com/blog/unicode-woes-in-javascript)。
我想要能够获得所有符号的长度为1或2,只要它们不混合使用1和2,因为我必须对可视文本的大小进行限制。我认为解决方案在这里:https://mathiasbynens.be/notes/javascript-unicode#accounting-for-astral-symbols,但我不确定如何使用它。
我的if大致如下:
if(document.getElementById("1").value.length<16){

编辑(它正在工作!):

<html>
    <head>
        <style>
            input{background:white;border:1px solid;height:30;outline-color:black;position:absolute;top:389;width:30}
        </style>
        <script>
            <!--
                function Add(symbol){
                    if (countSymbols(document.getElementById("1").value)<16) {
                        document.getElementById("1").value+=symbol}
                    if(document.getElementById("1").value.length==16 && document.getElementById("1").value=="\u{1F4BB}\u{1F3AE}\u{1F3C3}\u{1F525}\u2764\u{1D7CF}\u{1D7D1}\u{1F4B0}\u2757"){
                        document.getElementById("1").style.background="#00BB00"}
                    if(document.getElementById("1").value.length==16 && document.getElementById("1").value!="\u{1F4BB}\u{1F3AE}\u{1F3C3}\u{1F525}\u2764\u{1D7CF}\u{1D7D1}\u{1F4B0}\u2757"){
                        document.getElementById("1").style.background="#BB0000"}
                }
                function countSymbols(string) {
                    var regexAstralSymbols = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
                    return string
                    // Replace every surrogate pair with a BMP symbol.
                    .replace(regexAstralSymbols, '_')
                    // …and *then* get the length.
                    .length;
                }
            //-->
        </script>
    </head>
    <body>
        <input readOnly="true" id="1" style="left:573;outline:0;padding:5 8;top:356;width:294">
        <input onclick="Add('\u{1F4BB}')" style="left:573" type="button" value="&#128187">
        <input onclick="Add('\u{1F3AE}')" style="left:606" type="button" value="&#127918">
        <input onclick="Add('\u{1F3C3}')" style="left:639" type="button" value="&#127939">
        <input onclick="Add('\u{1F525}')" style="left:672" type="button" value="&#128293">
        <input onclick="Add('\u2764')" style="left:705" type="button" value="&#10084">
        <input onclick="Add('\u{1D7CF}')" style="left:738" type="button" value="&#120783">
        <input onclick="Add('\u{1D7D1}')" style="left:771" type="button" value="&#120785">
        <input onclick="Add('\u{1F4B0}')" style="left:804" type="button" value="&#128176">
        <input onclick="Add('\u2757')" style="left:837" type="button" value="&#10071">
    </body>
</html>

“视觉文本”……?我希望这并不意味着你正在尝试限制显示宽度(文本在显示时占用多少像素)?因为使用这种方法是不可能的。如果这与主题无关,请忽略此评论。 - deceze
可视文本长度为符号/非BMP字符的长度。例如,文本框中最大长度仅为9个字符。 - JS Newbie
例如,“s”的长度为4,但我在视觉文本中的意思是=2。” - JS Newbie
我可以将长度检查/如果语句加倍,但问题在于文本(框)可能会出现像这样的情况:27,其中长度为2+1+2+1=6,但视觉上只有4。 - JS Newbie
1个回答

4

我想你已经完成了大部分的研究,现在只需要整合所有内容:

使用您提供链接中的功能:

function countSymbols(string) {
    var regexAstralSymbols = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
    return string
        // Replace every surrogate pair with a BMP symbol.
        .replace(regexAstralSymbols, '_')
        // …and *then* get the length.
        .length;
}

你的if语句应该是:

if (countSymbols(document.getElementById("1").value)<16) { ...}

例如:countSymbols('27') 返回4。
这里有一个小例子:https://jsfiddle.net/q7g9qtk7/ 更新:你也可以使用Array.from(IE需要polyfill,Chrome和Firefox已经支持了),它将字符串分割成每个字符,不管它有多长。
Array.from('27') //returns ["", "2", "", "7"]

所以你的函数可以是:
function countSymbols(string) {
       return Array.from(string).length;
}

嗯,那应该可以工作,但我尝试过了,它没有返回任何内容。我认为函数countSymbols没有按预期工作。 - JS Newbie
在记事本中,我使用\u{1F3C3}2\u{1F525}7代替27,因为我无法保存Unicode。if语句不起作用,我已经尝试了这个结尾,但它不起作用(document.getElementById("1").value=countSymbols(document.getElementById("1").value.length)。 - JS Newbie
可以了,我要看看我的代码哪里出错了。谢谢。 - JS Newbie
你忘记了正则表达式...我在函数中添加它以使其“可导出” ;) - Pablo Lozano
[...''].length === 3 - vitaliydev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接