質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.36%

  • HTML

    6165questions

    HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

基本的なhtmlでの計算ツールのコードをjavaScriptなどを使って短縮したい

解決済

回答 2

投稿 2017/11/21 16:30 ・編集 2017/11/21 18:24

  • 評価
  • クリップ 1
  • VIEW 124

evine

score 2

htmlをソース短縮についてです。
できれば2次元のHashMapを使っていただけるとありがたいです。
栄養素の合計値を食べたものから算出するツールで、
野菜1は kcal 100 na 10 mg 20
野菜2は kcal 20 na 20 mg 10
野菜3は kcal 30 na 15 mg 40
の栄養素を基本的に摂取でき、食べた時の吸収能力によって補正を与えて複数の合計値を求めたいです。

ひとまず動くものはできたのですが、入力欄ごとにifを使わなければならないことと、その後数値化して最大値と最小値を指定するだけで非常に長くなってしまいました。
食べ物の種類を数百まで増やさなければならないので入力欄を増やすとソースが膨大になってしまいます。
そのため全ての入力欄の食べ物の栄養素をまとめて指定する方法(HashMapというのが便利みたいですが使い方が分かりませんでした)、また単純に省略できる部分について教えていただきたいです

人数: <input type="text" value="1" id="a1" class="example"><br /><br />
日数: <input type="text" value="1" id="b1" class="example"><br /><br />

<select  style="width: 222.297px;"  id="ve1"> 
<option  value="a">野菜1</option>
<option  value="b">野菜2</option>
<option  value="c">野菜3</option>  
</select>
<select  id="abs1">  
<option  value="x">吸収力弱</option> 
<option  value="y">吸収力中</option> 
<option  value="z">吸収力強</option>   
</select><br /><br />

<select  style="width: 222.297px;" id="ve2" > 
<option  value="a">野菜1</option> 
<option  value="b">野菜2</option>
<option  value="c">野菜3</option>
</select>
<select  id="abs2">  
<option  value="x">吸収力弱</option> 
<option  value="y">吸収力中</option> 
<option  value="z">吸収力強</option>   
</select><br /><br />

<select  id="ve3" style="width: 222.297px;">  
<option  value="a">野菜1</option>  
<option  value="b">野菜2</option>  
<option  value="c">野菜3</option>    
</select>
<select  id="abs3">  
<option  value="x">吸収力弱</option> 
<option  value="y">吸収力中</option> 
<option  value="z">吸収力強</option>   
</select><br /><br />

<input  onclick="practice_sum()" id="sum" value="計算!" type="button">
<br />
計算結果(一人当たり)<br />
 <label>カロリー<output  id="aresulta">未入力計算</output></label><br />
 <label>ナトリウム<output  id="aresultb">未入力計算</output></label><br />
 <label>マグネシウム<output  id="aresultc">未入力計算</output></label><br />
計算結果(全員)<br />
 <label>カロリー<output  id="resulta">未入力計算</output></label><br />
 <label>ナトリウム<output  id="resultb">未入力計算</output></label><br />
 <label>マグネシウム<output  id="resultc">未入力計算</output></label>
計算結果(日数分)<br />
 <label>カロリー<output  id="sresulta">未入力計算</output></label><br />
 <label>ナトリウム<output  id="sresultb">未入力計算</output></label><br />
 <label>マグネシウム<output  id="sresultc">未入力計算</output></label>


<script>

