Новые Webkit преобразуют десятичную запятую в ~ точку и наоборот при вводе числового типа. Имя Javascript этой функции браузера?

Я обнаружил весьма своеобразную функцию браузера в последних версиях Chrome (35; Win/Android/iOS) и Safari (7; iOS). Если у вас есть математическая форма с input type="number" и вы вводите число с десятичной запятой, браузеры выполняют вычисления с числом, как если бы запятая была точкой. А если вводить числа с десятичными точками, то они делают свои обычные вычисления, но результирующая цифра отображается с десятичной запятой. То есть в моем европейском (т.е. голландском) варианте. Про американские версии не знаю.

Если вам трудно в это поверить, я сделал демонстрацию, чтобы продемонстрировать это:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Demo Browser Behavior w/ Number Inputs</title>
    <style>
    input {
        box-sizing: border-box;
        margin-top: 10px;
        width: 100px;
    }
    </style>
</head>
<body>
    <form name="theForm">
        <input type="number" name="A1field" min="0" max="100" step="0.1"> Input field
                <br>
        <input type="number" name="A2field" min="0" max="100" step="0.1"> Input field
                <br>
        <input type="button" value="Calculate" onclick="calculateAndPopulate()">
                <br>
        <input type="number" name="R1field" min="0" max="10000" step="0.01"> Result field
                <br>
        <input type="reset" value="Reset">
    </form>
    <script>
        function calculateAndPopulate() {
            var A1val = theForm.A1field.value;
            var A2val = theForm.A2field.value;
            var R1 = (A1val*A2val);
            theForm.R1field.value = R1;
        }
    </script>
</body>
</html> 

Живая демонстрация здесь: http://codepen.io/anon/pen/xDvCB?editors= 100. Как подразумевается, вам, вероятно, понадобится версия, сделанная для стран с таким обозначением: € 4.999,99. Введите любые два числа до 100 с: а) одним десятичным знаком каждое и б) десятичными запятыми, десятичными точками или их комбинацией. И удивитесь отображаемому результату - не имеет значения, используется ли точка или запятая для ввода, вывод вычисления всегда один и тот же, а вывод всегда отображается с запятой.

Firefox 30 не имеет этой функции (или ошибки, в зависимости от того, как вы на это смотрите), как и IE9 (не знаю о более поздних версиях). Я хотел бы знать, знает ли кто-нибудь имя этой функции в Javascript. Я хотел бы сообщить посетителям с такими вебкитами, что результаты могут быть своеобразными.

Обширный поиск в Интернете с использованием input type = number (converts OR conversion) comma (dot OR period OR "full stop") browser feature не дал мне нужного ответа. Мне попалась статья производителя Chrome, но это только подтверждает (не слишком хорошо принятую) функцию, не упоминая ее имя JS. И также не этот поток SO, который является единственным потоком SO, который я смог найти, который приближается к тому, что я пытаюсь выяснить.


person Frank Conijn    schedule 25.06.2014    source источник
comment
К вашему сведению, я использую британскую локаль (точка для десятичного знака), а Chrome на Win рассматривает любое значение с запятой как недопустимое. Так что, похоже, это работает только в одну сторону, и поэтому я думаю, что это ошибка в Chrome. У меня нет ответов, но вот несколько связанных вопросов: Chrome auto formats input number , Как обрабатывать числа с плавающей запятой и десятичные разделители с номером типа ввода html5   -  person jfrej    schedule 25.06.2014
comment
@jfrej - то же самое делает мой Chrome 18, встроенный в мой редактор кода в качестве одного из вариантов предварительного просмотра. Но где-то между 18 и 35 ст. это поведение изменилось. И связанная статья производителя Chrome (т.е. обсуждение с пользователем) ясно говорит, что это не ошибка, а функция. Что касается потока SO, на который вы ссылаетесь: я широко пробовал этот метод шаблона во всех видах конфигураций, но это не лекарство от специфического вывода - всегда с запятой в качестве десятичного разделителя. Тем не менее, я еще раз пройдусь по этому вопросу и дам вам знать, если у меня что-то получится.   -  person Frank Conijn    schedule 25.06.2014
comment
@jfrej - Кроме того: установка типа ввода text в сочетании с шаблоном регулярного выражения действительно излечивает математическое / отображаемое поведение, но с text планшеты подтягивают свои обычные клавиатуры, как только шаблон включает точку или запятую. У меня есть форма, в которую нужно ввести до 11 цифр, и пользователей планшетов слишком раздражает необходимость каждый раз переключать клавиатуру на цифровую.   -  person Frank Conijn    schedule 25.06.2014
comment
@jfrej: я наконец понял это. Смотрите мой (собственный) ответ.   -  person Frank Conijn    schedule 26.06.2014


