2016-05-25 4 views
2

У меня есть < input type="text" > (в HTML), и каждый раз, когда я добавляю символ, я делаю if text.length < x {...} (в JavaScript).JavaScript Длина Юникода (астральные символы)

Проблема состоит в том, что специальные символы/астральные символы Юникода (\ 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(document.getElementById("1").value.length<16){ 

Edit (это работает!):

<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> 
+0

"Визуальный текст" ... ? Надеюсь, это не значит, что вы пытаетесь ограничить ширину * экрана * (сколько пикселей будет занимать текст при отображении)? Потому что это невозможно с помощью этого метода. Игнорируйте этот комментарий, если он не по теме. – deceze

+0

Visual Text = Длина символов/не-BMP, которые вы можете видеть. Например, только максимальная длина = 9 символов в тексте (поле). –

+0

Например, длина s равна 4, но то, что я имею в виду с визуальным текстом, равно = 2. –

ответ

2

Я думаю, что у вас есть большая часть исследований, проведенных, вам нужно всего лишь поместить все из них вместе:

Выполнение функции, которую предоставляет ваша связь:

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 (countSymbols(document.getElementById("1").value)<16) { ...} 

Например: countSymbols('27') возвращает 4

Вот вам небольшой пример: https://jsfiddle.net/q7g9qtk7/

Обновление: Вы можете также использовать Array.from (polyfilling для IE, Chrome и Firefox уже поддерживают его), который берет строку и разбивает ее на каждый символ, независимо от того, сколько это будет времени:

Array.from (· 27') // возвращает [ "", "2", "", "7"]

Так что ваша функция может быть

function countSymbols(string) { 
     return Array.from(string).length; 
} 
+0

Я попробую это, если. Надеюсь это работает. –

+0

использовать 'для обозначения кода как' code';) –

+0

Ну, это должно работать, но я пробовал и ничего не возвращает. Я думаю, функция countSymbols работает не так, как предполагалось. –

Смежные вопросы