function practice_sum() {
ve2 = document.getElementById("ve2").value; 
ve3 = document.getElementById("ve3").value; 
ve1 = document.getElementById("ve1").value; 
abs2 = document.getElementById("abs2").value; 
abs3 = document.getElementById("abs3").value; 
abs1 = document.getElementById("abs1").value; 

 if (ve1 == "a") { kcal1 = 100; na1 = 10; mg1 = 20; }
 if (ve1 == "b") { kcal1 = 20; na1 = 20; mg1 = 10; }
 if (ve1 == "c") { kcal1 = 30; na1 = 15; mg1 = 40; }
 if (ve2 == "a") { kcal2 = 100; na2 = 10; mg2 = 20; }
 if (ve2 == "b") { kcal2 = 20; na2 = 20; mg2 = 10; }
 if (ve2 == "c") { kcal2 = 30; na2 = 15; mg2 = 40; }
 if (ve3 == "a") { kcal3 = 100; na3 = 10; mg3 = 20; }
 if (ve3 == "b") { kcal3 = 20; na3 = 20; mg3 = 10; }
 if (ve3 == "c") { kcal3 = 30; na3 = 15; mg3 = 40; }
 if (abs1 == "x") { kcal1a = 1; na1a = 1; mg1a = 0.8; }
 if (abs1 == "y") { kcal1a = 1.2; na1a = 1.1; mg1a = 1.1; }
 if (abs1 == "z") { kcal1a = 1.3; na1a = 1.2; mg1a = 1.7; }
 if (abs2 == "x") { kcal2a = 1; na2a = 1; mg2a = 0.8; }
 if (abs2 == "y") { kcal2a = 1.20; na2a = 1.1; mg2a = 1.1; }
 if (abs2 == "z") { kcal2a = 1.30; na2a = 1.2; mg2a = 1.7; }
 if (abs3 == "x") { kcal3a = 1; na3a = 1; mg3a = 0.8; }
 if (abs3 == "y") { kcal3a = 1.2; na3a = 1.1; mg3a = 1.1; }
 if (abs3 == "z") { kcal3a = 1.3; na3a = 1.2; mg3a = 1.7; }


 keisan(kcal1, na1, mg1,kcal2, na2, mg2,kcal3, na3, mg3, kcal1a, na1a, mg1a, kcal2a, na2a, mg2a,kcal3a, na3a, mg3a)
 }
 function keisan(kcal1, na1, mg1,kcal2, na2, mg2,kcal3, na3, mg3, kcal1a, na1a, mg1a, kcal2a, na2a, mg2a,kcal3a, na3a, mg3a) {

var kcal1l = parseFloat(kcal1);    var  na1l = parseFloat( na1);    var  mg1l = parseFloat( mg1);    
var kcal2l = parseFloat(kcal2);    var  na2l = parseFloat( na2);    var  mg2l = parseFloat( mg2);    
var kcal3l = parseFloat(kcal3);    var  na3l = parseFloat( na3);    var  mg3l = parseFloat( mg3);    
var kcal1al = parseFloat(kcal1a);    var  na1al = parseFloat( na1a);    var  mg1al = parseFloat( mg1a);    
var kcal2al = parseFloat(kcal2a);    var  na2al = parseFloat( na2a);    var  mg2al = parseFloat( mg2a);    
var kcal3al = parseFloat(kcal3a);    var  na3al = parseFloat( na3a);    var  mg3al = parseFloat( mg3a);    



var a1l = parseFloat(document.getElementById("a1").value);    
var b1l = parseFloat(document.getElementById("b1").value);    

aresulta = (kcal1l*kcal1al+kcal2l*kcal2al+kcal3l*kcal3al);
if(aresulta > 99999999){
           document.getElementById("aresulta").value = 99999999;
 }else if (aresulta < 0){document.getElementById("aresulta").value = 0;
}else{ document.getElementById("aresulta").value = Math.floor(aresulta);
        } 

aresultb = (na1l*na1al+na2l*na2al+na3l*na3al)  ;
if(aresultb > 99999999){
           document.getElementById("aresultb").value = 99999999;
 }else if (aresultb < 0){document.getElementById("aresultb").value = 0;
}else{ document.getElementById("aresultb").value = Math.floor(aresultb);
        } 

aresultc = (mg1l*mg1al+mg2l*mg2al+mg3l*mg3al);
if(aresultc > 99999999){
           document.getElementById("aresultc").value = 99999999;
 }else if (aresultc < 0){document.getElementById("aresultc").value = 0;
}else{ document.getElementById("aresultc").value = Math.floor(aresultc);
        } 

resulta = (kcal1l*kcal1al+kcal2l*kcal2al+kcal3l*kcal3al)*a1l ;
if(resulta > 99999999){
           document.getElementById("resulta").value = 99999999;
 }else if (resulta < 0){document.getElementById("resulta").value = 0;
}else{ document.getElementById("resulta").value = Math.floor(resulta);
        } 

resultb = (na1l*na1al+na2l*na2al+na3l*na3al)*a1l  ;
if(resultb > 99999999){
           document.getElementById("resultb").value = 99999999;
 }else if (resultb < 0){document.getElementById("resultb").value = 0;
}else{ document.getElementById("resultb").value = Math.floor(resultb);
        } 

resultc = (mg1l*mg1al+mg2l*mg2al+mg3l*mg3al)*a1l ;
if(resultc > 99999999){
           document.getElementById("resultc").value = 99999999;
 }else if (resultc < 0){document.getElementById("resultc").value = 0;
}else{ document.getElementById("resultc").value = Math.floor(resultc);
        } 

sresulta = (kcal1l*kcal1al+kcal2l*kcal2al+kcal3l*kcal3al);
if(sresulta > 99999999){
           document.getElementById("sresulta").value = 99999999;
 }else if (sresulta < 0){document.getElementById("sresulta").value = 0;
}else{ document.getElementById("sresulta").value = Math.floor(sresulta);
        } 

sresultb = (na1l*na1al+na2l*na2al+na3l*na3al)  ;
if(sresultb > 99999999){
           document.getElementById("sresultb").value = 99999999;
 }else if (sresultb < 0){document.getElementById("sresultb").value = 0;
}else{ document.getElementById("sresultb").value = Math.floor(sresultb);
        } 

sresultc = (mg1l*mg1al+mg2l*mg2al+mg3l*mg3al);
if(sresultc > 99999999){
           document.getElementById("sresultc").value = 99999999;
 }else if (sresultc < 0){document.getElementById("sresultc").value = 0;
}else{ document.getElementById("sresultc").value = Math.floor(sresultc);
        } 

 }
 </script></div></div></span>
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • x_x

    2017/11/21 16:49

    Javaではなく、JavaScriptタグがついていますが、質問内容はJavaでしょうか?

    キャンセル

  • evine

    2017/11/21 16:58

    すみませんjavaのつもりでつけていました>< かといってjavaである必要もなく紛らわしいので外しておきます ご指摘ありがとうございますmm

    キャンセル

  • KSwordOfHaste

    2017/11/21 17:52 編集

    質問を拝見する限りではjavascriptのコード短縮が焦点でありjavaはからまない気がします。タイトルもjavascriptにした方がよくないでしょうか?それともこの複雑なjavascriptコードをサーバーサイドのjavaで簡潔に生成したいといった話が焦点なのでしょうか?

    キャンセル

  • evine

    2017/11/21 18:01

    逆になっていました; ありがとうございます修正します

    キャンセル

