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

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

ただいまの
回答率

90.50%

  • JavaScript

    20440questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • HTML

    11521questions

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

  • CSS

    7561questions

    CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

  • HTML5

    5136questions

    HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

  • ECMAScript

    143questions

    ECMAScriptとは、JavaScript類の標準を定めるために作られたスクリプト言語です。

[JavaScript] DOMで追加した特定の要素を、特定して削除したい(ライブラリもフレームワークも使わずに)

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 565

myuchan15

score 1

素のJavaScriptを使用し、DOMで追加したdiv要素を、
ライブラリもフレームワークも使わずに、
削除をするボタンで削除したいのですが、
DOMを作成する際、同じボタンでDOMを追加するので何個も同じDOMが出来上がる仕様となっています。
なので同じdivが何個もできるため、消したいdivを特定するやり方で、
何か良い方法がないかと思案しています。

考えているのが、
DOMで作成する際、idに、ボタンを押すたびに異なる番号が振られるようにして0. 番号リスト
(1回目に押したら id="id1" 2回目に押したら id="id2 のような感じ)
削除ボタンを押した際は、そのボタンでidを特定して、特定したidのものだけを削除するという
方法かなと思っているのですが、どのようにすればできるのか悩んでいます。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="css/styles.css">
    <title>お買い物リスト</title>
  </head>
  <body>
    <div id="container">
        <div id="border">
          <button id="aaa" type="button">AAA</button>
          <button id="bbb" type="button">BBB</button>
      </div>
      <span id="spa"></span>
    </div>
    <script src="js/main.js"></script>
  </body>
</html>
aaa.onclick = function() {
  var div = document.createElement('div');
  div.id = 'div';
  spa.appendChild(div);
  var aas = document.createElement('select');
  aas.id = 'aas';
  div.appendChild(aas);

  var del = document.createElement('button'); // 削除ボタン生成
  del.className = 'del';
  var saku = document.createTextNode('削除');
  del.appendChild(saku);
  div.appendChild(del);

del.onclick = function() {
  var e = document.getElementById('div');
  e.parentNode.removeChild(e);
  };

  var opta = document.createElement('option');
  opta.value = 'item';
  var senta = document.createTextNode('--------------AAA--------------');
  opta.appendChild(senta);
  aas.appendChild(opta);

  var optap = document.createElement('option');
  optap.value = 'apple';
  var apple = document.createTextNode('りんご');
  optap.appendChild(apple);
  vegi.appendChild(optap);

  var optmi = document.createElement('option');
  optmi.value = 'mikan';
  var mikan = document.createTextNode('みかん');
  optmi.appendChild(mikan);
  vegi.appendChild(optmi);
};


drink.onclick = function() {
  var div = document.createElement('div');
  div.id = 'div';
  spa.appendChild(div);
  var drink = document.createElement('select');
  drink.className = 'dr';
  div.appendChild(drink);
  var del = document.createElement('button'); // 削除ボタン生成
  del.className = 'del';
  var saku = document.createTextNode('削除');
  del.appendChild(saku);
  div.appendChild(del);

  var optdr = document.createElement('option');
  optdr.value = 'item';
  var senta = document.createTextNode('--------------BBB--------------');
  optdr.appendChild(senta); //
  drink.appendChild(optdr);

  var optmi = document.createElement('option');
  optmi.value = 'milk';
  var milk = document.createTextNode('牛乳');
  optmi.appendChild(milk);
  drink.appendChild(optmi);
};
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • x_x

    2019/02/06 14:09

    ```JavaScript
    コード
    ```
    などのように囲めば(Markdown記法)、言語に合わせて見やすくなるので修正お願いします

    キャンセル

  • Lhankor_Mhy

    2019/02/06 14:51

    変数 vegi には何が入っていますか?

    キャンセル

  • Lhankor_Mhy

    2019/02/06 14:53

    あと、変数 drink も未定義のまま使われているようです。

    キャンセル

  • myuchan15

    2019/02/06 15:48

    ご指摘ありがとうございます。今後はコードの部分を見やすくMarkdown記法で記述したいと思います。
    他の方にお教えいただいたやり方で解決しましたので、解決済みとしたいと思います。
    ありがとうございました。また何かありましたらよろしくお願いいたします。

    キャンセル

回答 4

checkベストアンサー

+2

まず、ソースコードは、質問投稿の中に、ツールとして、
<code>というボタンがあるので、それを使用して記載しましょう。
DOMコントロールをしたりなどのライブラリとしては、jQueryが有名ですが、
あくまで、JavaScriptを使用しやすく、短いコードでも機能を使えるようにしたものなので、
もともとJavaScriptの機能として存在するものです。

なので、DOMコントロールはネイティブでも十分可能ですよ。

それと、考え方として、
IDは一意の存在にすべきで、同じIDの要素を、たとえ動的にだったとしても、作成すべきではありません。
質問の中でおっしゃっている通り、一つ一つに、一意のIDを割り振るべきでしょう。
同じような要素を生成するなら、classを共通にすべきでしょう。

また、今回のケースだと、消したいdivの子要素のボタンを押すと、divを消すという挙動なので、
idを割り振る必要性がないかと思います。
ボタンの親を取得して、その親を削除、とすればいいので。

下記でいかがでしょうか。
(一応、一意のidを割り振るようにしております。)

// まず、ボタン要素を取ってくる
var aaa = document.getElementById('aaa'),
  drink = document.getElementById('bbb'),
  spa = document.getElementById('spa');

// 一意とするため、番号変数を用意しておく
var aaaCount = 0,
  bbbCount = 0;

aaa.onclick = function() {
  var div = document.createElement('div');
  var idInner = 'divA' + aaaCount;
  div.id = idInner;
  spa.appendChild(div);

  var aas = document.createElement('select');
  var aasId = 'aas' + aaaCount;
  aas.id = aasId;
  div.appendChild(aas);

  var del = document.createElement('button'); // 削除ボタン生成
  // ライブラリを使わないということなので、ネイティブでクラスを追加
  del.classList.add('del');
  var saku = document.createTextNode('削除');
  // 削除するIDを特定するために、ボタンのdata属性にIDを格納しておきます
  // data系をセットするとき、datasetという属性も使えますが、IEの下位互換のために、setAttributeを使用しています
  del.setAttribute('data-target', idInner);
  del.appendChild(saku);
  div.appendChild(del);

  del.onclick = function() {
    var e = del.parentNode;
    e.parentNode.removeChild(e);
  };

  var opta = document.createElement('option');
  opta.value = 'item';
  var senta = document.createTextNode('--------------AAA--------------');
  opta.appendChild(senta);
  aas.appendChild(opta);

  var optap = document.createElement('option');
  optap.value = 'apple';
  var apple = document.createTextNode('りんご');
  optap.appendChild(apple);
  // vegiが未定義のため、上のselect要素と仮定します。
  aas.appendChild(optap);
  // vegi.appendChild(optap);

  var optmi = document.createElement('option');
  optmi.value = 'mikan';
  var mikan = document.createTextNode('みかん');
  optmi.appendChild(mikan);
  aas.appendChild(optap);
  // vegi.appendChild(optmi);

  // 一意のidを足してく
  aaaCount++;
};

drink.onclick = function() {
  var div = document.createElement('div');
  var idInner = 'divB' + bbbCount;
  div.id = idInner;
  spa.appendChild(div);

  var drinkSelect = document.createElement('select');
  // ライブラリを使わないということなので、ネイティブでクラスを追加
  drinkSelect.classList.add('dr');
  div.appendChild(drinkSelect);

  var del = document.createElement('button'); // 削除ボタン生成
  del.classList.add('del');
  var saku = document.createTextNode('削除');
  // aaa同様に、data属性を追加
  del.setAttribute('data-target', idInner);
  del.appendChild(saku);
  div.appendChild(del);

  // aaaでも指定している通り、こちらでもクリックイベントを付与しなくてはならない
  // 現状のスクリプトの書き方だと、生成したDOM毎にクリックイベントを付与する必要がある
  del.onclick = function() {
    var e = del.parentNode;
    e.parentNode.removeChild(e);
  };

  var optdr = document.createElement('option');
  optdr.value = 'item';
  var senta = document.createTextNode('--------------BBB--------------');
  optdr.appendChild(senta); //
  drinkSelect.appendChild(optdr);

  var optmi = document.createElement('option');
  optmi.value = 'milk';
  var milk = document.createTextNode('牛乳');
  optmi.appendChild(milk);
  drink.appendChild(optmi);

  // 一意のidを足してく
  bbbCount++;
};

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/02/06 15:29

    ご丁寧にありがとうございます。やりたいことができました。
    とても参考になりました。
    ありがとうございました!!

    キャンセル

+2

私ならクロージャを使います。
サンプル

aaa.onclick = function() {
  var div = document.createElement('div');
  div.id = 'div';
  spa.appendChild(div);
  var aas = document.createElement('select');
  aas.id = 'aas';
  div.appendChild(aas);

  var del = document.createElement('button'); // 削除ボタン生成
  del.className = 'del';
  var saku = document.createTextNode('削除');
  del.appendChild(saku);
  div.appendChild(del);

  del.onclick = function() {
    div.parentNode.removeChild(div);   //  ← 変更点はここ
  };

  var opta = document.createElement('option');
  opta.value = 'item';
  var senta = document.createTextNode('--------------AAA'+Math.random()+'--------------');   // わかりやすくするためちょっと変更しました。
  opta.appendChild(senta);
  aas.appendChild(opta);

};

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/02/06 15:15

    横槍失礼します。
    クロージャで十分ですよね。
    むしろ、同じ処理なのに二つ続いてるクリックイベントもひとまとめにしたい。

    キャンセル

  • 2019/02/06 15:30

    このような方法もあるのですね。勉強になります。
    今後の参考にしたいと思います。
    ありがとうございました。

    キャンセル

+2

<html>
<head>
<meta charset="UTF-8">
<style></style>
<body>
<title>お買い物リスト</title>
</head>
<body>
<div id="container">
<div id="border">
<button id="aaa" type="button">AAA</button>
<button id="bbb" type="button">BBB</button>
</div>
<div id="spa"></div>
</div>


<script>

const
  A = (e, n) => {do{if(e.tagName===n) break}while(e=e.parentNode);return e},
  B = (...ns) => ns.map (n => document.createElement (n)),
  C = (...a) => a.reduce ((b,[c,d=c]) => { b.appendChild (new Option (c, d)); return b},
      document.createDocumentFragment ()),
  D = (a, b) => [...Object.entries (b)].forEach (([c,d])=>a[c]=d);


const
  SPA = document.getElementById('spa');


function aaa () {
  let [div, button, select] = B ('div', 'button', 'select');
  D (button, { textContent: '削除' });
  select.appendChild (C(['--------------AAA--------------',''], ['りんご'], ['みかん']));
  SPA.appendChild (div);
  div.appendChild (select);
  div.appendChild (button);
}

function bbb () {
  let [div, button, select] = B ('div', 'button', 'select');
  D (button, { textContent: '削除' });
  select.appendChild (C(['--------------BBB--------------',''], ['牛乳']));
  div.appendChild (select);
  div.appendChild (button);
  SPA.appendChild (div);
}


function del (e) {
  let t = A (e, 'DIV');
  if (t) t.remove ();
}

function handler ({target: e}) {
  let { id } = e;
  if (/^(aaa|bbb)$/.test (id)) window[id]();
  else if ('BUTTON' === e.tagName) if ('削除' === e.textContent) del (e);
}

document.addEventListener ('click', handler, false);


</script>

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/02/07 11:01

    配列でまとめていただいてありがとうございます。勉強になります!
    アロー関数も今後勉強しなきゃと思っていたので、ありがたいです。
    今後も何かありましたら、よろしくお願いいたします。

    キャンセル

+1

//copy from https://qiita.com/coa00/items/679b0b5c7c468698d53f
function getUniqueStr(myStrong){
 var strong = 1000;
 if (myStrong) strong = myStrong;
 return new Date().getTime().toString(16)  + Math.floor(strong*Math.random()).toString(16)
}

aaa.onclick = function() {
var div = document.createElement('div');
let idstr = getUniqueStr(); //これ追加
div.id = idstr; // これ改変
spa.appendChild(div);
//中略
del.className = 'del';
del.dataset.ref = idstr; //これ追加
var saku = document.createTextNode('削除');
//中略
del.onclick = function() {
var e = document.getElementById(this.dataset.ref); //これ改変
e.parentNode.removeChild(e);
};

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/02/06 15:25

    ありがとうございます。やりたいことができました。
    とても参考になりました。m(_ _)m

    キャンセル

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

  • JavaScript

    20440questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • HTML

    11521questions

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

  • CSS

    7561questions

    CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

  • HTML5

    5136questions

    HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

  • ECMAScript

    143questions

    ECMAScriptとは、JavaScript類の標準を定めるために作られたスクリプト言語です。