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

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

新規登録して質問してみよう
ただいま回答率
85.35%
JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

2回答

1822閲覧

各要素にn個ずつdivで囲んだpを配置できない

erp

総合スコア46

JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

0グッド

2クリップ

投稿2021/10/16 15:08

編集2021/10/18 23:10

前提・実現したいこと

jQuery からネイティブ js への書き換えを行っています。

発生している問題・エラーメッセージ

要素それぞれに、5つずつdivで囲んだpを配置したいのですが、appendChild が上手くいきません。
ブロック内が空っぽのままになってしまいます。
エラーは特にないです。

該当のソースコード

書き換え前

js

1$('.cc').each(function () { 2 do { 3 $(this).children("p:lt(5)").wrapAll('<div></div>') 4 } while ($(this).children("p").length); 5})

生 js に書き換え

js

1let title = document.querySelectorAll(".cc p"), 2 titles = document.querySelectorAll('.cc'), 3 length_02 = title.length; 4 for (var i = 0; i < length_02; i++) { 5 if (i % 5 === 0) { 6 var div = document.createElement('div'); 7 }; 8 div.appendChild(title[i]); 9 if (i % 5 === 4) { 10 titles.forEach(function (til) { 11 til.appendChild(div); 12 }); 13 } 14 }; 15 titles.forEach(function (til) { 16 til.appendChild(div); 17 });

元のHTML

html

1<div class="cc"> 2 <p>The quick brown fox jumps over the lazy dog</p> 3 <p>The quick brown fox jumps over the lazy dog</p> 4 <p>The quick brown fox jumps over the lazy dog</p> 5 <p>The quick brown fox jumps over the lazy dog</p> 6 <p>The quick brown fox jumps over the lazy dog</p> 7 <p>The quick brown fox jumps over the lazy dog</p> 8 <p>The quick brown fox jumps over the lazy dog</p> 9 <p>The quick brown fox jumps over the lazy dog</p> 10 <p>The quick brown fox jumps over the lazy dog</p> 11 <p>The quick brown fox jumps over the lazy dog</p> 12</div> 13<div class="cc"> 14 <p>The quick brown fox jumps over the lazy dog</p> 15 <p>The quick brown fox jumps over the lazy dog</p> 16 <p>The quick brown fox jumps over the lazy dog</p> 17 <p>The quick brown fox jumps over the lazy dog</p> 18 <p>The quick brown fox jumps over the lazy dog</p> 19 <p>The quick brown fox jumps over the lazy dog</p> 20 <p>The quick brown fox jumps over the lazy dog</p> 21 <p>The quick brown fox jumps over the lazy dog</p> 22 <p>The quick brown fox jumps over the lazy dog</p> 23 <p>The quick brown fox jumps over the lazy dog</p> 24</div>

想定しているHTML

HTML

1<div class="cc"> 2 <div> 3 <p>The quick brown fox jumps over the lazy dog</p> 4 <p>The quick brown fox jumps over the lazy dog</p> 5 <p>The quick brown fox jumps over the lazy dog</p> 6 <p>The quick brown fox jumps over the lazy dog</p> 7 <p>The quick brown fox jumps over the lazy dog</p> 8 </div> 9 <div> 10 <p>The quick brown fox jumps over the lazy dog</p> 11 <p>The quick brown fox jumps over the lazy dog</p> 12 <p>The quick brown fox jumps over the lazy dog</p> 13 <p>The quick brown fox jumps over the lazy dog</p> 14 <p>The quick brown fox jumps over the lazy dog</p> 15 </div> 16</div> 17<div class="cc"> 18 <div> 19 <p>The quick brown fox jumps over the lazy dog</p> 20 <p>The quick brown fox jumps over the lazy dog</p> 21 <p>The quick brown fox jumps over the lazy dog</p> 22 <p>The quick brown fox jumps over the lazy dog</p> 23 <p>The quick brown fox jumps over the lazy dog</p> 24 </div> 25 <div> 26 <p>The quick brown fox jumps over the lazy dog</p> 27 <p>The quick brown fox jumps over the lazy dog</p> 28 <p>The quick brown fox jumps over the lazy dog</p> 29 <p>The quick brown fox jumps over the lazy dog</p> 30 <p>The quick brown fox jumps over the lazy dog</p> 31 </div> 32</div>

試したこと

forEach で囲むと空っぽになってしまいます。
document.querySelector('.cc') にして titles.appendChild(div) にすると一番最初の .cc に全部出力されるので、他のコードは合っています。

どうすればループさせることができますでしょうか。

js