回答 2

checkベストアンサー

+3

簡単にまとめてこんな感じでは?
同じ処理が繰り返されているので関数にしたり繰り返し処理できる場所を見るければもっと簡易的になると思いますよ。

'use strict'
var kcal = {};
kcal["ve1"] = {};
kcal["ve2"] = {};
kcal["ve3"] = {};
kcal["ve1"]["a"] = {"kcal":100,"na":10,"mg":20};
kcal["ve1"]["b"] = {"kcal":20,"na":20,"mg":10};
kcal["ve1"]["c"] = {"kcal":30,"na":15,"mg":40};
kcal["ve2"]["a"] = {"kcal":100,"na":10,"mg":20};
kcal["ve2"]["b"] = {"kcal":20,"na":20,"mg":10};
kcal["ve2"]["c"] = {"kcal":30,"na":15,"mg":40};
kcal["ve3"]["a"] = {"kcal":100,"na":10,"mg":20};
kcal["ve3"]["b"] = {"kcal":20,"na":20,"mg":10};
kcal["ve3"]["c"] = {"kcal":30,"na":15,"mg":40};

var abs = {};
abs["abs1"] = {};
abs["abs2"] = {};
abs["abs3"] = {};
abs["abs1"]["x"] = {"kcal":1,"na":1,"mg":0.8};
abs["abs1"]["y"] = {"kcal":1.2,"na":1.1,"mg":1.1};
abs["abs1"]["z"] = {"kcal":1.3,"na":1.1,"mg":1.7};
abs["abs2"]["x"] = {"kcal":1,"na":1,"mg":0.8};
abs["abs2"]["y"] = {"kcal":1.2,"na":1.1,"mg":1.1};
abs["abs2"]["z"] = {"kcal":1.3,"na":1.1,"mg":1.7};
abs["abs3"]["x"] = {"kcal":1,"na":1,"mg":0.8};
abs["abs3"]["y"] = {"kcal":1.2,"na":1.1,"mg":1.1};
abs["abs3"]["z"] = {"kcal":1.3,"na":1.1,"mg":1.7};

function setVal(sel,val) {
  if(val > 99999999) {
    document.getElementById(sel).value = 99999999;
  }else if (val < 0) {
    document.getElementById(sel).value = 0;
  } else {
    document.getElementById(sel).value = Math.floor(val);
  }
}

