スマートフォンUI 要素並び替え(配列複製)JavaScript cloneNode
2013.04.06
この記事は最終更新日から1年以上が経過しています。
最近良くあるなと思うのが、「要素(DOM)を入れ替えたい」と言った要件だったりもします。
ソーシャルゲームなんかになるとカード画像を入替え。とかになりますかね。
以下の様な並びだとして、
タップ→タップで入替え。とか、タップ→スライドで入替え。
だったり。
そんなとき、JavaScript でcloneNode を使えば実現は可能かと思います。
タッチやクリックで要素をelemA、elemBの要素を取得し、
var newElemA = elemA.cloneNode(true), newElemB = elemB.cloneNode(true); elemA.parentNode.replaceChild( newElemB, elemA ); elemB.parentNode.replaceChild( newElemA, elemB. );
ちなみにreplaceChildに関しては以下の様に第一引数に新しい要素、第二引数に古い要素を代入。
replacedNode = parentNode.replaceChild(newChild, oldChild);
newChild: oldChild を置き換える新しいノード
oldChild: newChild に置き換えるノード
replacedNode: 置き換えられたノード
とここまでは、問題ないかと思われますが、複数cloneしたい。つまり配列でcloneしたいってなった時、
シンプルな配列であれば、
var defaultItem,cloneItem; defaultItem = ["a","b","c"]; cloneItem = []; for (var i=0, l = defaultItem.length; i < l; i++) { cloneItem[i] = defaultItem[i]; } <p>console.log(cloneItem);</p>
console
["a","b","c"]
var defaultItem,cloneItem; defaultItem = ["a","b","c"]; cloneItem = []; for (var i = 0, l = defaultItem.length; i < l; i++) { cloneItem[i] = defaultItem[i]; } defaultItem[3] = "d"; cloneItem[3] = "e"; console.log(defaultItem); console.log(cloneItem);
["a","b","c","d"]["a","b","c","e"]
とできますが、クローンするとなると、
var defaultItem = ["a","b","c","d"], cloneItem; for (var i = 0, l = defaultItem.length; i < l; i++) { cloneItem = item[i].cloneNode(true); }
こんな風にfor文でまわしてもコピーされないわけで、、、困ったちゃんですね。
そこで、ArrayのPrototypeにcloneを追加し、再起させるやり方となります。
Array.prototype.clone = function() { if ( this[0].constructor == Array ) { var arr, i; arr = new Array( this.length ); for ( i = 0; i < ar.length; i++ ) { arr[i] = this[i].clone(); } return arr; } return Array.apply( null, this ); }
自分自身(コンストラクタ)が配列かどうかをチェックし、新しい配列を作成します。配列の数だけ更に配列として作成。それを返す事によって複数(配列として)cloneすることが出来ます。
applyはcallと似ていますが、thisの値を変更することが出来ます。null
か undefined
が指定された場合は this
の値は global object になりますので、clone自身もグローバルオブジェクトとして扱われます。
では確認してみましょうー!
var cloneItem = new Array(); defaultItem = ["a","b","c","d"]; cloneItem = defaultItem.clone(); console.log(cloneItem);
console.logを確認すると。お、良い感じですね。
Array.prototype.clone = function() { if ( this[0].constructor == Array ) { var arr, i; arr = new Array( this.length ); for ( i = 0; i < ar.length; i++ ) { arr[i] = this[i].clone(); } return arr; } return Array.apply( null, this ); } var li = document.querySelectorAll("ul > li"); var cloneItem = new Array(); defaultItem = [li]; cloneItem = defaultItem.clone(); console.log(cloneItem);
domをcloneさせてみると、
といった感じに配列でクローン出来ているのが確認できると思います。