質問: ### 前提・実現したいこと JavaScript初心者です。 Twitterのクライアントアプリを作っているのですが、 外部に用意したツイート表示用のHTMLをJavaScript(jQuery)で読み込んで、 名前・アイコン・テキスト(本文)の部分をAPIで取得したものに差し替えてから、 Bodyの指定した位置に挿入したいです。 例えば以下のような感じです。 ツイート表示用のHTMLは"template.html"、 名前・テキストのタグのIDはそれぞれ "tweet-name", "tweet-text" です。 ``` ``` ### 発生している問題 外部のHTMLを $('#hoge').load("fuga.html"); で読み込むところまでは出来たのですが、 読み込んだHTMLの特定の要素の属性・textを書き換える方法が分かりません。 そもそもforの中で要素をappendしても1つしか挿入されません。 そしてcloneしたものをconsole.log(cloned[0])で表示しても中身が空っぽのdivタグです。 APIで取得するところまではできていて、あとはHTMLで表示させるだけなので、 jQueryを使わない方法でもいいのでご教示下さい。よろしくお願いします。m(_ _)m ### 補足情報(言語/FW/ツール等のバージョンなど) jQueryのバージョンは3.2.1です。 webサーバーはFlask、クライアント側はelectronです。
回答: 更にjQuery.loadのソースコードを見るとAjaxという非同期通信が使われている。 新たにHTMLリクエスト等を発射した場合、 リクエストの結果が返ってくるまで何の動作も出来ずに待ちぼうけになってしまう。 通信やファイルの読み書きといった結果が反映されるまで遅い処理を実行する時は、 通信結果を待たずに次の行を実行するという動作をする。 「えー、それじゃ困る、通信終わってから決めた処理をして欲しい」というケースはもちろんあるよね。 残りの処理を関数化して引数として渡しておき、「通信終わったらこの関数を実行してね」とお願いするのが慣習 さて上記前提条件を元にコードをみていこう。 リファレンスを見ると下記のような記述がある。 ``` $( "#success" ).load( "/not-here.php", function( response, status, xhr ) { if ( status == "error" ) { var msg = "Sorry but there was an error: "; $( "#error" ).html( msg + xhr.status + " " + xhr.statusText ); } }); ``` loadメソッドの第2引数に、やりたい処理を関数に包んで定義してある。 これと同じことをやろう。 ``` let template = $('').load("template.html"); for(let i = 0; i < tweets.length; ++i) { tweet_element = template.clone(); // 名前・テキストを差し替える(ここが分からない) tweet_element.find("#tweet-name").text(tweets[i].name) tweet_element.find("#tweet-text").text(tweets[i].text) $('#tweets-space').append(tweet_element[0]); } ``` こうではなく、こうだ! ``` let template = $('').load("template.html", function (response, status, xhr) { for(let i = 0; i < tweets.length; ++i) { tweet_element = template.clone(); // 名前・テキストを差し替える(ここが分からない) tweet_element.find("#tweet-name").text(tweets[i].name) tweet_element.find("#tweet-text").text(tweets[i].text) $('#tweets-space').append(tweet_element[0]); } } ``` 一旦これで様子を見よう。 このように処理を変えた事で、`tweet_element = template.clone();`の行の実行タイミングがAjax通信完了後に変わる。 つまり、関数に包んだだけで成功している可能性もあるわけだね。