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

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

ただいまの
回答率

88.80%

Javascript: 動的にdocument.getElementByIdを生成する方法

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 1,395

nanase21

score 104

  let price_itme = $('#plan').children().length;
  //=> 要素が2つの時、document.getElementByIdを2つ生成したい
  for(let i=0;i<price_itme;i++){
    let dom1 = document.getElementById(`plan${i}`).style.display = "none";
    //let dom2 = document.getElementById(`plan${i}`).style.display = "none";
  }

実現したいこと

#planの配下にある、要素を取得して要素数分だけdocument.getElementByIdを生成したい。

困っていること
要素数分だけ、document.getElementByIdを生成する方法が分からない。

let arr = [];
for(let i=0;i<price_itme;i++){
    arr[i] = `document.getElementById(plan${i})`;
}
//=> ["document.getElementById(plan0)", "document.getElementById(plan1)"]

上記で、document. getElementByIdを生成することができました。
配列にdocumentを生成した場合、どのようにstyleを利かせばよいかご教示いただけると幸いです。

#plan
  select#sample.form-control name="select" onchange="SendAjax(this);" 
    option value="plan" id="item" data-price="plan"
      = 'item1'
    option value="plan2" id="item2" data-price="plan2"
      = 'item2'
    option value="plan3" id="item3" data-price="plan3"
      = 'item3'

  input type="text" value="plan1" id="plan"
  input type="text" value="plan2" id="plan1"
  input type="text" value="plan3" id="plan2"
//TODO: jsに書き換えたいな
  var plan_item = $('#plan').children().length;
  for(let i=0;i<plan_item;i++){
    //ここをどうにかしたい。
    document.getElementById(`plan${i}`).style.display = "none";
    document.getElementById(`plan${i}`).style.display = "none";
    document.getElementById(`plan${i}`).style.display = "none";
  }

  function SendAjax(obj)
  {
      // objはselectタグ
      let idx = obj.selectedIndex;
      let value = obj.options[idx].value // value
      let text = obj.options[idx].text; // apper text

      //ここもforで編集する予定
      const txt1 = document.getElementById("item");
      const txt2 = document.getElementById("item2");
      const txt3 = document.getElementById("item3");


      if(value != txt1.id || value != txt2.id || value != txt3.id)
      {
          txt1.style.display = "none";
          txt2.style.display = "none";
          txt3.style.display = "none";
      }
      if(value == txt1.id)
      {
          txt1.style.display = "block";
      }
      if(value == txt2.id)
      {
          txt2.style.display = "block";
      }
      if(value == txt3.id)
      {
          txt3.style.display = "block";
      }

      console.log(`TEXT: ${text} / VALUE: ${value}`);
      console.log(`txt_ID1: ${txt1.id}`);
  }

`

試していること

evalを使って、jsコードを生成しようとしたのですがシンタックスエラーになってしまいました。 もし原因についてお分かりでしたら、ご教示いただけると幸いです。

for (var i = 0; i < 2; i++) {
  eval("let arr" + i + "=" + "document.getElementById('" + `plan${i}` + "')" + ";");
}

//=> arr0をすると下記のエラーになってしまいます。
// VM546:1 Uncaught ReferenceError: arr0 is not defined
// at <anonymous>:1:1
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • nanase21

    2019/08/31 17:27

    該当箇所のコードをhtml(slim)も含めて全て載せました。
    やりたいこととしては、初期表示ではinputの要素を全て隠して、selectで選択したオプションに応じて該当するinputだけを表示する処理をイメージしています。

    キャンセル

  • Lhankor_Mhy

    2019/08/31 18:29

    とりあえず、maisumakunさんのコメントのとおり、配列には「document.getElementByIdの実行結果」を入れましょう。
    evalとか必要ないです。

    あとはループの範囲がおかしいのと、plan1が存在しないのが気になります。

    キャンセル

  • nanase21

    2019/08/31 18:47

    変に変数を作ろうとせずにdocument.getElementById(id${i} == 比較するもの)で比較し、該当したらdocument.getElementById(`id${i}`).style.display = "none";をするようにして解決できました。

    キャンセル

回答 3

checkベストアンサー

0

要素が2つの時、document.getElementByIdを2つ生成したい

そのままで問題ないのではないかと思います。ループが回れば、price_itmeの数だけgetElementByIdがk\実行されます。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/08/31 16:19

    (うまくいかないばあいは具体的に、どのようにうまく行かないのか書いていただければ幸いです)

    キャンセル

  • 2019/08/31 16:43

    質問に今できていることを追記しました。
    配列にdocumentを入れた時にcssを効かす方が分からないです。
    最終的なイメージとしては、デフォルトでは要素を非表示にして、selectで選択した項目に応じて表示する内容を変更したいと考えています。

    キャンセル

  • 2019/08/31 16:55 編集

    「document.getElementByIdという文字列」を入れるのではなくて、配列には「document.getElementByIdの実行結果」を入れましょう。

    (配列に入れていない元のコードでも、それぞれ取った要素に対してCSSが効いていると思うのですが、なにかおかしいのでしょうか)

    キャンセル

  • 2019/08/31 17:29

    質問に該当箇所のコードを全て載せました。
    最終的にやりたいこととしては、初期表示ではinputの要素を全て隠して、selectで選択したオプションに応じて該当するinputだけを表示する処理をイメージしています。

    キャンセル

0

回答依頼ありがとうございます。

気になる点が2点。

  • dom1 には "none" が入ってそうな気がします。
  • let はブロックスコープなので、for を抜けると参照できなくなりそうです。

生成自体はできていると思います。ただ、変数に納められていないと思いますので、適切に代入されてはいかがでしょうか。
ループを用いているので、配列に代入するのが無難なような気がします。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

jQuery を使用するならこれだけで消せると思いますよ。

$( '#plan > [id^="plan"]' ).hide();

動くサンプル:https://jsfiddle.net/cv3o8t14/


【属性セレクタ - CSS: カスケーディングスタイルシート | MDN】
https://developer.mozilla.org/ja/docs/Web/CSS/Attribute_selectors

【.hide() | jQuery API Documentation】
https://api.jquery.com/hide/

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

  • ただいまの回答率 88.80%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

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