1for (let cc of document.querySelectorAll('.cc')) { 2 let tp = [...cc.children].filter(child => child.matches('p')); 3 if (tp.length > 0) { 4 let div = document.createElement('div'); 5 for (let i = 0; i < 5; i = i + 1) { 6 div.appendChild(tp[i]); 7 cc.appendChild(div); 8 } 9 } 10 }

としたところ最初の5つしかdivで囲まれませんでした。

js

1for (let cc of document.querySelectorAll('.cc')) { 2 let tp = [...cc.children].filter(child => child.matches('p')); 3 if (tp.length > 0) { 4 while (tp.length) { 5 let div = document.createElement('div'); 6 for (let i = 0; i < 5; i = i + 1 ) { 7 div.appendChild(tp[i]); 8 cc.appendChild(div); 9 } 10 }; 11 } 12 }

としたところ、重すぎてページが読み込まれませんでした。

js

1for (let cc of document.querySelectorAll('.cc')) { 2 let tp = [...cc.children].filter(child => child.matches('p')); 3 tp = tp.slice(5); 4 for (let p of tp.slice(0, 5)) { 5 let div = document.createElement('div'); 6 for (let i = 0; i < 5; i = i + 1) { 7 div.appendChild(tp[i]); 8 }; 9 cc.appendChild(div); 10 }; 11 }

としたところ、.cc の初めの5つのpのみ、divで囲まれた状態になりました。
エラーは以下です。

error

1Node.appendChild: Argument 1 is not an object.

js

1for (let cc of document.querySelectorAll('.cc')) { 2 let tp = [...cc.children].filter(child => child.matches('p')); 3 for (let p of tp.slice(0, 5)) { 4 tp = tp.slice(5); 5 if (tp.length > 0) { 6 while (tp.length) { 7 let div = document.createElement('div'); 8 cc.appendChild(div); 9 div.appendChild(tp); 10 } 11 } 12 }; 13 }

としたところ、

error

1Node.appendChild: Argument 1 is not an object.

とエラーが出てしまいました。div.appendChild(tp);のところです。
何が違うのでしょうか。

js

1for (let cc of document.querySelectorAll('.cc')) { 2 let tp = [...cc.children].filter(child => child.matches('p')); 3 for (let p of tp.slice(0, 5)) { 4 if (tp.length > 0) { 5 while (tp.length) { 6 let div = document.createElement('div'); 7 cc.appendChild(div); 8 tp = tp.slice(5); 9 div.appendChild(tp); 10 } 11 } 12 }; 13 }

としたところ、

error

1Node.appendChild: Argument 1 is not an object.

とエラーが出てしまいました。div.appendChild(tp); のところです。
tp の値が違うのでしょうか。

補足情報(FW/ツールのバージョンなど)

firefox 最新版、Safari 604.1

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yambejp

2021/10/18 00:35

元のHTMLと想定する結果のHTMLを提示ください
erp

2021/10/18 08:53

了解いたしました。作業がしばらく出来ないので、追記が完了しましたらまたお知らせいたします。すみません。
erp

2021/10/18 10:40

追記しました。
yambejp

2021/10/19 00:22

pを5個ずつdivに入れてあまりは何もしないということでよいですか? あまりもdivに入れる?
erp

2021/10/19 03:15

あまりもdivに入れる方が求めていたものですので、回答大変助かります。思っていたものが実装できました。本当にありがとうございます。 お時間ある時で結構ですので、もしよろしければコードで何をしているのか教えていただけないでしょうか。 let wrap=p.previousElementSibling というのは、p の兄弟要素ということですか? ここで何をしているのでしょうか。
guest

回答2

0

ベストアンサー

javascript

1window.addEventListener('DOMContentLoaded', ()=>{ 2 const max=5; 3 document.querySelectorAll('.cc').forEach(cc=>{ 4 cc.querySelectorAll('p').forEach(p=>{ 5 let wrap=p.previousElementSibling; 6 if(!wrap || wrap.querySelectorAll('p').length>=max){ 7 wrap=document.createElement('div'); 8 cc.insertBefore(wrap,p); 9 } 10 wrap.appendChild(p); 11 }); 12 }); 13});

投稿2021/10/19 00:39

yambejp

総合スコア116724

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yambejp

2021/10/19 03:30

解説: (1)cc内でpを順番に処理します。 (2)最初のpを掴んだらその前方のHTML要素を探します。 (3)当然最初はないのでifが適用され、新しくdivをつくってpの前方に挿入します (4)div要素にpを挿入(移動)します (5)2番目のp要素について、前方のHTML要素を探します。 (6)さっきつくったdivが存在してそのdivもつpの数がmaxより少ないのでifは適用されません (7)(4)に戻ります (8)3、4、5番目までは(5)(6)と同等の処理です (9)6番目にくると前方のdiv要素はすでに5つのpを持っていますのでifが適用され あらたにdivをつくりpの前方に挿入します (10)あとは最後のpまで繰り返されます
erp

