ラボ > Javascript関連:DOM関連
javascriptで要素を追加したい(createElement、createTextNode、createElementNSなど)
タグじゃなくてテキストを追加したいときにcreateElementだと出来ない…ついでに複製方法も。
作成日:2024-03-29, 更新日:2024-03-29
HTMLを追加: createElement
let elm = document.createElement('div');
テキストを追加: createTextNode
let elm = document.createTextNode('丸ごとシマウマ');
名前空間を持つ要素(SVGやXMLなど): createElementNS
let elm = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
コメントノード(<!-- xxx -->): createComment
let elm = document.createComment('丸ごとシマウマ');
要素の複製: cloneNode
let orig = document.querySelector('.xxx'); let shallow_elm = orig.cloneNode(false); let deep_elm = orig.cloneNode(true);
cloneNode()の引数
子要素ごと複製、親要素のみ複製と振り分けが可能
複製元にする要素のサンプル
let elm_label_choiceFile = document.createTextNode('写真・動画を選択'); let elm_ipt_choiceFile = document.createElement('input'); elm_ipt_choiceFile.setAttribute('type', 'file'); elm_ipt_choiceFile.setAttribute('name', 'choiceFile'); elm_ipt_choiceFile.setAttribute('accept', 'image/*, video/*'); elm_ipt_choiceFile.oninput = function(){ alert('xxx'); } let elm_formSample = document.createElement('div'); elm_formSample.appendChild(elm_label_choiceFile); elm_formSample.appendChild(elm_ipt_choiceFile);
親要素だけ複製(shallow clone): cloneNode(false)
この場合だと「div」のみ複製
let shallow_elm = orig.cloneNode(false);
子要素ごと複製(deep clone): cloneNode(true)
この場合だと「div」の子にある「写真・動画を選択」や「inputタグ」、inputタグのイベントも複製
let deep_elm = orig.cloneNode(true);
cloneNode()で複製した要素の修正
let elm_label_choiceFile = document.createTextNode('写真・動画を選択'); let elm_ipt_choiceFile = document.createElement('input'); elm_ipt_choiceFile.setAttribute('type', 'file'); elm_ipt_choiceFile.setAttribute('name', 'choiceFile'); elm_ipt_choiceFile.setAttribute('accept', 'image/*, video/*'); elm_ipt_choiceFile.oninput = function(){ alert('xxx'); } let elm_formSample = document.createElement('div'); elm_formSample.appendChild(elm_label_choiceFile); elm_formSample.appendChild(elm_ipt_choiceFile); document.body.appendChild(elm_formSample); let elm_form_TakePic = elm_form_choiceFile.cloneNode(true); elm_form_TakePic.childNodes[0].textContent = '写真を撮る'; // テキストノードは…取得できないので子ノードから取得 // let elm_ipt_TakePic = elm_form_TakePic.childNodes[1]; // こっちでもいける。メンテナンス(元のほうで順番を変更したりするかも…)を考えると避けたい let elm_ipt_TakePic = elm_form_TakePic.querySelector('input'); elm_ipt_TakePic.setAttribute('capture', 'camera'); elm_ipt_TakePic.setAttribute('accept', 'image/*'); document.body.appendChild(elm_form_TakePic); // elm_ipt_TakePicじゃなく、元になるelm_form_TakePicを追加
テンポラリデータの作成: createDocumentFragment
let elm_temporary = document.createDocumentFragment();
使い道は…
- ループなどで何個も要素を追加したいとき - 一つの要素ずつ描画するのではなく、まとめて描画
- 複雑なHTMLなどを追加したい - タイトルを描画後、本文を描画して、さらにボタンを描画じゃなく、まとめて描画
- テンプレートにしたい - 使いまわすことが可能。cloneNode()を合わせれば色々と出来そう…
使い道: ループなどで何個も要素を追加したいとき
createDocumentFragmentを使うと描画が一回だけになる
createDocumentFragmentを使わない場合
「document.body.appendChild()」で毎回、描画が行われるのでパフォーマンスが落ちる
for (let i = 0; i < 10; i++) { let newElement = document.createElement('p'); newElement.textContent = 'Paragraph ' + i; document.body.appendChild(newElement); }
createDocumentFragmentを使う場合
「document.body.appendChild()」の描画が1回だけなのでパフォーマンスがあまり落ちない
let elm_temporary = document.createDocumentFragment(); for (let i = 0; i < 10; i++) { let newElement = document.createElement('p'); newElement.textContent = 'Paragraph ' + i; elm_temporary.appendChild(newElement); } document.body.appendChild(elm_temporary);