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

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

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

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

jQuery

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

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Q&A

解決済

2回答

1450閲覧

Javascript(jQuery)のAjaxを使った課題についてサポートお願い致します。

mint5150

総合スコア6

JavaScript

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

jQuery

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

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

0グッド

2クリップ

投稿2023/02/20 21:03

実現したいこと

JavascriptのAjaxを使ったコードを理解できる様になりたい

前提

会社の研修カリキュラムでAjaxの課題に取り組んでいます。

国立情報学研究所(NII)が提供しているAPIを使用して、全国各地の大学図書館等約1200館が所有す
る、図書情報の検索する機能を実装するという課題です。

コードが複雑すぎて意味が分からないので助けて欲しいです。
大変お手数ですがアドバイスやヒントなどお願い致します。

1.解答コードを添付しますので
それぞれのコードがどういう仕組みで何をしているのか
解説して頂きたいです。

2.変数a~fまでありますが
どのような変数名を付けるべきなのか確認したいです。

3.c.title ? c.title : "\u30bf\u30a4\u30c8\u30eb\u4e0d\u660e"の部分など三項演算子で書かれている部分をif文に直すにはどうしたら良いか確認したいです。

該当のソースコード

var

1$jscomp.scope = {}; 2$jscomp.createTemplateTagFirstArg = function (a) { return a.raw = a }; 3$jscomp.createTemplateTagFirstArgWithRaw = function (a, d) { a.raw = d; 4 return a }; 5 6$(function () { 7 function a(e) { 8 $(".message").remove(); 9 let b; 10 let messageLength = 0; 11 12 if(null == (b = e[0].items)) { 13 messageLength = void 0; 14 console.log("0です"); 15 } else { 16 messageLength = b.length; 17 console.log("b.Lengthです"); 18 } 19 20 if(0 < messageLength) { 21 $.each(e[0].items, function (h, c) { 22 let g = '<li class="lists-item"><div class="list-inner"><p>\u30bf\u30a4\u30c8\u30eb\uff1a' + ((c.title ? c.title : "\u30bf\u30a4\u30c8\u30eb\u4e0d\u660e") + "</p><p>\u4f5c\u8005\uff1a") + ((c["dc:creator"] ? c["dc:creator"] : "\u4f5c\u8005\u4e0d\u660e") + "</p><p>\u51fa\u7248\u793e\uff1a") + ((c["dc:publisher"] ? c["dc:publisher"][0] : "\u51fa\u7248\u793e\u4e0d\u660e") + '</p><a href="') + (c.link["@id"] +'" target="_blank">\u66f8\u7c4d\u60c5\u5831</a></div></li>'); 23 $(".lists").prepend(g)}) 24 } else { 25 $(".lists").before('<div class="message">\u691c\u7d22\u7d50\u679c\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002<br>\u5225\u306e\u30ad\u30fc\u30ef\u30fc\u30c9\u3067\u691c\u7d22\u3057\u3066\u4e0b\u3055\u3044\u3002</div>')} 26 } 27 28let d = 1, f = ""; 29 $(".search-btn").on("click", function () {var e = $("#search-input").val(); 30 31 if(e !== f) { 32 (d = 1, $(".lists").empty(), f = e) 33 } else { 34 d++; 35 } 36 37 $.ajax({url: "https://ci.nii.ac.jp/books/opensearch/search?title=" + e + "&format=json&p=" + d + "&count=20", method: "GET"}).done(function (b) { a(b["@graph"]) }).fail(function (b) {$(".lists").empty(); 38 39 $(".message").remove(); 40 0 === b.status ? $(".lists").before('<div class="message">\u6b63\u5e38\u306b\u901a\u4fe1\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002<br>\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u306e\u63a5\u7d9a\u306e\u78ba\u8a8d\u3092\u3057\u3066\u304f\u3060\u3055\u3044\u3002</div>') : 400 === b.status ? $(".lists").before('<div class="message">\u691c\u7d22\u30ad\u30fc\u30ef\u30fc\u30c9\u304c\u6709\u52b9\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002<br>1\u6587\u5b57\u4ee5\u4e0a\u3067\u691c\u7d22\u3057\u3066\u4e0b\u3055\u3044\u3002</div>') :$(".lists").before('<div class="message">\u4e88\u671f\u305b\u306c\u30a8\u30e9\u30fc\u304c\u8d77\u304d\u307e\u3057\u305f\u3002<br>\u518d\u8aad\u307f\u8fbc\u307f\u3092\u884c\u3063\u3066\u304f\u3060\u3055\u3044\u3002</div>') 41 }) 42 }); 43 44 $(".reset-btn").on("click", function () { d = 1; 45 f = ""; 46 $(".lists").empty(); 47 $(".message").remove(); 48 $("#search-input").val("") }) 49});

試したこと

Ajaxとは何か、Ajaxの基本構文を調べました

補足情報(HTML)

<html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="./css/reset.css"> <link rel="stylesheet" href="./css/base.css"> <link rel="stylesheet" href="./css/style.css"> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> </head> <body> <header class="header"> <p>Search CiNii Book</p> </header> <main class="main"> <section class="search-area"> <input id="search-input" type="text" placeholder="検索ワード"> <button class="search-btn btn">検索</button> <button class="reset-btn btn">リセット</button> </section> <section class="list-area"> <div class="inner"> <ul class="lists"></ul> </div> </section> <script src="./js/app.js"></script> </main> </body> </html>

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

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

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

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

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

int32_t

2023/02/20 22:03 編集

> 解説して頂きたいです。 けっこう過大な要求です。質問者さんの理解度が不明なので、どこまで解説すべきか不明です。 すべてがわからないならすべてを解説する必要があり、そのような状態なら解説しても理解できない危惧があります。 聞きたいことが3つある場合、質問を3つ作るほうがおすすめです。回答しやすくなります。
m.ts10806

2023/02/20 22:10

課題であれば出題者に確認すべきで、出題者の意図を考慮しない赤の他人の解説を受けたところで課題の達成にはなり得ないかと。
yambejp

2023/02/21 00:30

$jscompが宣言されてないようなので動作しないのでは?
guest

回答2

0

コメントにすべき内容ですが、マークダウンを使いたいので回答として投稿します。

関数の範囲は合っています。
もう一つ44行目から48行目にかけて関数がありますが、これは書き忘れということでよいでしょう。

元のソースでは読みにくいので、勝手ではありますが書き直しました。
・全体的に整形ツールを使って整形しました。
・Unicodeエスケープシーケンスは全角文字に置換しました。
・関数名と変数名は最初の回答の通りに変更しました。
・エラー修正のため1行目の記述を追加しました。

javascript

1$jscomp = {} 2$jscomp.scope = {} 3$jscomp.createTemplateTagFirstArg = function (a) { 4 return (a.raw = a) 5} 6$jscomp.createTemplateTagFirstArgWithRaw = function (a, d) { 7 a.raw = d 8 return a 9} 10 11$(function () { 12 function showResult(result) { 13 $('.message').remove() 14 let firstItem 15 let messageLength = 0 16 17 if (null == (firstItem = result[0].items)) { 18 messageLength = void 0 19 console.log('0です') 20 } else { 21 messageLength = firstItem.length 22 console.log('firstItem.Lengthです') 23 } 24 25 if (0 < messageLength) { 26 $.each(result[0].items, function (index, item) { 27 let html = 28 '<li class="lists-item"><div class="list-inner"><p>タイトル:' + 29 ((item.title ? item.title : 'タイトル不明') + '</p><p>作者:') + 30 ((item['dc:creator'] ? item['dc:creator'] : '作者不明') + 31 '</p><p>出版社:') + 32 ((item['dc:publisher'] ? item['dc:publisher'][0] : '出版社不明') + '</p><a href="') + 33 (item.link['@id'] + '" target="_blank">書籍情報</a></div></li>') 34 $('.lists').prepend(html) 35 }) 36 } else { 37 $('.lists').before( 38 '<div class="message">検索結果が見つかりませんでした。<br>別のキーワードで検索して下さい。</div>' 39 ) 40 } 41 } 42 43 let page = 1, 44 lastSearchInput = '' 45 $('.search-btn').on('click', function () { 46 var currentSearchInput = $('#search-input').val() 47 48 if (currentSearchInput !== lastSearchInput) { 49 ;(page = 1), $('.lists').empty(), (lastSearchInput = currentSearchInput) 50 } else { 51 page++ 52 } 53 54 $.ajax({ 55 url: 'https://ci.nii.ac.jp/books/opensearch/search?title=' + currentSearchInput + '&format=json&p=' + page + '&count=20', 56 method: 'GET', 57 }) 58 .done(function (data) { 59 showResult(data['@graph']) 60 }) 61 .fail(function (jqXHR) { 62 $('.lists').empty() 63 64 $('.message').remove() 65 0 === jqXHR.status 66 ? $('.lists').before( 67 '<div class="message">正常に通信できませんでした。<br>インターネットの接続の確認をしてください。</div>' 68 ) 69 : 400 === jqXHR.status 70 ? $('.lists').before( 71 '<div class="message">検索キーワードが有効ではありません。<br>1文字以上で検索して下さい。</div>' 72 ) 73 : $('.lists').before( 74 '<div class="message">予期せぬエラーが起きました。<br>再読み込みを行ってください。</div>' 75 ) 76 }) 77 }) 78 79 $('.reset-btn').on('click', function () { 80 page = 1 81 lastSearchInput = '' 82 $('.lists').empty() 83 $('.message').remove() 84 $('#search-input').val('') 85 }) 86})