2021/10/19 11:05

お返事遅くなり失礼しました。大変分かりやすい解説をありがとうございます。let wrap=p.previousElementSibling; は前方の要素を参照する意味があったのですね。大変勉強になりました。 本当にありがとうございます。
guest

0

1つのdivを複数のtitlesappendChild()しているのがどうにもおかしいです。

元のjQueryコードの構造をできるだけ踏襲しましょう。

  • 最初のループは、for (let cc of document.querySelectorAll('.cc')) {
  • [...cc.children].filter(child => child.matches('p')) ($(this).children("p")に相当)をとっておいて、その長さが0以上なら繰り返す。その最初の5個を<div>に入れてccappendChild()する

追記:

  • 配列 tp のすべての要素を処理したいので、while (tp.length) でループを作るのはいい方針だと思います。この場合は、そのループ内で tp の長さを縮めないと永久ループになります。for (let p of tp.slice(0, 5)) で tpの最初の5個を処理して、tp = tp.slice(5); で処理済みの配列要素を削除しましょう。
  • 1回のdocument.createElement('div') の実行に対して、cc.appendChild(div) は1回だけ実行してください。現在、後者が5回実行されています。(まあこれは実害はありませんが)

参考コード

js

1for (let cc of document.querySelectorAll('.cc')) { 2 let tp = [...cc.children].filter(child => child.matches('p')); 3 while (tp.length) { 4 let div = document.createElement('div'); 5 for (let p of tp.slice(0, 5)) { 6 div.appendChild(p); 7 } 8 cc.appendChild(div); 9 tp = tp.slice(5); 10 } 11}

投稿2021/10/16 15:30

編集2021/10/19 03:51
int32_t

総合スコア21695

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

erp

2021/10/16 16:34

ありがとうございます。 自分なりにコードを書いてみたのですが、エラーになってしまいました。エラーについて調べたのですが、createElement で作成したノードでなぜエラーになるのか分かりませんでした。 どこが違うのかご教示いただけますと大変助かります。
int32_t

2021/10/16 17:22

色々と不備はありますが、まずは、 ・var を使わないでください。let か const です。 ・1つの<p>に対して1つの<div>を作る必要はありません。5個(5個以内)の<p>に対して1つの<div>ですから、内側のforループの中で<div>を作るのは間違ってます。
erp

2021/10/17 00:18

var 修正しました。各ccの中にdivを一つ作ることは出来たのですが、それをループさせることができませんでした。while を使うと重すぎ、forEach を使うと div.forEach is not a function とエラーになってしまいました。 ループについてどう直せばいいのか、どうかご教示いただけないでしょうか。
int32_t

2021/10/17 05:58

回答に追記しました。
erp

2021/10/18 08:52

ありがとうございます。しばらく作業が出来ないので、またコードを書きましたら追記とお返事いたします。すみません。
erp

2021/10/18 10:42

追記いたしました。ループから抜けることはできたのですが、初めの5つのpしかdivで囲むことができませんでした。コードのどこが問題なのでしょうか。
int32_t

2021/10/18 14:26 編集

「tpの長さが0でない間はループ」が消えてしまってますね。 「for (let p of tp.slice(0, 5))」があれば「for (let i = 0; i < 5; i = i + 1)」は不要なはずです。 tp.slice(0, 5)とtp.slice(5)の順番が間違ってます。最初の5個を処理してから最初の5個を消す必要があります。
int32_t

2021/10/18 22:07

tpを初期化したあと、やりたいことは「tpの長さが0になるまで、tpの先頭5個を削り続ける」ことですから、 tp.lengthが0でない間ループ  (ここでdivを作ったりtpの最初の5個をdivに入れたり)  slice()でtpの先頭5個を削る という構成のはずです。
int32_t

2021/10/18 23:43

19日08:10のコードについて: 「for (let p of tp.slice(0, 5)) {」(tpの最初の5個の<p>を処理するループ)の中に「while (tp.length) {」(tpを5個ずつ縮めるループ)が入っているのはおかしいですよ。逆のはずですよね。 > div.appendChild(tp); appendChild()に配列は渡せません。ここには p を渡せばよいです。 「document.createElement('div')」1回に対して「div.appendChild()」は5回呼ばれるのが正しいです。
erp

2021/10/19 03:17

回答ありがとうございます。すみません、pでやってみたのですが、ループが間違っているのかできませんでした。長いお時間お付き合いくださったのに申し訳ないです。 回答、本当にありがとうございました。
int32_t

2021/10/19 03:53 編集

参考用に完全なコードを載せておきます。 コピペプログラマを産まないために完全なコードを書くのは避けているのですが、もう意味がないので。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問