Ответы (1)


Я, наконец, понял это (потратив на это около трех дней). Я мог бы спросить производителя Chrome, как называется Javascript, но было бы намного лучше, если бы я мог заставить браузеры вести себя правильно. Более широкая цель этого вопроса, который в первую очередь касается математических форм, заключается в следующем:

  • Согласованное межбраузерное поведение: все браузеры и версии браузеров должны вести себя одинаково.
  • Последовательное поведение внутри браузера: десятичная запятая в полях ввода = десятичная запятая в поле вывода. То же самое относится и к десятичным точкам.
  • Веб-разработчик должен иметь возможность поставить запятую или точку.
  • Непреднамеренные ошибки ввода посетителем должны быть исправлены или обнаружены. Клавиши с точками и запятыми всегда находятся рядом друг с другом, и разницу трудно увидеть, особенно на маленьких экранах.
  • На планшетах поле числового ввода, которое получает фокус, должно открывать цифровую клавиатуру/пэд.
  • Действительный HTML.

Эти два метода предлагают следующее:

ПРИНУДИТЕЛЬНАЯ ДЕСЯТИЧНАЯ ТОЧКА

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Math form with forced dot separator</title>
    <style>
    input {
        box-sizing: border-box;
        margin-top: 10px;
        width: 100px;
    }
    input[type="tel"]:invalid {
        box-shadow: none; /* 0 doesn't work */
    }
    </style>
</head>
<body>
    <h3>Math form with forced dot separator</h3>
    <form name="theForm">
        <input type="tel" name="A1field"> Input field
                <br>
        <input type="tel" name="A2field"> Input field
                <br>
        <input type="button" value="Multiply" onclick="multiplyAndPopulate()">
                <br>
        <input type="tel" name="R1field"> Result field
                <br>
        <input type="reset" value="Reset">
    </form>
    <script>
        var telInputs = document.querySelectorAll('input[type="tel"]');
        for (var i=0; i<telInputs.length; i++) {
            telInputs[i].onblur = function() {
                this.value = this.value.replace(',','.');
            }
        }

        function multiplyAndPopulate() {
            var A1 = theForm.A1field.value;
            var A2 = theForm.A2field.value;
            var R1 = (A1*A2);
            if (isNaN(R1) == true) {
                alert('In one or more input fields you have used more than the allowed one comma or dot, or entered a non-numerical character.');
                return false;
            }
            else {
                theForm.R1field.value = R1;
            }
        }
    </script>
</body>
</html>

Живая демонстрация здесь: http://codepen.io/anon/pen/bhajB?editors=100. .

ОБЯЗАТЕЛЬНО ДОПУСКАЕТСЯ ДЕСЯТИЧНОЙ ЗАПЯТОЙ

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Math form with forced comma separator</title>
    <style>
    input {
        box-sizing: border-box;
        margin-top: 10px;
        width: 100px;
    }
    input[type="tel"]:invalid {
        box-shadow: none; /* 0 doesn't work */
    }
    </style>
