プロが教えるわが家の防犯対策術!

スタイルがうまく表示できません。
関数を作って収入と支出の計算をしているのですが、残高が0より小さい時は赤字で表示。0以上の時は青字で表示しています。
以下がソースなのですが、数字を何度も変更して確認したのですが、うまくいく時と行かない時があります。(マイナスでも青字になったり、マイナスではないのに赤字になったりすることがあります。何度やってもうまく行く時もあります)

<html lang="ja">
<head>
<script type="text/javascript">
<!--
function zandaka(){
moneyin = document.form1.text1.value;
moneyout = document.form1.text2.value;
document.form1.text3.value=moneyin-moneyout;
if(moneyout>moneyin){
document.form1.text3.style.color="red";
}
else{
document.form1.text3.style.color="blue";
}
}
-->
</script>
<title>簡単計算機</title>
</head>
<body>
<h1>簡単計算機</h1>
<hr>
<h2>収支計算</h2>
<form name="form1">
<p>収入<input type="text" value="0" class="right" name="text1">円</p>
<p>支出<input type="text" value="0" class="right" name="text2">円</p>
<p>残高<input type="text" value="0" class="right" name="text3" onfocus="zandaka()">円</p>
</form>
</body>
</html>

うまくいかない時と行く時の区別がつかないため原因がわかりません。
初心者なのでつまらないミスだとは思うのですが、原因がわかればお願いします。

A 回答 (5件)

#2です。



誤解を与える説明だったので、補足します。
parseInt() はいくつか注意点があり、私が所持している参考書『JavaScript: The Good Parts』でもP120で解説されています。

parseInt() は「数値型変換を行う関数」ではなく、「指定された基数の整数値に変換を行う関数」です。
第一引数に与えられた文字列を第二引数で与えられた基数の整数値に変換します。
第二引数が省略された場合、先頭に 0 を持つ数値文字列を第一引数に与えられると8進数に基数変換します。
なので、10進数に変換したい場合は、第二引数で 10 を指定した方が無難です。(これは『JavaScript: The Good Parts』でも推奨されています)

var a = "010";
alert(parseInt(a));// 8 (第二引数で基数値を指定しない場合、parseInt() は0で始まる数値を8進数として扱う)
alert(parseInt(a, 10));// 10 (第2引数に10を指定すれば、常に10進数として扱う)

parseInt() は一番目の文字が数に変換できない場合、NaN を返します。(MDCより)

var b = "";// 空文字
alert(parseInt(b));// NaN
alert(parseInt(b, 10));// NaN

一方、Number() は指定された値を「数値型に変換する関数」です。
parseInt() と同じく数値型に変換できない場合に NaN を返しますが、parseInt() より幅広い型変換が可能です。

var a = "010";
var b = "";// 空文字
var c = null;// null型
var d = NaN;// NaN型
var e = void(0);// undefined型
alert(Number(a));// 10
alert(Number(b));// 0
alert(Number(c));// 0
alert(Number(d));// NaN
alert(Number(e));// NaN

ですので、もしWeb制作者が指定された値を数値型に変換したいのなら、Number() を使用した方が良い、と私は思います。
実際、下記コードは "NaN" を残高に格納します。(全角空白は半角空白に置換してください)

<form>
 <p>収入<input type="text" value="" class="right" name="text1">円</p>
 <p>支出<input type="text" value="" class="right" name="text2">円</p>
 <p>残高<input type="text" value="" class="right" name="text3" id="text3" onfocus="zandaka(event);">円</p>
</form>
<script type="text/javascript"><!--
(function (){
 var target = document.getElementById('text3');
 var form = target.form;
 target.value = parseInt(form.elements['text1'].value, 10) + parseInt(form.elements['text2'].value, 10);
 alert(iframeElement); // iframe#hoge を参照する
})();
//--></script>

勿論、"NaN" を返す場合は例外処理でエラーを返してもいいのですが、その場合は複雑な処理が必要です。
どちらにせよ、parseInt() は Number() で数値型に変換された値を基数変換する関数だと思います。

parseInt - MDC
https://developer.mozilla.org/ja/Core_JavaScript …
Number - MDC
https://developer.mozilla.org/ja/Core_JavaScript …
    • good
    • 0

#2,4です。



#4に一部ミスがありました。

----
 alert(iframeElement); // iframe#hoge を参照する
----

これは別のテストコードの名残で本件とは無関係です。ごめんなさい。
    • good
    • 0

回答読んでも解らないですか?


とりあえず、
if(moneyout>moneyin){
 document.form1.text3.style.color="red";
}
else{
 document.form1.text3.style.color="blue";
}

if(parseInt(document.form1.text3.value)>=0){
  document.form1.text3.style.color="blue";
}else{
  document.form1.text3.style.color="red";
 }
にしてみなされ(もち全角空白は半角空白にして)
    • good
    • 0

前質問の回答を読んで下さい。




■前回の質問(http://okwave.jp/qa/q5932254.html)より
----------------------------------------------
あと、これは後になって出てくる問題ですが、<input> からローカル変数に代入した値も明示的に数値型に変換しないと文字列型として扱います。

Number - MDC
https://developer.mozilla.org/ja/Core_JavaScript …
Javascriptで、以下の様な足し算をする場合、 | OKWave
http://okwave.jp/qa/q5896295.html
----------------------------------------------

■parseInt() の仕様
----------------------------------------------
基数が指定されなかったり、0 が指定された場合、JavaScript は以下のように解釈します。:

・入力 string が "0x" で始まっている場合、基数は 16(16 進表記)になります。
・入力 string が "0" で始まっている場合、基数は 8 (8 進表記)になります。この機能は、非推奨です。
・入力 string が他の値で始まっている場合、基数は、10(10進表記)になります。

一番目の文字が数に変換できない場合、parseInt は、NaN を返します。
https://developer.mozilla.org/ja/Core_JavaScript …
----------------------------------------------

■検証用コード
------------
var a = "";
var b = 3;
var c = "05"
var d = null;

var num1 = Number(a) - Number(b) + Number(c) + Number(d);
var int1 = parseInt(a) - parseInt(b) + parseInt(c) + parseInt(d);
var int1 = parseInt(a) - parseInt(b) + parseInt(c) + parseInt(d);
var int2 = parseInt(a, 10) - parseInt(b, 10) + parseInt(c, 10) + parseInt(d, 10);

alert(num1);// 2
alert(int1);// NaN
alert(int2);// NaN
------------
    • good
    • 0

文字列の型の問題です。


JavaScriptは型に対して寛容(いい加減)なので、演算する際は注意が必要です。

if(moneyout>moneyin)

if(parseInt(moneyout)>parseInt(moneyin))
にすれば解決するはずです。

■説明

moneyin = document.form1.text1.value;
moneyout = document.form1.text2.value;

この場合、moneyinとmoneyoutの算術演算(+-*/)は数字型として扱われますが、比較演算する際は文字列型として扱われます。

通常の数学では
1<2 10>2
ですが、文字列比較の場合は先頭の文字から比較するため
1<2 10<2
となります。(10は先頭の文字が1なので、2の方が大きいとみなす。)

質問者のソースでは以下の様になることを確認してください。
・収入1、支出2の場合、赤字の-1になり、
・収入10、支出2の場合、赤字の8になります。 (本来は青字の8が正しい)

そこで、比較する際は型を数字型に強制的に変更(キャスト)します。
キャストの方法は簡単で、整数にするならparseInt(変数)、小数点を使うならparseFloat(変数)とします。
    • good
    • 1

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!