143

主にモバイルブラウザ用のWebアプリを構築しています。数値型の入力フィールドを使用しているため、(ほとんどの) モバイル ブラウザーはユーザー エクスペリエンスを向上させるために数値キーボードのみを呼び出します。この Web アプリは主に、小数点がドットではなくコンマである地域で使用されるため、両方の小数点を処理する必要があります。

この混乱全体をドットとコンマでカバーする方法は?

私の調査結果:

デスクトップ クローム

  • 入力タイプ=数値
  • ユーザーは入力フィールドに「4,55」と入力します
  • $("#my_input").val();「455」を返します
  • 入力から正しい値を取得できません

デスクトップ Firefox

  • 入力タイプ=数値
  • ユーザーは入力フィールドに「4,55」と入力します
  • $("#my_input").val();「4,55」を返します
  • それは結構です。コンマをドットに置き換えて、正しいフロートを取得できます

Android ブラウザ

  • 入力タイプ=数値
  • ユーザーは入力フィールドに「4,55」と入力します
  • 入力がフォーカスを失うと、値は「4」に切り捨てられます
  • ユーザーを混乱させる

Windows Phone 8

  • 入力タイプ=数値
  • ユーザーは入力フィールドに「4,55」と入力します
  • $("#my_input").val();「4,55」を返します
  • それは結構です。コンマをドットに置き換えて、正しいフロートを取得できます

ユーザーがコンマまたはドットを小数点記号として使用する可能性があり、より良いユーザーエクスペリエンスを提供するために、html 入力タイプを数値として保持したい場合、このような状況での「ベストプラクティス」は何ですか?

コンマを「その場で」ドットに変換して、キーイベントをバインドできますか?数値入力で機能しますか?

編集

現在、型が数値に設定されている入力から浮動小数点値 (文字列または数値として) を取得する方法はありません。エンドユーザーが「4,55」と入力すると、Chrome は常に「455」を返し、Firefox は「4,55」を返しますが、これで問題ありません。

また、Android (テスト済みの 4.2 エミュレーター) で、入力フィールドに「4,55」と入力してフォーカスを別の場所に移動すると、入力した数値が「4」に切り捨てられるのも非常に面倒です。

4

10 に答える 10

26

w3.org によると、数値入力の属性は浮動小数点数として定義されています。浮動小数点数の構文は、小数点としてドットのみを受け入れるようです。

役立つ可能性のあるいくつかのオプションを以下にリストしました。

1. pattern 属性の使用

pattern属性を使用すると、HTML5 互換の方法で正規表現を使用して、許可された形式を指定できます。ここで、コンマ文字を許可し、パターンが失敗した場合に役立つフィードバック メッセージを指定できます。

<input type="number" pattern="[0-9]+([,\.][0-9]+)?" name="my-num"
           title="The number input must start with a number and use either comma or a dot as a decimal character."/>

注:クロスブラウザーのサポートはさまざまです。完全、部分的、または存在しない可能性があります..

2. JavaScript の検証

たとえば、コンマを置き換えるか、すべて一緒に検証するonchange (および/またはblur ) イベントに単純なコールバックをバインドしようとすることができます。

3. ブラウザの検証を無効にする ##

3 番目に、数値入力でformnovalidate属性を使用して、そのフィールドのブラウザー検証をすべて無効にすることを試みることができます。

<input type="number" formnovalidate />

4.組み合わせ…?

<input type="number" pattern="[0-9]+([,\.][0-9]+)?" 
           name="my-num" formnovalidate
           title="The number input must start with a number and use either comma or a dot as a decimal character."/>
于 2013-03-08T22:07:08.927 に答える
10

小数点記号にコンマを使用するかピリオドを使用するかは、ブラウザ次第です。ブラウザーは、オペレーティング システムまたはブラウザーのロケールに基づいて判断を下すか、一部のブラウザーは Web サイトからヒントを得ます。さまざまなブラウザーのサポートがさまざまなローカライズ方法をどのように処理するかを示すブラウザー比較表を作成しました。Safari は、カンマとピリオドを同じ意味で扱う唯一のブラウザです。

基本的に、Web 作成者としてこれを実際に制御することはできません。いくつかの回避策には、整数を含む 2 つの入力フィールドを使用することが含まれます。これにより、すべてのユーザーが期待どおりにデータを入力できます。特に魅力的ではありませんが、すべてのユーザーにとってあらゆる場合に機能します。

于 2015-02-08T15:15:04.973 に答える
7

valueAsNumberの代わりに使用してください.val()

入力。valueAsNumber [= value]

該当する場合は、フォームコントロールの値を表す数値を返します。それ以外の場合は、nullを返します。
設定して値を変更できます。
コントロールが日付ベースでも時間ベースでも数値でもない場合は、INVALID_STATE_ERR例外をスローします。

于 2013-03-08T21:55:25.627 に答える
4

完璧な解決策は見つかりませんでしたが、type="tel" を使用して html5 検証 (formnovalidate) を無効にすることが最善の方法でした。

<input name="txtTest" type="tel" value="1,200.00" formnovalidate="formnovalidate" />

ユーザーがカンマを入力すると、私が試したすべての最新ブラウザ (最新の FF、IE、エッジ、オペラ、クロム、サファリ デスクトップ、アンドロイド クロム) でカンマ付きで出力されます。

