質問: accrodionTrigger.cloneNode(true);` 2for文の外に書いてみる。 ### エラー内容 Cannot read property 'cloneNode' of undefined at window.onload 引き続き調べを進めますが、 何かヒントなどいただければ嬉しいです。
回答: `const accrodionItemsCopy = this.nextElementSibling.cloneNode(true);` ここでおもむろに `this.nextElementSibling` が登場していますが、こういう登場の仕方をしたときの `this` は `window` を指します。`this` はどういう登場の仕方をするかによって取り回しが違います。これを話し始めると長くなるので詳細は必要に応じてググっていただこうと思います。 つまり、こうなります。 ``` this.nextElementSibling // -> window.nextElementSibling ``` で、残念ながら `window` に `nextElementSibling` などというプロパティは無いので、 こうなります。 ``` this.nextElementSibling // -> window.nextElementSibling // -> undefined ``` `undefined` に `cloneNode()` などというメソッド(or プロパティ) はないですよ、というのがそのエラーの内容です。 forループの中で `accrodionItemsCopy` を宣言している行を、こう書き換えたら動きませんでしょうか。 ``` const accrodionItemsCopy = accrodionTrigger[i].nextElementSibling.cloneNode(true); // もしくは const accrodionItemsCopy = accrodionItems[i].cloneNode(true); ``` ここまでが回答です。 ここから先は余談というか、読まなくても別にいいのですが...... アコーディオンを実現するためにいちいちノードをコピーするのは、まあ大した負荷ではないのですが、スマートではないと思います。当時は確かにJavaScriptで要素の高さを調べて、高さを徐々に0にしたり本来の高さにしたりしてニュルっと動くアニメーションを作るしかなかったのですが、最近では長々とコードを書かなくてもCSSだけ(あるいはアニメーションはCSSで定義、アニメーションさせるためのクラスを付けたり外したりするのをJavaScriptでやったり)でアコーディオンを実装できたりしますので、モダンな書き方というか、最近の流行りを探ってみるとよいかなと思います。