</head>
<body>
    <h3>Math form with forced comma separator</h3>
    <form name="theForm">
        <input type="tel" name="A1field"> Input field
            <br>
        <input type="tel" name="A2field"> Input field
            <br>
        <input type="button" value="Multiply" onclick="multiplyAndPopulate()">
            <br>
        <input type="tel" name="R1field"> Result field
            <br>
        <input type="reset" value="Reset">
    </form>
    <script>
        var telInputs = document.querySelectorAll('input[type="tel"]');
        for (var i=0; i<telInputs.length; i++) {
            telInputs[i].onblur = function() {
                this.value = this.value.replace('.',',');
            }
        }

        function multiplyAndPopulate() {
            var A1 = theForm.A1field.value.replace(',','.'); // not visible
            var A2 = theForm.A2field.value.replace(',','.'); // not visible
            var R1 = (A1*A2);
            if (isNaN(R1) == true) {
                alert('In one or more input fields you have used more than the allowed one comma or dot, or entered a non-numerical character.');
                return false;
            }
            else {
                theForm.R1field.value = R1;
                theForm.R1field.value = theForm.R1field.value.replace('.',',');
            }
        }
    </script>
</body>
</html>

Живая демонстрация здесь: http://codepen.io/anon/pen/jqFeJ?editors=100. .

.
Несколько пояснений:

  • input type="tel": только числовые типы ввода подтягивают цифровую клавиатуру/панель на iOS и Android. type="text" pattern="[0-9]*" не работает на Android. Кроме того, input type="number" заставляет старые Chrome (и, возможно, Safari на Win) удалять введенные запятые без надлежащего уведомления. Например. 4,5 незаметно превращается в 45. Отсюда и input type="tel".
  • Проверка Javascript: это лучше, чем проверка HTML5, потому что последняя не поддерживается старыми браузерами, а всплывающие подсказки с текстом предупреждений не могут быть изменены.
  • CSS: input[type="tel"]:invalid {box-shadow: none;}: который не позволяет новым версиям Firefox и, возможно, другим браузерам в будущем помещать (красную) предупреждающую рамку вокруг каждого поля ввода, которое он считает заполненным неправильно.

Остальной код должен говорить сам за себя. Коды были протестированы в IE8/9, Chrome 18 и 35 (Win/Android 4.1 Jelly Bean), Safari 5 (Win) и 7 (iOS) и собственном браузере Android (Android 4.1).

Есть только одно несовершенство и одно ограничение. Недостаток заключается в том, что цифровая клавиатура для телефонных номеров на Android немного отличается от обычной цифровой клавиатуры и может вызвать недоумение у опытных пользователей Android. Но все необходимые ключи есть, и большинство посетителей этого даже не заметят. Ограничение состоит в том, что посетители могут ввести только одну запятую или точку в поле ввода, то есть разделитель. Вы могли бы проинструктировать их заранее. И если они (по-прежнему) вводят больше, это фиксируется сценарием проверки.

Протестируйте живые демонстрации, если хотите. Если вы все еще найдете что-то неправильное или непоследовательное, пожалуйста, оставьте комментарий.

person Frank Conijn    schedule 26.06.2014
comment
Ваше решение НЕ РАБОТАЕТ на iPhone (проверено с iOS7 или iOS8), потому что на iPhone появляется виртуальная клавиатура 0-9, у которой нет обычной сдвинутой клавиатуры (вместо этого есть клавиатура 0-9 с клавишей [+*#] и нет доступных клавиш [.] или [,]). - person robocat; 20.10.2014
comment
Я могу обойтись без крика (uppercast), но спасибо за отзыв. На айфоне не проверял. Я протестировал его на iPad, и, поскольку между моим планшетом Android и телефоном не было разницы в клавиатуре, я предположил, что между iPhone и iPad также не будет разницы. Но видимо есть. А с клавиатуры номера телефона на айфоне нельзя перейти на другую клавиатуру? - person Frank Conijn; 23.10.2014