function practice_sum() {
  var ve1  = document.getElementById("ve1");
  var ve2  = document.getElementById("ve2");
  var ve3  = document.getElementById("ve3");
  var abs1 = document.getElementById("abs1");
  var abs2 = document.getElementById("abs2");
  var abs3 = document.getElementById("abs3");
  var a1l = parseFloat(document.getElementById("a1").value);
  var b1l = parseFloat(document.getElementById("b1").value);
  var aresulta = ( parseFloat(kcal[ve1.id][ve1.value].kcal) * parseFloat(abs[abs1.id][abs1.value].kcal) ) +
                 ( parseFloat(kcal[ve2.id][ve2.value].kcal) * parseFloat(abs[abs2.id][abs2.value].kcal) ) +
                 ( parseFloat(kcal[ve3.id][ve3.value].kcal) * parseFloat(abs[abs3.id][abs3.value].kcal) );
  setVal("aresulta",aresulta);

  var aresultb = ( parseFloat(kcal[ve1.id][ve1.value].na) * parseFloat(abs[abs1.id][abs1.value].na) ) +
                 ( parseFloat(kcal[ve2.id][ve2.value].na) * parseFloat(abs[abs2.id][abs2.value].na) ) +
                 ( parseFloat(kcal[ve3.id][ve3.value].na) * parseFloat(abs[abs3.id][abs3.value].na) );
  setVal("aresultb",aresultb);

  var aresultc = ( parseFloat(kcal[ve1.id][ve1.value].mg) * parseFloat(abs[abs1.id][abs1.value].mg) ) +
                 ( parseFloat(kcal[ve2.id][ve2.value].mg) * parseFloat(abs[abs2.id][abs2.value].mg) ) +
                 ( parseFloat(kcal[ve3.id][ve3.value].mg) * parseFloat(abs[abs3.id][abs3.value].mg) );
  setVal("aresultc",aresultc);

  var resulta = aresulta*a1l ;
  setVal("resulta",resulta);

  var resultb = aresultb*a1l ;
  setVal("resultb",resultb);

  var sresulta = aresultc*a1l ;
  setVal("sresulta",sresulta);

  setVal("sresulta",aresulta);
  setVal("sresultb",aresultb);
  setVal("sresultc",aresultc);
}

質問のコードで

var b1l = parseFloat(document.getElementById("b1").value);


が使われていないので一応そのまま書いてます。

JSで小数点を扱うのは、注意が必要なのでお気を付けください。。

投稿 2017/11/21 19:08

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/11/21 22:05

    凄く助かります!ありがとうございました!このような表記が可能なのですね....
    頂いたものを参考に記述方法を勉強してみます!

    キャンセル

+3

NIAさんがコード例を回答しておられるので蛇足ですが、コードより考え方の参考として論理の断片を挙げてみます。

冗長性を減らすためには元になるデータを一か所にしかおかず、それに基づき全てを表現することがコツだと思います。JavascriptのObject(Map的なもの)とArrayを組み合わせ、野菜の属性やselect要素の名前一覧などを一か所におき、それらを通じて個々の要素を間接的にアクセスすれば冗長性が軽減できると思います。

var veSpecs = [
  { name: "野菜1", id: "a", cal: 100, ca: 10, mg: 20 },
  ...
];

var veSelectIds = [ "ve1", "ve2", "ve3" ];

// veSpecsとveSelectIdsから野菜のメニューのDOMを生成する
// 追記:当初「HTMLを生成する」と書きましたが「DOMを生成する」の間違いでした。スミマセン
function setupVeSelectElements() {
  veSelectIds.forEach(function (selectId) {
    var select = document.getElementById(selectId);
    var html = veSpecs.map(funciton (ve) {
      return `<option value="${ve.id}">${ve.name}</option>`
    })
    .join();
    select.innerHTML = html;
  });
}

function onLoad() {
  setupVeSelectElements();
  ...
} 

上記のようにすればHTMLに一々a,b,cのoptionを記述する必要はなくなります。

<body onload="onLoad()">
...
<select style="width: 222.297px;" id="ve1"></select>
<select  id="abs1"></select>
<select style="width: 222.297px;" id="ve2"></select>
<select  id="abs2"></select>
<select style="width: 222.297px;" id="ve3"></select>
<select  id="abs3"></select>

if文のところも同様にveSpecsなどを使って「間接的な参照」でコードを書けば同じコードの繰り返しからループに変更できます。例えば3つの野菜メニューの9行分のif文は次のように書けるでしょう。

veSelectIds.forEach(function (selectId) {
  var select = document.getElementById(selectId);
  var id = select.value;
  var ve = veSpecs.find(function (ve) { return ve.id === id; });
  // ve.cal, ve.ca, ve.mgなどに必要な情報がある
  ...なにかする
});

上記はHTMLのDOMリファレンスやArrayのリファレンスを見ながら書きましたがもし間違いがあったらスミマセン。

投稿 2017/11/21 19:16

編集 2017/11/21 22:39

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/11/21 22:07

    これだけ簡単に記述できるのですね!間接的な参照方法や色々と知識不足でした><
    今後参考にさせていただきます ありがとうございました!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

ただいまの回答率

91.36%

関連した質問

同じタグがついた質問を見る

  • HTML

    6165questions

    HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。