主な問題は次のとおりです。

  • モバイル ユーザーには、数字キーボードとは異なる電話キーボードが表示されます。
  • さらに悪いことに、電話のキーボードにはカンマのキーさえない場合があります。

私のユースケースでは、次のことだけを行う必要がありました。

  • カンマで初期値を表示します (firefox は type=number の場合はそれを取り除きます)
  • html5検証に失敗しない(カンマがある場合)
  • フィールドを入力とまったく同じように読み取ります (コンマを使用することもできます)。

同様の要件がある場合、これはうまくいくはずです。

注: pattern 属性のサポートが好きではありませんでした。formnovalidate の方がはるかにうまく機能するようです。

于 2016-04-05T23:14:58.980 に答える
1

呼び出す$("#my_input").val();と、文字列変数として返されます。したがって、変換にはparseFloatandを使用します。デスクトップまたは電話parseIntを使用すると、 ITSELFは変数の意味を理解します。parseFloat

toFixedさらに、次のように桁数の引数を持つ which を使用して、浮動小数点数を文字列に変換できます。

var i = 0.011;
var ss = i.toFixed(2); //It returns 0.01
于 2015-12-17T08:53:29.427 に答える
1

どうやらブラウザにはまだ問題があるようです (ただし、Chrome と Firefox Nightly は問題ありません)。数値フィールドを実際に使用する必要がある人のために、ハックなアプローチがあります (テキスト フィールドにはない小さな矢印が原因かもしれません)。

私の解決策

フォーム入力にイベント ハンドラーを追加keyupし、状態を追跡して、値が再び有効になったら値を設定しました。

純粋な JS スニペット JSFIDDLE

var currentString = '';
var badState = false;
var lastCharacter = null;

document.getElementById("field").addEventListener("keyup",($event) => {
  if ($event.target.value && !$event.target.validity.badInput) {
          currentString = $event.target.value;
  } else if ($event.target.validity.badInput) {
    if (badState && lastCharacter && lastCharacter.match(/[\.,]/) && !isNaN(+$event.key)) {
      $event.target.value = ((+currentString) + (+$event.key / 10));
      badState = false;
    } else {
      badState = true;
    }
  }
  document.getElementById("number").textContent = $event.target.value;
  lastCharacter = $event.key;
});

document.getElementById("field").addEventListener("blur",($event) => {
	if (badState) {
    $event.target.value = (+currentString);
    badState = false;
		document.getElementById("number").textContent = $event.target.value;
  }
});
#result{
  padding: 10px;
  background-color: orange;
  font-size: 25px;
  width: 400px;
  margin-top: 10px;
  display: inline-block;
}

#field{
  padding: 5px;
  border-radius: 5px;
  border: 1px solid grey;
  width: 400px;
}
<input type="number" id="field" keyup="keyUpFunction" step="0.01" placeholder="Field for both comma separators">

<span id="result" >
 <span >Current value: </span>
 <span id="number"></span>
</span>

Angular 9 スニペット

@Directive({
  selector: '[appFloatHelper]'
})
export class FloatHelperDirective {
  private currentString = '';
  private badState = false;
  private lastCharacter: string = null;

  @HostListener("blur", ['$event']) onBlur(event) {
    if (this.badState) {
      this.model.update.emit((+this.currentString));
      this.badState = false;
    }
  }

  constructor(private renderer: Renderer2, private el: ElementRef, private change: ChangeDetectorRef, private zone: NgZone, private model: NgModel) {
    this.renderer.listen(this.el.nativeElement, 'keyup', (e: KeyboardEvent) => {
      if (el.nativeElement.value && !el.nativeElement.validity.badInput) {
        this.currentString = el.nativeElement.value;
      } else if (el.nativeElement.validity.badInput) {
        if (this.badState && this.lastCharacter && this.lastCharacter.match(/[\.,]/) && !isNaN(+e.key)) {
          model.update.emit((+this.currentString) + (+e.key / 10));
          el.nativeElement.value = (+this.currentString) + (+e.key / 10);
          this.badState = false;
        } else {
          this.badState = true;
        }
      }       
      this.lastCharacter = e.key;
    });
  }
  
}
<input type="number" matInput placeholder="Field for both comma separators" appFloatHelper [(ngModel)]="numberModel">

于 2020-03-31T11:46:13.033 に答える
0

私の推薦?jQuery は一切使用しないでください。私はあなたと同じ問題を抱えていました。$('#my_input').val()常に奇妙な結果を返すことがわかりました。

document.getElementById('my_input').valueAsNumberの代わりに使用してから$("#my_input").val();、使用Number(your_value_retrieved)して数値を作成してみてください。値が NaN の場合、それが数値ではないことは確かにわかります。

追加することの 1 つは、入力に数値を書き込む場合、入力は実際にはほとんどすべての文字を受け入れることです (ユーロ記号、ドル、およびその他すべての特殊文字を書き込むことができます)。.valueAsNumberjQueryを使用する代わりに。

ああ、ところで、これにより、ユーザーは国際化を追加できます (つまり、ドットの代わりにコンマをサポートして 10 進数を作成できます)。オブジェクトに何かを作成させるだけNumber()で、いわば小数セーフになります。

于 2013-04-04T21:33:02.950 に答える
0

数値入力で toLocaleString() を使用したいようです。

使用方法については、 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleStringを参照してください。

JS での数値のローカライズは、Chrome では機能しない国際化 (数値フォーマット "num.toLocaleString()")でもカバーされています

于 2013-05-30T09:21:38.013 に答える