JavaScriptの変数の更新
受付中
回答 3
投稿
- 評価
- クリップ 0
- VIEW 1,634
そこまではうまくいくのですがこれを
次回入力された数字が前回より大きな数字だった場合のみ保存
という風にするにはどうすればいいのでしょうか?
<body>
<input type="button" value="start" onclick="start()">
<div id="result"></div>
<script>
function start() {
var num = prompt("数字を入力");
document.getElementById('result').innerHTML = num;
save();
}
window.onload = function(){
var body_num = localStorage.getItem('num');
document.getElementById('result').innerHTML = body_num;
}
function save(){
localStorage.setItem('num', document.getElementById('result').innerHTML);
}
</script>
</body>
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
0
function start() {
var num = prompt("数字を入力");
var nowValue = parseInt(document.getElementById("result").innerHTML, 10);
if(!isNaN(nowValue) && nowValue < parseInt(num, 10)){
document.getElementById('result').innerHTML = num;
save();
}
}
上記のようにしてみてはいかがでしょうか?
現在表示されている値と入力された値を数値にして比較しているだけです。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
個人的には値を取得する関数に切り分けてると見通しが良くなるかなと思いました。
後は、マイナスの数と0の時の処理の取りこぼしに気をつければ良さそうな気がします。
/* 値を取得するだけ */
function getNum() {
return localStorage.getItem('num');
}
/* 渡された値を保存するだけ */
function save(num){
/* 必要であれば ここに num が数値ではなければ弾くバリデーションを入れる。*/
localStorage.setItem('num', num);
}
function start() {
var num = getNum();
// 空文字列をNaNにするためにparseInt()を使用。Number()だと0になってしまう。
var newNum = parseInt(prompt("数字を入力"), 10);
/*
* 0 の時も比較できるようにnewNumの有無を (newNum || newNum === 0) で判定
* num-0 して数値化して比較する。
* なにも保存されてない時マイナスの数を入力されると
* newNum > num-0 だけだと 0 との比較になって保存されないので、
* newNumがあってnumがnullの場合は保存するようにする
*/
if((newNum || newNum === 0) && (newNum > num-0 || !num)) {
document.getElementById('result').innerHTML = newNum;
save(newNum);
}
}
window.onload = function(){
var body_num = getNum();
document.getElementById('result').innerHTML = body_num;
};
parseInt()
もNumber()
も入力される値によって変換のクセがあるので完璧に数値の入力しか受け付けないとかにするのであれば、入力値を直ぐに変換するのではなく間にバリデーションを入れてその後で変換するなどとした方が良いと思います。
型変換のいろいろ
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
JSFiddle に下記HTMLをUPしました。
<script>
'use strict';
function getNumber () {
var number = localStorage.getItem('num');
return number ? Number(number) : NaN;
}
function handleStart () {
var numberString = prompt('数字を入力'),
number = Number(numberString),
oldNumber = getNumber();
if (numberString === number.toString() && !isNaN(number) && (number > oldNumber || isNaN(oldNumber))) {
localStorage.setItem('num', numberString);
document.getElementById('result').firstChild.data = number;
}
}
function handleInitialize () {
localStorage.removeItem('num');
document.getElementById('result').firstChild.data = '出力値';
}
function handleDOMContentLoaded () {
var number = getNumber();
if (!isNaN(number)) {
document.getElementById('result').firstChild.data = number;
}
}
document.addEventListener('DOMContentLoaded', handleDOMContentLoaded, false);
</script>
</head>
<body>
<input type="button" value="start" onclick="handleStart()">
<input type="button" value="initialize" onclick="handleInitialize()">
<div id="result">出力値</div>
-
localStrage
は String 型でデータが保存される為、数値の大小比較するためには Number 型へ変換する必要があります
- Number 型への変換方法は主に
Number()
, parseInt()
, parseFloat()
の三種類が存在しますが、ここでは最も簡易的処理となる Number()
を採用しました
-
Number()
(内部的には ToNumber) で Number 型へ型変換した後に Number.prototype.toString
で String 型に戻し、元々の文字列と照合する事で正規の数値文字列かを確認しています
-
localStrage
にゴミが残ると良くないので削除処理も入れておきました
-
locasStrage
は IE8+で使えるメソッドです(IE7 に対応するなら Cookie を使用して下さい)
-
addEventListener
は IE9+ で使えるメソッドです(諸般の事情で addEventListener
を使用しましたが、IE8 に対応するなら attachEvent
or body[onload]
を使用して下さい)投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.35%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2015/08/27 10:22
いくつか解説お願いしたいです・・・。
var nowValue = parseInt(document.getElementById("result").innerHTML, 10);
の10とはなんなのでしょうか?
if(!isNaN(nowValue) && nowValue < parseInt(num, 10))
の!isNaN(nowValue)とは?NaNじゃなかったらということでしょうか?
2015/08/27 10:48
>の10とはなんなのでしょうか?
こちらは十進数の数値に変換するという意味です。「10」で十進数を指定しています。
>if(!isNaN(nowValue) && nowValue < parseInt(num, 10))
>の!isNaN(nowValue)とは?NaNじゃなかったらということでしょうか?
そのとおりです。parseIntは数値を含まないような文字列(例えば、「abc」といった文字列)を変換するとNaN(Not a Number)を返しますので、そのような場合を拒否しています。
これを書いて思ったのですが、最初に示したコードはまずいですね。次のようにしてください。
function start() {
var num = prompt("数字を入力");
num = parseInt(num, 10);
var nowValue = parseInt(document.getElementById("result").innerHTML, 10);
if(!isNaN(nowValue) && !isNaN(nowValue) && nowValue < num){
document.getElementById('result').innerHTML = num;
save();
}
}
2015/08/27 12:20
また、初回の何も保存されていない時、nowValueは`parseInt('', 10);`になるので常にNaNになってしまうように思います。で、NaN > num で数値比較しても常にfalseになってしまったように思いますので、上手く動作しないような気がしますが、いかがでしょうか?
2015/08/30 11:28
補足しますと、isNaN() は NaN 値の判定ではなく、Number 型へ変換した時に NaN になれば true を返します。
つまり、isNaN('string') === true です。
parseInt() で Number 型へ変換済の為、この場合は NaN の判定として機能しますが、isNaN() の機能として記憶してしまうと混乱の元なので補足しました。
NaN の判定には Number.isNaN() を使います。
2015/08/31 09:31
>コメント中のif文の中に !isNaN(nowValue) && !isNaN(nowValue) && 〜と二回繰り返されていますが、 !isNaN(num) && !isNaN(nowValue) && 〜 の書き間違いでしょうか?
その通り、書き間違いです。
>また、初回の何も保存されていない時、nowValueは`parseInt('', 10);`になるので常にNaNになってしまうように思います。で、NaN > num で数値比較しても常にfalseになってしまったように思いますので、上手く動作しないような気がしますが、いかがでしょうか?
確かに最初がうまく動作しないですね。ご指摘ありがとうございます。
think49さん
補足説明ありがとうございます。