Illust & Music 月の高いところ

今日のプリン言

謎のプリン語る。
一人書く人増えました。

JavaScript、イベント付きDOMの操作

2016年05月24日

みやびプリン 140 87

500 320

JavaScript、イベント付きDOMの操作 - サムネイル

※この記事は4年以上前の記事です。
現在は状況が異なる可能性がありますのでご注意ください。

どうも、スープカレーが目に入って死ぬかと思ったみやびです。
まじで染みるわ。

さて、
最近、jQueryとかライブラリ使わないでネイティブのJSに挑戦してるのですが、
その中でもDOM操作ってのが、けっこう難しいんだよ、ネイティブはさ。

ただ、jQueryなどのライブラリでDOM操作をするのは実は重い。
スマホなどの低スペックデバイスだと、けっこう悲鳴を上げたりする。
そんな中、ネイティブの有用なメソッドに、DocumentFragmentというのがある。
これは、通常一個一個DOMを挿入していかねばならんのを、予め、DOMの塊を生成することができるってやつ。
DOMって、操作する度にブラウザがレンダリングするので、無駄にメモリを食う。
なので、DOMの塊を予め作っておいて、一気に挿入、レンダリングは一回で!ってやることで、パフォーマンスの向上になるわけ。

●普通のやり方

var targetDOM = document.getElementById('targetID');//ulタグ
for(var i = 0; i < 1000; i++){
  var innerLi = document.createElement('li');//liタグ生成
  innerLi.textContent = i + '個目どすえ';//テキスコ
  targetDOM.appendChild(innerLi);
}

これだと、一回入れるたんびにブラウザがレンダリングしる。
まぁ、途中jQuery使っても同じく一個入れるたびにブラウザはレンダリングする。

●DocumentFragmentを使った場合

var targetDOM = document.getElementById('targetID');//ulタグ
var fragmentDOM = document.createDocumentFragment();//Fragmentオブジェクトの生成
for(var i = 0; i < 1000; i++){
  var innerLi = document.createElement('li');//liタグ生成
  innerLi.textContent = i + '個目どすえ';//テキスコ
  fragmentDOM.appendChild(innerLi);
}
targetDOM.appendChild(fragmentDOM);

こうすることによって、レンダリングは最後の一回だけってわけ。
けっして便利ではないけど、パフォーマンスの向上にはなります。

さてこっからが本題 (なげーよ前置きが)

ネイティブでのDOM操作の方が、軽くする方法があり、ライブラリを読み込むことによるパフォーマンスの低下も防げる。
前述した、DocumentFragmentなんてのは、特にスマホでどんどん使っていきたいものだ。
だが、やはり一から自分で書くのはけっこうきつい。
例えば、イベントをつけたDOMをいったんコピーし、別のところに入れたい時。
下記の方法では当然イベントはコピーされない。

var btnElement = document.getElementById('testBtn');
$(btnElement).click(function(){
  console.log('クリックイベントつけるにjQuery使っちゃってるのはめんどくさいからです。');
});
var wrapperTarget = document.getElementById('targetDOM');
var copyBtn = btnElement.cloneNode(true);//ボタンのコピーを生成
btnElement.parentNode.removeChild(btnElement);//ボタンを削除しちゃう
wrapperTarget.appendChild(copyBtn);//ターゲットにボタンのコピーを入れる

当然押してもなんもならん。
うん、そうだと思ったよ。
多分、付与されてるイベント検索して、
再付与しなきゃいけないだろう。
そうだろうよ。
だからね、あきらめたよ。

便利な部分はjQuery使おう

ってね。

var btnElement = document.getElementById('testBtn');
$(btnElement).click(function(){
  console.log('クリックイベントつけるにjQuery使っちゃってるのはめんどくさいからです。');
});
var wrapperTarget = document.getElementById('targetDOM');
var copyBtn = $(btnElement).clone(true);//jQueryでボタンのコピーを生成
btnElement.parentNode.removeChild(btnElement);//ボタンを削除しちゃう
$(wrapperTarget).append(copyBtn);//ターゲットにボタンのコピーを入れる。(もちろんjQueryで)

こんなとこくでぇでパフォーマンス落ちんべ。
→いや、読み込んでる時点で(以下ry

というわけで、パフォーマンス向上を目指す中でも、
落ちないような場所にはライブラリ積極的に使っていきましょうって話でした。

LINEスタンプを格安で制作します!【スタンプファクトリー】 - メイン

トラックバック(0)

トラックバックURL:

コメントする