これだけでもだいぶ見通しが良くなると思います。
以後、整形済みソースの行番号で話したいと思います。

>・search-btnのクリックイベント、通信成功処理、通信失敗処理、リセット処理の
順番に並べて下さい
→それぞれ何行目から始まる関数かはわかりますか?
並べ替えをするには新たに関数として切り分ける必要のある処理がありますが、どれかわかりますか?

改行についてはさすがに自力でやってほしいです。

なお、このプログラムのエッセンスは次のようになります。

javascript

1$(function () { 2 function showResult(result) { 3 $.each(result[0].items, function (index, item) { 4 let html = 'タイトル:' + item.title + '<br />' 5 $('.lists').prepend(html) 6 }) 7 } 8 9 $.ajax({ 10 url: 'https://ci.nii.ac.jp/books/opensearch/search?title=あ&format=json&p=1&count=20', 11 method: 'GET', 12 }) 13 .done(function (data) { 14 showResult(data['@graph']) 15 }) 16})

このエッセンスはどのくらい理解できるでしょうか。

投稿2023/02/24 01:44

gosaro

総合スコア24

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

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

mint5150

2023/02/24 15:47

この度はご返信頂きありがとうございます。 かなり見通しが分かりやすくなっている感じがして感動しました。 search-btnのクリックイベント→45行目から 通信成功処理→58行目から 通信失敗処理→61行目から リセット処理→79行目から という事で合ってますでしょうか? エッセンス部分に関しては $.each(resultで順番に見ていってリストにHTMLを作成して追加 ajax通信宣言をして 成功した場合は showResult(data['@graph'])の処理をする という感じでしょうか?
gosaro

2023/02/25 04:53

はい、合ってます。 通信成功処理は12行目からの意図と思いますが、58行目からでも間違いではないです。 ソースの整形についてはエディタのプラグインでできたり、Web上でもコピペしてボタン一発でできるサイトがありますので、それらを活用するとよいですね。 Unicodeエスケープシーケンスも同様です。 >・search-btnのクリックイベント、通信成功処理、通信失敗処理、リセット処理の 順番に並べて下さい →現状では通信失敗処理がsearch-btnのクリックイベント中に埋め込まれているので、そのままでは指示された順に並べ替えることができません。 通信失敗処理を showResult() と同様に独立した関数として切り分けて並べ替えるとよいです。 エッセンスが把握できれば、他はHTMLの組み立てと、ページ送りと、エラー処理といったところになります。 まだ詳しい説明が必要な箇所があればコメントください。
mint5150

2023/02/26 11:56

gosaro様、いつもご回答ありがとうございます。 丁寧にご回答頂き大変勉強になり、助かっております。 1.以下の様にコードを書いて提出して見ましたが、各文のコメント解説は合ってますでしょうか? 2.そもそもどうしてこういったコードになるのかはまだ分かりませんが 経験を積んだ操作設計のエンジニアの仕事で現場での操作設計は 別のエンジニアがやるので初級エンジニアとしてはとりあえずは困らないでしょうか? 3.リセット処理は$(".reset-btn").on("click", function () {~の部分だと思いますが $(".search-btn").on("click", function () {の $(".lists").empty()なども リセット処理に関連している所なのでしょうか? //関数を実行する $(function () { //関数名a(引数e) //関数showResult(引数result)を実行する function showResult(result) { //.messageクラスのある要素を削除する $(".message").remove(); //変数firstItemを定義する let firstItem; //変数messageLengthに0を代入する let messageLength = 0; //もしnull == (firstItem = result[0].items)がfalseなら if(null == (firstItem = result[0].items)) { //messageLengthにvoid 0を代入する=Undefinedになる; messageLength = void 0; //もしnull == (firstItem = result[0].items)がfalseなら } else { //messageLengthにfirstItem.lengthを代入する messageLength = firstItem.length; } //もし0 < messageLengthなら if(0 < messageLength) { //$.each(result[0].items, function (index, item) { $.each(result[0].items, function (index, item) { //変数htmlに<li class="<li class="lists-item"><div class="list-inner"><p>\u30bf\u30a4\u30c8\u30eb\uff1aを代入する let html = '<li class="lists-item"><div class="list-inner"><p>\u30bf\u30a4\u30c8\u30eb\uff1a'; //もしitem.titleなら if (item.title) { //html += item.title html += item.title; //もし0 < messageLengthでないなら } else { //html += "\u30bf\u30a4\u30c8\u30eb\u4e0d\u660e"; html += "\u30bf\u30a4\u30c8\u30eb\u4e0d\u660e"; } html += "</p><p>\u4f5c\u8005\uff1a"; //もしitem['dc:creator']なら if (item['dc:creator']) { //html += item["dc:creator"]; html += item["dc:creator"]; //もしitem['dc:creator']でないなら } else { //html += "\u4f5c\u8005\u4e0d\u660e"; html += "\u4f5c\u8005\u4e0d\u660e"; } html += "</p><p>\u51fa\u7248\u793e\uff1a"; //もしitem["dc:publisher"]なら if (item["dc:publisher"]) { //html += item["dc:publisher"][0]; html += item["dc:publisher"][0]; //もしitem["dc:publisher"]でないなら } else { //html += "\u51fa\u7248\u793e\u4e0d\u660e"; html += "\u51fa\u7248\u793e\u4e0d\u660e"; } html += '</p><a href="'; + (item.link["@id"] +'" target="_blank">\u66f8\u7c4d\u60c5\u5831</a></div></li>'); //.listsの最初の子要素の前に挿入する $(".lists").prepend(html) }) //もし0 < messageLengthでないなら } else { //.listsの直前の要素に挿入する $(".lists").before('<div class="message">\u691c\u7d22\u7d50\u679c\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002<br>\u5225\u306e\u30ad\u30fc\u30ef\u30fc\u30c9\u3067\u691c\u7d22\u3057\u3066\u4e0b\u3055\u3044\u3002</div>'); } }; //変数pageに1を代入する let page = 1; //変数lastSearchInputに空の値を代入する let lastSearchInput = ""; //.search-btnがクリックされたらfunction () {let currentSearchInput = $("#search-input").val()を実行する $(".search-btn").on("click", function () { let currentSearchInput = $("#search-input").val(); //もし変数currentSearchInputが変数lastSearchInputと同一でないなら if(currentSearchInput !== lastSearchInput) { ( //変数pageに1を代入する page = 1, //$(".lists").empty()を実行する $(".lists").empty(), //変数lastSearchInputにcurrentSearchInputを代入する lastSearchInput = currentSearchInput ); //もし変数currentSearchInputが変数lastSearchInputと同一なら } else { //変数pageに1を加える page++; } //Ajaxリクエストを送信するオプションをキーと値のペアで指定する $.ajax({url: "https://ci.nii.ac.jp/books/opensearch/search?title=" + currentSearchInput + "&format=json&p=" + page + "&count=20", method: "GET"}) //成功なら(function (data) { showResult(data["@graph"]) .done(function (data) { showResult(data["@graph"]) }) //失敗ならfunction (jqXHR) {$(".lists").empty(); .fail(function (jqXHR) { $(".lists").empty(); //.messageクラスのある要素を削除する $(".message").remove(); //もし0 完全一致 data.statusがtrueなら if (0 === data.status) { //$(".lists").before('<div~ $(".lists").before('<div class="message">\u6b63\u5e38\u306b\u901a\u4fe1\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002<br>\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u306e\u63a5\u7d9a\u306e\u78ba\u8a8d\u3092\u3057\u3066\u304f\u3060\u3055\u3044\u3002</div>'); //もし0 完全一致 data.statusがfalseなら } else { //もし400 完全一致 jqXHR.statusがtrueなら if (400 === jqXHR.status) { //$(".lists").before('<div~ $(".lists").before('<div class="message">\u691c\u7d22\u30ad\u30fc\u30ef\u30fc\u30c9\u304c\u6709\u52b9\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002<br>1\u6587\u5b57\u4ee5\u4e0a\u3067\u691c\u7d22\u3057\u3066\u4e0b\u3055\u3044\u3002</div>'); //もし400 完全一致 jqXHR.statusがfalseなら } else { //$(".lists").before('<div~ $(".lists").before('<div class="message">\u4e88\u671f\u305b\u306c\u30a8\u30e9\u30fc\u304c\u8d77\u304d\u307e\u3057\u305f\u3002<br>\u518d\u8aad\u307f\u8fbc\u307f\u3092\u884c\u3063\u3066\u304f\u3060\u3055\u3044\u3002</div>'); } } }) }); //.reset-btnが押されたらfunction () { を実行する $(".reset-btn").on("click", function () { //変数pageに1を代入する page = 1; //変数lastSearchInputに空の値を代入する lastSearchInput = ""; //.listsの子要素を全て削除する $(".lists").empty(); //.messageの要素を全て削除する $(".message").remove(); //#search-inputの値を空にする $("#search-input").val("") }) });
gosaro

2023/02/27 00:56

>1.以下の様にコードを書いて提出して見ましたが、各文のコメント解説は合ってますでしょうか? 厳しいことを言いますが、 //html += item.title html += item.title; こんなコメントを付けられて合っているかと聞かれても、それ以前の問題で話にならないとしか言いようがないです。 (怒っているのではなく、呆れています) 1行ごとにコメントを付けて JavaScript の文や式の内容を記述するだけというのもナンセンスです。 コメントを付けるならどのような意図でその処理を行っているのか書かなければ意味がありません。 例えば次のようにします。 if(currentSearchInput !== lastSearchInput) { ( //前回と異なる検索ワードで検索したら1ページ目を対象にする page = 1, $(".lists").empty(), lastSearchInput = currentSearchInput } else { //前回と同じ検索ワードで検索したら次のページを対象にする page++; } 研修の課題ということなので、何か書かなければならないという思いで書いたのでしょうけれども、少なくともこの場においてはまだわからなければ「まだわからない」と言えば済みます。 >2.そもそもどうしてこういったコードになるのかはまだ分かりませんが >経験を積んだ操作設計のエンジニアの仕事で現場での操作設計は >別のエンジニアがやるので初級エンジニアとしてはとりあえずは困らないでしょうか? そうはいかないでしょう。 恐らくこの研修の目標はAPI(それも図書検索ではなくこれから開発・保守するシステムの独自のAPI)を使ったフロントエンド開発・保守ができるようになることだろうと思います。 開発であれば課題のようなプログラムを作れること、保守であればプログラムの不具合の原因を調べて修正できることが、初級エンジニアに求められると思います。 >3.リセット処理は$(".reset-btn").on("click", function () {~の部分だと思いますが >$(".search-btn").on("click", function () {の $(".lists").empty()なども >リセット処理に関連している所なのでしょうか? 意味的にはそうなります。 ただ、今回の課題ではリセット処理と言えばあくまでもリセットボタンクリック時の処理のみを指すと考えておいた方がよいでしょう。 いずれにしても、エッセンスの理解が不十分なままでは全体の理解はおぼつきません。 改めてエッセンスについて確認したいと思います。 1. エッセンスのプログラムは実行してみましたか?ついでに課題のプログラムは実行してみましたか? 2. 1行目の関数はどのようなタイミングで実行されるでしょうか。 3. 13行目の data、2行目の result、3行目の item にはそれぞれどのようなデータが設定されるでしょうか。 3.は全部書き出すと膨大な量になりますので、先頭の部分だけ答えてもらえれば結構です。
mint5150

2023/02/27 07:15

gosaro様この度はご回答頂きありがとうございます。 「プログラム中のコメントはどのような意図でその処理を行っているのかを残す」という事で大変勉強になりました。 ありがとうございます。 1. エッセンスのプログラムは実行してみましたか?ついでに課題のプログラムは実行してみましたか? 書き直し頂いたプログラムは正しく実行できることを確認しました。 エッセンスのプログラムは以下の様なエラーが出ました。 ESLint(1) ERROR:Parsing error:Unexpected token html let html = 'タイトル:' + item.title + '<br />' JSLint(4) 'S'was used before it was defined. $(function(){ Missing'use strict' statement. function showResult(result){ Expected an identifer and instead saw'let'. let html = 'タイトル:' + item.title + '<br />' それぞれエラー文をコピペして調べてみましたが解決策はどうすれば良いか分かりませんでした。 2. 1行目の関数はどのようなタイミングで実行されるでしょうか。 ajax通信が成功した時に実行されるのでしょうか? 3. 13行目の data、2行目の result、3行目の item にはそれぞれどのようなデータが設定されるでしょうか。 data ajax通信が成功したデータが格納されるのでしょうか? result eachメソッドで順番に処理したデータが格納されるのでしょうか? item ajaxの書籍データが格納されるのでしょうか? ※eachメソッドでajaxで指定したリンク先のデータを一つ一つ見ていって変数に格納し、 doneの条件に当てはまれば表示するみたいな仕組みになっているのではと思いました。
gosaro

2023/02/27 08:46

>エッセンスのプログラムは以下の様なエラーが出ました。 なぜここで ESLint や JSLint が出てくるのかわかりません。 HTML を Chrome や Edge などのブラウザにドラッグ&ドロップするだけだと思っていましたがそうではないのでしょうか? 特別な環境を使っているのであればどのような環境で実行しているのか記載してください。 >2. 1行目の関数はどのようなタイミングで実行されるでしょうか。 >ajax通信が成功した時に実行されるのでしょうか? いいえ。 HTML の要素の読み込みが終わったタイミングで実行されます。 https://qiita.com/bakatono_super/items/fcbc828b21599568a597 エッセンスのプログラムでは HTML の要素の読み込みが終わったときにすぐ Ajax 通信を行います。 整形後のプログラムでは45行目で検索ボタン押下時のイベントハンドラの設定をしていて、Ajax 通信は検索ボタン押下時に行われるようになっています。 $('.search-btn').on('click', function () { >3. 13行目の data、2行目の result、3行目の item にはそれぞれどのようなデータが設定されるでしょうか。 漠然とした意味合いではなく、具体的にどのようなデータが設定されるかの理解が必要です。 ここが API を使う上での核心的な部分です。 ブラウザのアドレスバーに Ajax で指定されている次のURLを入力すると、 https://ci.nii.ac.jp/books/opensearch/search?title=あ&format=json&p=1&count=20 次のような JSON 形式の文字列が表示されます。(整形後) { "@id": "https://ci.nii.ac.jp/books/opensearch/search?p=1&format=json&count=20&title=%E3%81%82", "@graph": [ { "title": "CiNii Books OpenSearch - 1 20 あ", "description": "CiNii Books OpenSearch - 1 20 あ", "link": { "@id": "https://ci.nii.ac.jp/books/opensearch/search?p=1&format=json&count=20&title=%E3%81%82" }, "items": [ { "title": "ああああ : ああああああああああ", "link": { "@id": "https://ci.nii.ac.jp/ncid/BA85458893" }, (以下略) これを JavaScirpt のオブジェクトにしたもの(JSON.parse()したもの)が 13行目の data に設定されるデータです。 これを元に2行目の result、3行目の item にどのようなデータが設定されるか考えて下さい。 もし JSON がよくわからない場合はそれも調べて下さい。 なお、図書検索の API の仕様は次の URL で公開されています。 https://support.nii.ac.jp/ja/cib/api/b_opensearch_lib このような仕様から、どのようなクエリを送ればどのようなレスポンスが得られるかを読み取り、プログラムを書き起こすのがフロントエンドのプログラマの仕事になります。
mint5150

2023/02/28 18:34

gosaro様、いつも丁寧なご回答頂き誠にありがとうございます。 HTMLをChromeにドラッグ&ドロップする方法で開いた所 検索結果の欄に タイトル:ああ父よああ母よ タイトル:あ・あ タイトル:あー・あー タイトル:あ、あ! タイトル:あしあと タイトル:アイデア×アイデア タイトル:アルヴァ・アアルト タイトル:アジア・オセアニア タイトル:アルヴァ・アアルト タイトル:ありあ タイトル:アジアはアジア人で : アジア五つの旅より タイトル:アヹ・マリア タイトル:アドルフ・アピア タイトル:ああ〜ん、あんあん タイトル:アジア・包 タイトル:アジアは「アジア的」か タイトル:ヒア・アイ・アム タイトル:あああああ : 詩集 タイトル:あああああ : 詩誌 タイトル:ああああ : ああああああああああ という表示がされていて 検索バーやリセットボタンを押しても反応しない状態ですが、 ディベロッパーツールでもコンソールなどを見てもエラーは出ていない状態です。 Bracketsではapp.jsにESLint や JSLintのエラーが表示されていました。 1行目の関数はHTML要素の読み込みが終わったタイミングで実行される という事でURLとても分かりやすくて参考になりました。 ありがとうございます。 検索ボタン押下時にajax通信が行われるというのは $('.search-btn').on('click', function () {内で$.ajax({~の記述部分があるので ボタンを押したら動くのかなというイメージがありましたが、 HTML要素の読み込みが終わったときにもすぐAjax 通信を行っているというのは初めて知り ajax通信の仕組みを理解する事がこの問題の核心かも知れないと感じました。 JSON.parse()したものがdataに設定されるという事で エッセンス10行目のURLにformat=json&pと書かれていますが、 仕様書のURLに出力フォーマットの項目名がformatとありましたので この記述があることでJSON.parse()されるという意味で良いでしょうか? JSONを調べた所、JavaScript Object Notationという事で JavaScriptのオブジェクト記法を用いたドキュメント規格(テキストフォーマット)で 見やすくて加工しやすいのが特徴という認識を持ちました。 2行目の result、3行目の item にどのようなデータが設定されるか考えて下さい。 resultに設定されるデータは JSONファイルを整形して確認した所 各文書の情報は以下の項目になっている様なので これがeach処理する毎に各文書に対応した情報で格納されるのではと思いました。 title:〇〇 link:{ @id:〇〇 } @id:〇〇 @type:item rdfs:seeAlso:{ @id:https://ci.nii.ac.jp/ncid/〇〇.json } dc:date:〇〇 dc:creator:〇〇 dc:publisher:[ 0:〇〇 ] prism:publicationDate:〇〇 cinii:ownerCount:〇〇 } itemに設定されるデータは title:、link:、@id:、@type:などそれぞれの項目が each処理する毎に毎回格納されるのではと思いました。
gosaro

2023/03/01 04:28

>HTML要素の読み込みが終わったときにもすぐAjax 通信を行っているというのは初めて知り これはいつでもそのようになるわけではなく、そのようにプログラムを作ったのでそうなります。 >エッセンス10行目のURLにformat=json&pと書かれていますが、 >仕様書のURLに出力フォーマットの項目名がformatとありましたので >この記述があることでJSON.parse()されるという意味で良いでしょうか? いいえ。 仕様書を読むと format には json の他に atom や rss を指定できるとされています。 試しに format=atom に変えてアドレスバーに入力すると全く異なるフォーマットでレスポンスが返されるのがわかります。 このフォーマットを指定するのが format パラメータです。 JSON.parse() するのは jQuery の ajax() 関数の中で行われます。 >2行目の result、3行目の item にどのようなデータが設定されるか考えて下さい。 どちらも正しくありません。 ディベロッパーツールでブレークポイントを設定すれば変数の値を調べることができるので、確認してください。 その上で、なぜそのようなデータが設定されるのか考えて下さい。
mint5150

2023/03/03 21:14

gosaro様、いつもご回答頂きありがとうございます。 ディベロッパーツールでブレークポイントを設定してのデバッグについて 以下の様な記事を参考にやってみました https://ics.media/entry/190517/ ディベロッパーツールのソース管理から app.jsを開いて行番号2をクリックすると何故か行番号3が選択されます。 マウスを当ててもツールチップが表示されず、 実業務ではデバッグスキルも必須かと思いますのでこの機会に覚えたいのですが、 色々ボタンを押してみて試しても使い方が良く分からず作業が止まってしまっています。 学習方法などヒントでも良いのですがどの様に学べば良いでしょうか?
gosaro

2023/03/04 01:53

>app.jsを開いて行番号2をクリックすると何故か行番号3が選択されます。 これは正しい動作です。 2行目は関数の宣言のみで実行すべき処理がないためです。 3行目にブレークポイントを設定してブラウザの更新ボタンを押すとそこでブレークするので result の値を調べられます。 >実業務ではデバッグスキルも必須かと思いますのでこの機会に覚えたいのですが、 示していただいたリンク先の記事はよくまとまっていると思います。 記事をよく読んで実際に試してみればよいと思います。 >学習方法などヒントでも良いのですがどの様に学べば良いでしょうか? まだ自信をもって使える言語がないのではないかとお見受けしますが、さしあたり必要とされている JavaScript(と jQuery)を体系的に学ぶのがよいと思います。 ネットではなかなか体系的に学べるサイトがないので(会員制の有料サイトならあるかもしれませんが)、基本は書籍で学ぶのがよいでしょう。 1つでも使える言語ができれば、他の言語への応用はかなり効くようになります。
mint5150

2023/03/08 19:04 編集

gosaro様いつも丁寧なご回答頂きありがとうございます。 3行目にブレークポイントを設定して試してみたのですが $の所のツールチップは Animation: ƒ ft(o,e,t) Callbacks: ※以下長いので省略します eachの所のツールチップは length: 2 name: "each" prototype: {constructor: ƒ} arguments: (...) caller: (...) [[FunctionLocation]]: jquery.min.js:2 [[Prototype]]: ƒ () [[Scopes]]: Scopes[2] とありました。 ▶マークがある項目については深階層がある様で更に開くことが出来る様ですが、 沢山あってresultとitemに格納されるデータがどれかが分からないので困っています。 あとスクリプトの実行を再開ボタンを押すとVM682(数字は毎回違うみたいです)の様に window.__REACT_DEVTOOLS_GLOBAL_HOOK__ && window.__REACT_DEVTOOLS_GLOBAL_HOOK__.renderers.size > 0 コンソールに表示されますが、検索エンジンで調べてみた所 リアクトのデブツールをインストールしてくださいという意味の様でした。 jQueryのコードのデバッグをしているのになぜこのような表示がされるか分かりませんが、 このままでも特に影響はないでしょうか?
gosaro

2023/03/09 00:19

>3行目にブレークポイントを設定して試してみたのですが 私の環境(Chrome)でも $ や each のツールチップは同じように表示されます。 これは正常な動作です。 >沢山あってresultとitemに格納されるデータがどれかが分からないので困っています。 3行目でブレークしたときに result をポイントすれば result の値がツールチップに表示されます。 コンソールに result と入力して調べることもできます。 コンソールに JSON.stringify(result) と入力すれば result の値のJSON形式の文字列表現が得られるので、コピペなどに使うにはこちらの方が便利です。 3行目ではまだ item の値は設定されていないので、item の値を調べるためにはもっと先に進める必要があります。 >このままでも特に影響はないでしょうか? よくわかりませんが、差し当たり無視してよいのではないかと思います。
mint5150

2023/03/10 20:33

gosaro様いつもご回答頂きありがとうございます。 resultの値について教えて頂いた通りにresultをポイントした所、以下の値が確認できました。 0: @id: "https://ci.nii.ac.jp/books/opensearch/search?p=1&format=json&count=20&title=%E3%81%82" @type: "channel" dc:date: "2023-03-11T05:26:19+09:00" description: "CiNii Books OpenSearch - 1 20 あ" items: (20) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}] link: {@id: 'https://ci.nii.ac.jp/books/opensearch/search?p=1&format=json&count=20&title=%E3%81%82'} opensearch:itemsPerPage: "20" opensearch:startIndex: "0" opensearch:totalResults: "993945" title: "CiNii Books OpenSearch - 1 20 あ" [[Prototype]]: Object length: 1 この内、itemsを更に開くと以下の値が確認できました items: Array(20) 0: {title: 'ああああ : ああああああああああ', link: {…}, @id: 'https://ci.nii.ac.jp/ncid/BA85458893', @type: 'item', rdfs:seeAlso: {…}, …} 1: {title: 'あああああ : 詩誌', link: {…}, @id: 'https://ci.nii.ac.jp/ncid/AA11715029', @type: 'item', rdfs:seeAlso: {…}, …} 2: {title: 'あああああ : 詩集', link: {…}, @id: 'https://ci.nii.ac.jp/ncid/BA47118631', @type: 'item', rdfs:seeAlso: {…}, …} 3: {title: 'ヒア・アイ・アム', link: {…}, @id: 'https://ci.nii.ac.jp/ncid/BB29151381', @type: 'item', rdfs:seeAlso: {…}, …} 4: {title: 'アジアは「アジア的」か', link: {…}, @id: 'https://ci.nii.ac.jp/ncid/BA76379435', @type: 'item', rdfs:seeAlso: {…}, …} 5: {title: 'アジア・包', link: {…}, @id: 'https://ci.nii.ac.jp/ncid/BA49145191', @type: 'item', rdfs:seeAlso: {…}, …} 6: {title: 'ああ〜ん、あんあん', link: {…}, @id: 'https://ci.nii.ac.jp/ncid/BA52279662', @type: 'item', rdfs:seeAlso: {…}, …} 7: {title: 'アドルフ・アピア', link: {…}, @id: 'https://ci.nii.ac.jp/ncid/BN04020694', @type: 'item', rdfs:seeAlso: {…}, …} 8: {title: 'アヹ・マリア', link: {…}, @id: 'https://ci.nii.ac.jp/ncid/BA31576353', @type: 'item', rdfs:seeAlso: {…}, …} 9: {title: 'アジアはアジア人で : アジア五つの旅より', link: {…}, @id: 'https://ci.nii.ac.jp/ncid/BA3847603X', @type: 'item', rdfs:seeAlso: {…}, …} 10: {title: 'ありあ', link: {…}, @id: 'https://ci.nii.ac.jp/ncid/AA11730951', @type: 'item', rdfs:seeAlso: {…}, …} 11: {title: 'アルヴァ・アアルト', link: {…}, @id: 'https://ci.nii.ac.jp/ncid/BN06901603', @type: 'item', rdfs:seeAlso: {…}, …} 12: {title: 'アジア・オセアニア', link: {…}, @id: 'https://ci.nii.ac.jp/ncid/BN04137148', @type: 'item', rdfs:seeAlso: {…}, …} 13: {title: 'アルヴァ・アアルト', link: {…}, @id: 'https://ci.nii.ac.jp/ncid/BA68476844', @type: 'item', rdfs:seeAlso: {…}, …} 14: {title: 'アイデア×アイデア', link: {…}, @id: 'https://ci.nii.ac.jp/ncid/BA66514942', @type: 'item', rdfs:seeAlso: {…}, …} 15: {title: 'あしあと', link: {…}, @id: 'https://ci.nii.ac.jp/ncid/AA11731127', @type: 'item', rdfs:seeAlso: {…}, …} 16: {title: 'あ、あ!', link: {…}, @id: 'https://ci.nii.ac.jp/ncid/BB26473494', @type: 'item', rdfs:seeAlso: {…}, …} 17: {title: 'あー・あー', link: {…}, @id: 'https://ci.nii.ac.jp/ncid/BB17243041', @type: 'item', rdfs:seeAlso: {…}, …} 18: {title: 'あ・あ', link: {…}, @id: 'https://ci.nii.ac.jp/ncid/BB17242606', @type: 'item', rdfs:seeAlso: {…}, …} 19: {title: 'ああ父よああ母よ', link: {…}, @id: 'https://ci.nii.ac.jp/ncid/BB12421619', @type: 'item', rdfs:seeAlso: {…}, …} length: 20 0~20までの各番号がitemに格納される値ということでしょうか? もしくは、「もっと先に進める必要があります」とのことなので 先に進めるにはどの様に操作したら良いでしょうか?
gosaro

2023/03/11 02:45

>resultの値について教えて頂いた通りにresultをポイントした所、以下の値が確認できました。 どのようにしてこの値が設定されたのか。 そこが理解できているかが重要なポイントです。 以前示した data の値と照らし合わせて考えてください。 わからなければ答えを書きますが、まずは考えてください。 >先に進めるにはどの様に操作したら良いでしょうか? item の値は3行目で設定されるので、4行目にブレークポイントを設定すれば調べることができます。
mint5150

2023/03/14 09:33

gosaro様いつもご回答頂きありがとうございます。 4行目にブレークポイントを設定し、itemにポイントしたら以下の値が確認できました。 @id: "https://ci.nii.ac.jp/ncid/BA85458893" @type: "item" cinii:ownerCount: "1" dc:creator: "松本百司" dc:date: "1966" dc:publisher: ['あ出版社'] link: {@id: 'https://ci.nii.ac.jp/ncid/BA85458893'} prism:publicationDate: "1966" rdfs:seeAlso: {@id: 'https://ci.nii.ac.jp/ncid/BA85458893.json'} title: "ああああ : ああああああああああ" [[Prototype]]: Object 又、14行目にブレークポイントを設定し dataをポイントしたら以下の値が確認できました @context: {dc: 'http://purl.org/dc/elements/1.1/', rdf: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', opensearch: 'http://a9.com/-/spec/opensearch/1.1/', rdfs: 'http://www.w3.org/2000/01/rdf-schema#', dcterms: 'http://purl.org/dc/terms/', …} @graph: [{…}] @id: "https://ci.nii.ac.jp/books/opensearch/search?p=1&format=json&count=20&title=%E3%81%82" [[Prototype]]: Object どのようにしてこの値が設定されたのかについては エッセンス部分のコンパクトなコードでも詳しい仕組みが良く分かっておらず 相変わらず $.each(resultで順番に見ていってリストにHTMLを作成して追加 ajax通信をして、成功した場合は showResult(data['@graph'])の処理をする という感じのイメージがあるもののあっているか分かりませんで、 順番に処理して順番に項目が格納されているのかな? という感じはしますが、 どのタイミングでどのデータがどの様な仕組みで設定されるのか というのも、ちょっと見当がつかない感じです。
gosaro

2023/03/15 00:23

プログラムが実行される順番について。 ・2~7行目は関数 showResult() の定義なので、すぐには実行されない。14行目で呼び出されたときに実行される。 ・4~6行目は each() による繰り返しなので、result[0].items の要素数分(20回)繰り返される。 ・13行目の done() の引数の function (data) は非同期に($.ajax() の呼び出しが終わった後で)実行される。 以上により、ブレークポイントを設定可能なすべての行(2,8,10,11,12行目以外)に設定して実行すると次の順にブレークします。 1→9→13→16→14→3→4→5→6→4→5→6→…→4→5→6→7→15 このあたりは JavaScript の初歩なので、わからなければ初心者用の書籍等で学習してください。 data と result の関係について。 以前示したように data の内容(JSON形式の文字列)は次のとおりです。 { "@id": "https://ci.nii.ac.jp/books/opensearch/search?p=1&format=json&count=20&title=%E3%81%82", "@graph": [ { "title": "CiNii Books OpenSearch - 1 20 あ", "description": "CiNii Books OpenSearch - 1 20 あ", "link": { "@id": "https://ci.nii.ac.jp/books/opensearch/search?p=1&format=json&count=20&title=%E3%81%82" }, "items": [ { "title": "ああああ : ああああああああああ", "link": { "@id": "https://ci.nii.ac.jp/ncid/BA85458893" }, (以下略) このことから次のことがわかります。 data["@id"] の値は "https://ci.nii.ac.jp/books/opensearch/search?p=1&format=json&count=20&title=%E3%81%82" data["@graph"] の値は [ { "title": "CiNii Books OpenSearch - 1 20 あ", "description": "CiNii Books OpenSearch - 1 20 あ", "link": { "@id": "https://ci.nii.ac.jp/books/opensearch/search?p=1&format=json&count=20&title=%E3%81%82" }, (以下略) data["@graph"][0] の値は { "title": "CiNii Books OpenSearch - 1 20 あ", "description": "CiNii Books OpenSearch - 1 20 あ", "link": { "@id": "https://ci.nii.ac.jp/books/opensearch/search?p=1&format=json&count=20&title=%E3%81%82" }, (以下略) data["@graph"][0].title の値は "CiNii Books OpenSearch - 1 20 あ" 一方 result の内容(JSON形式の文字列)は次のとおりです。 [ { "title": "CiNii Books OpenSearch - 1 20 あ", "description": "CiNii Books OpenSearch - 1 20 あ", "link": { "@id": "https://ci.nii.ac.jp/books/opensearch/search?p=1&format=json&count=20&title=%E3%81%82" }, data の内容と比較してみると data["@graph"] と同じであることがわかります。 ピンときたでしょうか? 14行目 showResult(data['graph']) で渡された data['graph'] が 2行目 function showResult(result) の result に設定されているのです。 これも JavaScript の初歩ですので、よくわからなければ書籍等で学習してください。 基本が身につけば同様にして result と item の関係も理解できると思います。
mint5150

2023/03/16 20:52 編集

gosaro様、いつもご回答頂きありがとうございます。 プロゲートや書籍など初心者向けのものを探して勉強してみます。 search-btnのクリックイベント、通信成功処理、通信失敗処理、リセット処理の順に並べて下さい という指摘について、 講師に詳細に確認した所、 通信成功処理.done(function (data) {の後に実行されている関数、showResult()は、 API実行後にしか呼ばれていないので位置の修正をして下さい という事でした。 現状のコードは以下の様になっています。 ------------------------------------------------------------------------- $(function () { function showResult(result) { $(".message").remove(); if(null === (result[0].items)) { void 0; } else { result[0].items.length; } if(0 < result[0].items.length) { $.each(result[0].items, function (index, item) { let html = '<li class="lists-item"><div class="list-inner"><p>\u30bf\u30a4\u30c8\u30eb\uff1a'; if (item.title) { html += item.title; } else { html += "\u30bf\u30a4\u30c8\u30eb\u4e0d\u660e"; } html += "</p><p>\u4f5c\u8005\uff1a"; if (item['dc:creator']) { html += item["dc:creator"]; } else { html += "\u4f5c\u8005\u4e0d\u660e"; } html += "</p><p>\u51fa\u7248\u793e\uff1a"; if (item["dc:publisher"]) { html += item["dc:publisher"][0]; } else { html += "\u51fa\u7248\u793e\u4e0d\u660e"; } html += '</p><a href="'; + (item.link["@id"] +'" target="_blank">\u66f8\u7c4d\u60c5\u5831</a></div></li>'); $(".lists").prepend(html) }) } else { $(".lists").before('<div class="message">\u691c\u7d22\u7d50\u679c\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002<br>\u5225\u306e\u30ad\u30fc\u30ef\u30fc\u30c9\u3067\u691c\u7d22\u3057\u3066\u4e0b\u3055\u3044\u3002</div>'); } }; let page = 1; let lastSearchInput = ""; $(".search-btn").on("click", function () { let currentSearchInput = $("#search-input").val(); if(currentSearchInput !== lastSearchInput) { ( page = 1, $(".lists").empty(), lastSearchInput = currentSearchInput ); } else { page++; } $.ajax({url: "https://ci.nii.ac.jp/books/opensearch/search?title=" + currentSearchInput + "&format=json&p=" + page + "&count=20", method: "GET"}) .done(function (data) { showResult(data["@graph"]) }) .fail(function (jqXHR) { $(".lists").empty(); $(".message").remove(); if (0 === data.status) { $(".lists").before('<div class="message">\u6b63\u5e38\u306b\u901a\u4fe1\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002<br>\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u306e\u63a5\u7d9a\u306e\u78ba\u8a8d\u3092\u3057\u3066\u304f\u3060\u3055\u3044\u3002</div>'); } else { if (400 === jqXHR.status) { $(".lists").before('<div class="message">\u691c\u7d22\u30ad\u30fc\u30ef\u30fc\u30c9\u304c\u6709\u52b9\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002<br>1\u6587\u5b57\u4ee5\u4e0a\u3067\u691c\u7d22\u3057\u3066\u4e0b\u3055\u3044\u3002</div>'); } else { $(".lists").before('<div class="message">\u4e88\u671f\u305b\u306c\u30a8\u30e9\u30fc\u304c\u8d77\u304d\u307e\u3057\u305f\u3002<br>\u518d\u8aad\u307f\u8fbc\u307f\u3092\u884c\u3063\u3066\u304f\u3060\u3055\u3044\u3002</div>'); } } }) }); $(".reset-btn").on("click", function () { page = 1; lastSearchInput = ""; $(".lists").empty(); $(".message").remove(); $("#search-input").val("") }) }); ------------------------------------------------------------------------- この中でshowResult()と書いてある部分としては 冒頭のfunction showResult(result) { と 通信成功処理.done(function (data) {showResult(data["@graph"])}) がありました。 該当する箇所としては search-btnのクリックイベント、 $(".search-btn").on("click", function () {~の部分 通信成功処理、 .done(function (data) {showResult(data["@graph"])}) 通信失敗処理、 .fail(function (jqXHR) {~の部分 リセット処理 $(".reset-btn").on("click", function () {~の部分 だと思います。 今回エッセンス部分のプログラムの流れを解説頂いた内容からすると showResult(data["@graph"])で処理されたデータが showResult(result)に設定されるという様な仕組みに なっているのかと思いましたが、 順番に並べるにあたって showResult(data["@graph"])の部分だけどこかに移動すれば良いのか、 showResult(result)の部分をまるまる移動する必要があるのか どうすれば良いのでしょうか?
gosaro

2023/03/17 00:43

>showResult(data["@graph"])で処理されたデータが >showResult(result)に設定されるという様な仕組みに >なっているのかと思いましたが、 いいえ、違います。 オブジェクトの扱い方や関数呼び出しの仕組みといった初歩的なことが理解できていないとこれ以上解説をしても仕方がないです。 まずは基礎をしっかり固めて下さい。 課題の指摘について、答案の見本を書いておきます。 2/25のコメントの通り、通信失敗処理を showResult() と同様に独立した関数として切り分けています。 $(function () { let page = 1; let lastSearchInput = ""; //search-btnのクリックイベント $(".search-btn").on("click", function () { (中略) $.ajax({ url: "https://ci.nii.ac.jp/books/opensearch/search?title=" + currentSearchInput + "&format=json&p=" + page + "&count=20", method: "GET" }) .done(function (data) { showResult(data["@graph"]) }) .fail(function (jqXHR) { showError(jqXHR) }) }); //通信成功処理 function showResult(result) { (中略) }; //通信失敗処理 function showError(jqXHR) { $(".lists").empty(); $(".message").remove(); if (0 === jqXHR.status) { $(".lists").before('<div class="message">正常に通信できませんでした。<br>インターネットの接続の確認をしてください。</div>'); } else { if (400 === jqXHR.status) { $(".lists").before('<div class="message">検索キーワードが有効ではありません。<br>1文字以上で検索して下さい。</div>'); } else { $(".lists").before('<div class="message">予期せぬエラーが起きました。<br>再読み込みを行ってください。</div>'); } } } //リセット処理 $(".reset-btn").on("click", function () { (中略) }) });
mint5150

2023/03/30 09:40 編集

gosaro様いつもご回答頂きありがとうございます 綺麗なコードを頂いたのでずっと眺めていたら少しだけ データの流れや各ブロックの意味が分かったような気がしてきましたw 頂いたコードを元に以下の内容で提出してみました $(function () { let page = 1; let lastSearchInput = ""; //search-btnのクリックイベント $(".search-btn").on("click", function () { let currentSearchInput = $("#search-input").val(); if(currentSearchInput === lastSearchInput) { page = 1, $(".lists").empty(); //lastSearchInput = currentSearchInput } else { page++; } //ajax通信 $.ajax({url: "https://ci.nii.ac.jp/books/opensearch/search?title=" + currentSearchInput + "&format=json&p=" + page + "&count=20", method: "GET"}) .done(function (data) { showResult(data["@graph"]) }) .fail(function (jqXhr) { showError(jqXhr) }) }); //通信成功処理 function showResult(result) { $(".message").remove(); if(result[0].items.length > 0) { $.each(result[0].items, function (index, item) { let html = '<li class="lists-item"><div class="list-inner"><p>'; if (item.title) { html += item.title; } else { html += ""; } html += "</p><p>"; let creator = item['dc:creator'] ? html += item["dc:creator"] : html += ""; let publisher = item["dc:publisher"] ? html += item["dc:publisher"][0] : html += ""; let url = html += '</p><p>テスト<a href="'+ (item.link["@id"] +'" target="_blank"></a></p></div></li>'); let htmlResult = creator + publisher + url; /*元コード if (item['dc:creator']) { html += item["dc:creator"]; } else { html += ""; } html += "</p><p>"; if (item["dc:publisher"]) { html += item["dc:publisher"][0]; } else { html += ""; } html += '</p><a href="'; + (item.link["@id"] +'" target="_blank"></a></div></li>'); */ $(".lists").prepend(htmlResult) }) } else { $(".lists").before('<div class="message"></div>'); } }; //通信失敗処理 function showError(jqXhr) { $(".lists").empty(); $(".message").remove(); if (0 === jqXhr.status) { $(".lists").before('<div class="message">正常に通信できませんでした。<br>インターネットの接続の確認をしてください。</div>'); } else { if (400 === jqXhr.status) { $(".lists").before('<div class="message">検索キーワードが有効ではありません。<br>1文字以上で検索して下さい。</div>'); } else { $(".lists").before('<div class="message">予期せぬエラーが起きました。<br>再読み込みを行ってください。</div>'); } } } //リセット処理 $(".reset-btn").on("click", function () { page = 1; lastSearchInput = ""; $(".lists").empty(); $(".message").remove(); $("#search-input").val("") }) }); これについて以下の様な追加の修正依頼が来ました ①元コードの部分が冗長なのでitemから欲しい情報を三項演算子でそれぞれ代入し、それをもとに変数のhtmlに代入するようにして下さい →自分なりに参考演算子について調べてコードを書き換えてみました 検索してみて一応動いているみたいだったのですが正解でしょうか? ②リンクが表示されていないので修正お願いします →これについてはどうやったら表示できるのかが分かりません、 テストの文字については3つおきに表示されていて、aタグは表示されていないので 処理や式が間違っているのでしょうか? ③showErrorの条件としているエラーはどのような操作をしてその番号を確認したのか回答お願いします →「jqXhr.status」でGoogle検索したら以下のURLが出てきましたのでその番号なのかなと思います https://webty.jp/staffblog/production/post-437/ 検索バーを空欄で入力しても 正常に通信できませんでした。インターネットの接続の確認をしてください。 の方のメッセージが表示されるので400 === jqXhr.statusは動いていないという事でしょうか?
gosaro

2023/03/31 00:58

> ①元コードの部分が冗長なのでitemから欲しい情報を三項演算子でそれぞれ代入し、それをもとに変数のhtmlに代入するようにして下さい > →自分なりに参考演算子について調べてコードを書き換えてみました > 検索してみて一応動いているみたいだったのですが正解でしょうか? 三項演算子の書き方は文法的には正しいです。 しかし変数 html の扱い方が適切ではなく、元のコードと動作が変わっています。 元のコードと動作が変わらないように書き換えるのが修正依頼の趣旨だと思いますので、正解とは言えないと思います。 また、title についても三項演算子を使うことが期待されていると思います。 let creator = item['dc:creator'] ? html += item["dc:creator"] : html += ""; let publisher = item["dc:publisher"] ? html += item["dc:publisher"][0] : html += ""; let url = html += '</p><p>テスト<a href="' + (item.link["@id"] + '" target="_blank"></a></p></div></li>'); let htmlResult = creator + publisher + url; ↓ let creator = item['dc:creator'] ? item["dc:creator"] : ""; let publisher = item["dc:publisher"] ? item["dc:publisher"][0] : ""; let url = '</p><a href="' + (item.link["@id"] + '" target="_blank"></a></div></li>'); let htmlResult = html + creator + "</p><p>" + publisher + url; さしあたりこれで元のコードと同じ動作になります。 title については手を加えていないので、そこは上のコードを参考にして自分でやってみてください。 > ②リンクが表示されていないので修正お願いします > →これについてはどうやったら表示できるのかが分かりません、 > テストの文字については3つおきに表示されていて、aタグは表示されていないので > 処理や式が間違っているのでしょうか? <a> と </a> の間が空になっているので表示されていません。 > ③showErrorの条件としているエラーはどのような操作をしてその番号を確認したのか回答お願いします > →「jqXhr.status」でGoogle検索したら以下のURLが出てきましたのでその番号なのかなと思います > https://webty.jp/staffblog/production/post-437/ > > 検索バーを空欄で入力しても > 正常に通信できませんでした。インターネットの接続の確認をしてください。 > の方のメッセージが表示されるので400 === jqXhr.statusは動いていないという事でしょうか? そうなります。 jqXhr.status に何が設定されているかはデバッグすればわかります。 リンク先の情報はあくまでも一般論としてのコードの意味であり、個別の API サービスでどのように実装されているかはそのサービスの仕様を読むか実際に試してみなければわかりません。
mint5150

2023/04/01 17:12 編集

gosaro様いつもご回答頂きありがとうございます 現在のコードです $(function () { let page = 1; let lastSearchInput = ""; //search-btnのクリックイベント ※変更なし //ajax通信 ※変更なし //通信成功処理 function showResult(result) { $(".message").remove(); if(result[0].items.length > 0) { $.each(result[0].items, function (index, item) { let html = '<li class="lists-item"><div class="list-inner"><p>'; if (item.title) { html += item.title; } else { html += ""; } html += "</p><p>"; let creator = item['dc:creator'] ? item["dc:creator"] : ""; let publisher = item["dc:publisher"] ? item["dc:publisher"][0] : ""; let url = '</p><a href="' + (item.link["@id"] + '" target="_blank">'+item.link["@id"]+'</a></div></li>'); let htmlResult = html + creator + "</p><p>" + publisher + url; $(".lists").prepend(htmlResult) }) } else { $(".lists").before('<div class="message"></div>'); } }; //通信失敗処理 function showError(jqXhr) { $(".lists").empty(); $(".message").remove(); console.log("jqXHR:" + jqXhr.status); if (0 === jqXhr.status) { $(".lists").before('<div class="message">正常に通信できませんでした。<br>インターネットの接続の確認をしてください。</div>'); } else { if (400 === jqXhr.status) { $(".lists").before('<div class="message">検索キーワードが有効ではありません。<br>1文字以上で検索して下さい。</div>'); } else { $(".lists").before('<div class="message">予期せぬエラーが起きました。<br>再読み込みを行ってください。</div>'); } } } //リセット処理 ※変更なし }); ①修正頂いたコードで無事表示されました →title部分はまだ指摘されていませんが、フィードバック来たらやってみます ②<a> と </a> の間が空になっているので表示されていません。 →ヒント頂きありがとうございます。無事に表示されました ③jqXhr.statusのデバッグについてコンソールログを追加して 何も入力しないで検索ボタンを押すとjqXHR:0になりました if (0 === jqXhr.status)にした理由はそれで提出できそうですが if (400 === jqXhr.status) になっている部分について なぜ400番なのかが検証できていません https://webty.jp/staffblog/production/post-437/の ページを見てみるとエラーコードは色々あるみたいなのですが なぜ400なのでしょうか?
gosaro

2023/04/03 00:15

前回も書きましたがリンク先のエラーコード表はあくまでも一般的な意味をまとめたものにすぎません。 図書検索APIの仕様を見てもエラーコードについての記載がないので、なぜ400なのかはこのプログラムを書いた人に聞かなければわかりません。 結果的に適切な動作をしていないことから、よくわからないままどこかからコピペしてきただけのコードであるように思われます。
mint5150

2023/04/12 06:53

gosaro様いつもご回答頂きありがとうございます 回答コードの段階から400番と記載がありましたので失礼いたしました。 何も入力しないで検索ボタンを押すと、 コンソールログではステータスコード0番が返って来ますが、 ネットワークタブでは400番になっていましたので それが要因で400番にしたのではと講師の方へ解答した所、 「こちらではstatusにも400番返ってくることが確認できています。 クロスオリジンエラーが出てないかなど見返してください。 後は自力で解決してください」 と言われてしまい、困っている状態です。 どの様にデバッグすれば良いでしょうか? 現在のコードです $(function () { let page = 1; let lastSearchInput = ""; //search-btnのクリックイベント $(".search-btn").on("click", function () { let currentSearchInput = $("#search-input").val(); if(currentSearchInput === lastSearchInput) { page = 1, $(".lists").empty(); //lastSearchInput = currentSearchInput } else { page++; } //ajax通信 $.ajax({url: "https://ci.nii.ac.jp/books/opensearch/search?title=" + currentSearchInput + "&format=json&p=" + page + "&count=20", method: "GET"}) .done(function (data) { showResult(data["@graph"]) }) .fail(function (jqXhr) { showError(jqXhr) }) }); //通信成功処理 function showResult(result) { $(".message").remove(); if(result[0].items.length > 0) { $.each(result[0].items, function (index, item) { let html = '<li class="lists-item"><div class="list-inner"><p>'; if (item.title) { html += item.title; } else { html += ""; } html += "</p><p>"; let creator = item['dc:creator'] ? item["dc:creator"] : ""; let publisher = item["dc:publisher"] ? item["dc:publisher"][0] : ""; let url = '</p><a href="' + (item.link["@id"] + '" target="_blank">'+item.link["@id"]+'</a></div></li>'); let htmlResult = html + creator + "</p><p>" + publisher + url; /* if (item['dc:creator']) { html += item["dc:creator"]; } else { html += ""; } html += "</p><p>"; if (item["dc:publisher"]) { html += item["dc:publisher"][0]; } else { html += ""; } html += '</p><a href="'; + (item.link["@id"] +'" target="_blank"></a></div></li>'); */ $(".lists").prepend(htmlResult) }) } else { $(".lists").before('<div class="message"></div>'); } }; //通信失敗処理 function showError(jqXhr) { $(".lists").empty(); $(".message").remove(); if (0 === jqXhr.status) { $(".lists").before('<div class="message">正常に通信できませんでした。<br>インターネットの接続の確認をしてください。</div>'); } else { if (400 === jqXhr.status) { $(".lists").before('<div class="message">検索キーワードが有効ではありません。<br>1文字以上で検索して下さい。</div>'); } else { $(".lists").before('<div class="message">予期せぬエラーが起きました。<br>再読み込みを行ってください。</div>'); } } console.log("jqXHR:" + jqXhr.status); } //リセット処理 $(".reset-btn").on("click", function () { page = 1; lastSearchInput = ""; $(".lists").empty(); $(".message").remove(); $("#search-input").val("") }) });
gosaro

2023/04/13 00:57

確かにクロスオリジンエラーが出ていますね。 Access to XMLHttpRequest at 'https://ci.nii.ac.jp/books/opensearch/search?title=&format=json&p=1&count=20' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. しかし、講師の環境でこれが出ないと言われてもどんな環境を使っているのか私には知るすべがありません。 元々の問いは ③showErrorの条件としているエラーはどのような操作をしてその番号を確認したのか回答お願いします ということだったと思います。 仕様に明記されているわけではなく、環境によって結果が変わるともなると、繰り返しになりますが、「作った人に聞かなければわからない」です。
mint5150

2023/04/13 19:40

gosaro様いつもご回答頂きありがとうございます。 確認できない質問で申し訳ございません。 クロスオリジンエラーが出ているという事ですが、 どの様に確認されましたでしょうか? 「クロスオリジンエラー 確認方法」などでググってみましたが 解決方法は書いてあってもどの様に確認したのかは見つけられませんでした。 ディベロッパーツールなどでどこかに表示がされているものなのでしょうか?
gosaro

2023/04/13 23:57

>クロスオリジンエラーが出ているという事ですが、 >どの様に確認されましたでしょうか? Chrome に HTML ファイルをドロップして検索ワードを入力しないで検索ボタンをクリックすると、前のコメントに記載したエラーがディベロッパーツールのコンソールに出力されます。
guest

0

ベストアンサー

4行目まで : $jscomp はIEに対応するためのものらしいですが、詳細は分かりません。
7行目の a : 検索結果を表示する関数です。名前は showResult など。
7行目の e : 検索結果を受け取る引数です。名前は result など。
9行目の b : 検索結果の最初の項目を代入する変数です。名前は firstItem など。
21行目の h : 検索結果の各項目の位置を受け取る引数です。名前は index など。
21行目の c : 検索結果の各項目を受け取る引数です。名前は item など。
22行目の g : c を元に生成した HTML を代入する変数です。名前は html など。
28行目の d : 同じ検索ワードで検索した回数を数える変数です。API のページパラメータとして使用されます。名前は page など。
28行目の f : 最後に検索したときの検索ワードを保存する変数です。名前は lastSearchInput など。
29行目の e : 現在の検索ワードを代入する変数です。名前は currentSearchInput など。
37行目の done 内の b : API で取得したデータを受け取る引数です。名前は data など。
37行目の fail 内の b : API がエラーになった場合にエラーの内容などを受け取る引数です。名前は jqXHR など。

3項演算子を if 文に書き換えるのは次のようにします。

JavaScript

1let g = '<li class="lists-item"><div class="list-inner"><p>\u30bf\u30a4\u30c8\u30eb\uff1a'; 2if (c.title) { 3 g += c.title; 4} else { 5 g += "\u30bf\u30a4\u30c8\u30eb\u4e0d\u660e"; 6} 7g += "</p><p>\u4f5c\u8005\uff1a"; 8if (c['dc:creator']) { 9...

他にわからないところがあればどうぞ。
気が向いたら回答するかもしれません。

投稿2023/02/21 05:58

gosaro

総合スコア24

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

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

mint5150

2023/02/21 12:50

この度はご回答頂きありがとうございます。 教えて頂いた内容を参考に修正しとりあえず課題を提出することが出来ました。 それぞれのコード文がどんな役割をしているのか、仕組みは分かっておりませんので もし可能でしたら解説頂けると大変助かります。 他の方のコメントで指摘されたように過大な要求かも知れませんので その場合はどの様にして解析していけば理解できるのか 学習方法のアドバイスを頂けるとありがたいです。 この度は丁寧なご回答頂きありがとうございます。
gosaro

2023/02/22 00:33

とりあえず関数の範囲は把握できているでしょうか。 6行目で始まる $(function () { と7行目で始まる function a(e) { がそれぞれ何行目で終わっているのか。 $(function () { の直下には function a(e) { の他に関数がいくつあって、それぞれ何行目から何行目までなのか。 また、function a() については先の回答で理解できたでしょうか。 できないならどのあたりがわからないのかコメントください。
mint5150

2023/02/23 12:59

gosaro様、ご返信ありがとうございます。 6行目で始まる $(function () {は49行目 7行目で始まる function a(e) {は26行目 21行目で始まるfunction (h, c) {は23行目 29行目で始まる function () {は42行目 37行目で始まるdone(function (b) {は37行目 a(b["@graph"]) } 37行目で始まるfail(function (b) {は41行目 までの範囲でよろしいでしょうか? function a() についても仕組みが良く分かっていません P.S.提出後の追加のフィードバックとして ・search-btnのクリックイベント、通信成功処理、通信失敗処理、リセット処理の 順番に並べて下さい ・32行目に目的の違う処理が1行にまとめてあるのでそれぞれ改行して下さい ・37行目の処理の見通しが悪いので改行を入れて整理して下さい という指摘をされましたがどの様にすれば良いのでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問