できる! javascriptでローディングアニメ(Nowloading)をページに実装する
4つのパターンのサンプル
~GIF animation, Web icon spinner, CSS animation & YouTube-like Loading bar animation~

1.  準備 | 2.  ローディングアニメ実装方法  | 2-1  ローディング中表示、非表示の方法| 2-2  ローディングアニメ実装方法 - 4パターン

ローディングアニメ(Nowloading)をYouTube検索ページ(PHP)に実装してみました。 実装対象のYouTube検索ページ(PHP)の元ソースコードは、つぎのサイトの「動画の検索(認証なし)」HTMLサンプル(フリー)です。
https://phpjavascriptroom.com/?t=strm&p=youtubedataapi_v3_list#a_search_noauth_video


本ページでは、つぎの4つのローディングアニメ画像を使用し、それぞれの実装サンプルについて説明します。

1.  準 備

使用するYouTUbe検索HTML、ローディングアニメ画像などをフリー画像を公開しているサイトからダウンロードして準備します。

  1. YouTUbe検索HTML
    つぎのサイトからYouTube検索HTMLのソースをコピーして、HTMLファイルからPHPファイルに変更します。
    https://phpjavascriptroom.com/?t=strm&p=youtubedataapi_v3_list#a_search_noauth_video
    PHPに変更する理由は、HTMLファイルは検索キーワードが固定になっているので、入力フォームを設け検索キーワードを入力できように変更改造します。
    なお、YouTUbe検索を自サイトに構築する場会は、googleサイトよりYouTube API Keyを取得する必要があります。
    ・参考サイト : YouTube APIキーの取得 (2020/03/25時点)
  2. GIFアニメ画像(SVG画像も可) ↓以下の2,3,4項の総目次=https://www.benricho.org/loading_images/
    GIF:https://www.benricho.org/loading_images/size01.html
          https://www.benricho.org/loading_images/popular01.html
          https://www.benricho.org/loading_images/transparent01.html
    SVG:https://www.benricho.org/loading_images/svg01.html
  3. FontAwesomeのWebアイコンフォント
    https://www.benricho.org/loading_images/webfont.html
  4. CSSのみで生成したアニメ画像
    https://www.benricho.org/loading_images/withCSS/
    https://www.benricho.org/loading_images/withCSS_02
    https://www.benricho.org/loading_images/withCSS_03
    https://www.benricho.org/loading_images/withCSS_04/
    https://www.benricho.org/loading_images/withCSS_05/
    https://www.benricho.org/loading_images/withCSS_06/
    https://www.benricho.org/loading_images/withCSS_07/
  5. javascriptで描いたYouTube風線画アニメ(横線アニメーション.js使用)
    https://qiita.com/nekoneko-wanwan/items/2827feaf5a831a0726aa

・本ページで使用したローディングアニメ画像
1. GIFアニメ画像

2. FontAwesomeのWebアイコンフォント

3. CSSのみで生成したアニメ画像

4. javascriptで描いたYouTube風線画アニメ

上、灰色線上に赤線が左から右へ描かれます。

2.  ローディングアニメ実装方法

  ローディング中表示、非表示の方法

ローディング中表示、非表示を行うJabascriptなどの機能(スペック)は、つぎのとおり10のスペックで構成されています。 ただし、表示するローディングアニメの種類により多少の違いがありますす。

表示するローディングアニメの種類はつぎのとおりです。アニメは、上spec-7 ローディング中表示アニメ画像配置DIV域に置きます。 ローディングアニメの種類と使用スペックの対応を下表に示します。

表示アニメのパターン(種類)spec-1spec-2spec-3spec-4spec-5spec-6spec-7spec-8spec-9spec-10spec-11
1. GIFアニメ画像
2. FontAwesomeのWebアイコンフォント
3. CSSのみで生成したアニメ画像
4. javascriptで描いたYouTube風線画アニメ

つぎに、下タブメニューに示すコードは実装対象の「YouTube検索HTML」の中に、11のスペックコードをどの位置に配置するかを「表示するアニメ」の種類ごとに示します。 実装追加するスペックコードを青字で示し、スペック番号(1-11)を付与しています。
なお、元のYouTube検索HTMLコードのJavascript(7行目から194行目)の部分は省略形で表示しています。

・実装スペック配置場所ソースコード

<html>
<head>
   <meta charset="utf-8">
   <link rel="stylesheet" type="text/css" href="/module/include/strm/youtubedataapi_v3_list/style.css">
   <title>YouTubeAPIv3サンプル | 再生リストの動画検索(認証なし)</title>
   <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>  ←6行目
<?php //spec-1前部 YouTube検索javascript
if(isset($_REQUEST['keyword'])){
$keyWord = $_REQUEST['keyword'];  // 検索キーワード
print <<<YOU
  <script>   ←7行目
      /* 開発キー
         https://code.google.com/apis/console
      */
      var APIKEY="AIzaSyC3VBRnfUU9_qO1Gr1ARBO8BZLT-Sp6vFc";   // ←11行目 YuTube API KEY 要変更 
 
      function onJSClientLoad() {
         dbg("★onJSClientLoad");
         gapi.client.setApiKey(APIKEY);
         gapi.client.load('youtube', 'v3', function(){
            $.getYouTubeResults({
               query:"$keyWord",     // ←18行目 "ハムスター hamster"を"$keyWord"に変更
               order:"date",
               limit:50,
               maxResults:10
            });
         });
      }
          ・
          ・ 
   </script>   ←194行目 
YOU;
}      //spec-1後部 YOU;から3行
?>

<style>
/* spec-2 ローディング画面フェードレイヤーCSS  */
#fadeLayer {
  position:absolute;
  top:0px;
  left:0px;
  width:100%;
  height:100%;
  background-color:#000000;  /* 黒 */
  opacity:0.50;
  visibility:hidden;
  z-index:10;
}

/* spec-3  ローディングアニメ表示域CSS  */
#nowLoading {
 position: absolute;
 left: 580px; 
 top: 150px; 
 width: 48px;  
 height: 48px; 
 visibility: hidden; 
 text-align: center; 
 border-radius: 50%;
}
</style>

<script>   // spec-4 ローディング中非表示javascript
window.onload = function() {
  document.getElementById("nowLoading").style.visibility="hidden";  //ローディングアニメ画像非表示 
  document.getElementById("fadeLayer").style.visibility="hidden";      //ローディング終了時のフェード画面(明るくする)
  document.getElementById("keyWord").value = "<?php echo $_REQUEST['keyword'] ?>";
};
</script>

   <script src="https://apis.google.com/js/client.js?onload=onJSClientLoad"></script> ←195行目
<link rel="stylesheet" type="text/css" href="/common/css/example.css"></head>
</head>
<body>
<!-- spec-5 YouTube検索フォーム -->
<form name="sform" ACTION="#" method=post>
<input type="search" value="" name="keyword" size=50 id="keyWord">
<input type="submit" value="YouTube検索">
</form>

<h3 class='h'>実行結果</h3>
   <h1>設置サンプル:[YouTube API(v3) - 動画検索(認証なし)</h1>
   <p>   'ハムスター'または'hamster'がタイトルに含まれる動画を、新着順に上限50まで取得するサンプル。 取得制限数は、スクリプト側でかけてます。</p>
   <div id="message"></div>
   <div id="results"></div>

<!-- spec-6 ローディング中表示画面フェイドレイヤーDIV域 -->
<div id="fadeLayer"></div>

<!-- spec-7 ローディング中表示アニメ画像配置DIV域 --> 
<div id="nowLoading"><img src="nowloading-712-48.gif" id="imgloading" width=48></div>

 
<?php  // spec-8 ローディング中表示javascript 上2つDIV域の後に配置
if(isset($_REQUEST['keyword'])){
   print "<script>\n";               
   print "document.getElementById('nowLoading').style.visibility='visible';\n";  //ローディングアニメ画像表示 
   print "document.getElementById('fadeLayer').style.visibility='visible';\n";      //ローディングアニメ表示中のフェード画面(うす暗くする)
   print "</script>";
}
?>

</body>
</html>

  【注】
「 4. YouTube風線画アニメ」の「spec-10 横線アニメーション」は、jQuery animate関数を使用すると、つぎの数ステップのコードで実現できます。 合せて、CSS(spec-3)とアニメ画像配置(spec-7)を差し替えます。
<style>
/* spec-3  ローディングアニメ表示域CSS  */
#nowLoading {
 position: absolute;
 left: 0px; 
 top: 0px; 
 width:2px;
 height:2px;
 background-color: red;
 visibility: hidden; 
}
</style>

<!-- spec-10 横線アニメーション -->
<script>
function drawHorizontalLineAnim(){
$(function(){
    $('.box3').animate({
        width: '100%'
     }, 5000, 'linear');

});
}
</script>

<!-- spec-7 ローディングアニメ画像配置DIV域 --> 
<div id="nowLoading"></div>

  ローディングアニメ実装方法 - 4パターン

YouTube検索原本MTMLに対して、上記各スペックを実装配置した結果のPHPソースコード(全体)をローディングアニメごとに、下タブメニューに示します。 PHPソースコードは、実装配置したコードの部分をライトブルー背景で表示しています。

・実装スペック配置手順

  1. 下0.YouTube検索原本MTMLをコピーしてテキストエディターに貼り付けます。
  2. 上実装スペック配置場所ソースコードより、好みの該当パターンの表示アニメのスペック(青字)をコピーし、
    YouTube検索原本MTMLコードに配置します。
  3. 該当スペックのスペックの配置が終わったら、任意のファイル名で拡張子を.phpで保存します。
  4. 走行確認には、つぎの項目の修正設定が必要です。

・ローディングアニメ実装済みPHPの4パターンのデモ:

  1. GIFアニメ画像
  2. FontAwesomeのWebアイコンフォント
  3. CSSのみで生成したアニメ画像
  4. javascriptで描いたYouTube風線画アニメ


・実装コード配置済みPHPソースコード
  1. <html>
  2. <head>
  3. <meta charset="utf-8">
  4. <link rel="stylesheet" type="text/css" href="/module/include/strm/youtubedataapi_v3_list/style.css">
  5. <title>YouTubeAPIv3サンプル | 再生リストの動画検索(認証なし)</title>
  6. <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
  7. <script>
  8. /* 開発キー
  9. https://code.google.com/apis/console
  10. */
  11. var APIKEY="AIzaSyC3VBRnfUU9_qO1Gr1ARBO8BZLT-Sp6vFc";
  12.  
  13. function onJSClientLoad() {
  14. dbg("★onJSClientLoad");
  15. gapi.client.setApiKey(APIKEY);
  16. gapi.client.load('youtube', 'v3', function(){
  17. $.getYouTubeResults({
  18. query:"ハムスター hamster",
  19. order:"date",
  20. limit:50,
  21. maxResults:10
  22. });
  23. });
  24. }
  25. (function($){
  26. $.getYouTubeResults=function(options){
  27. dbg("★getYouTubeResults");
  28. var opt=$.extend({
  29. query:"",
  30. type:"video",
  31. maxResults:10,
  32. limit:0,
  33. channelId:"",
  34. regionCode:"JP", /* 国コード */
  35. order:"viewCount", /* 検索順 */
  36. part:"id, snippet, status",
  37. fields:""
  38. },options);
  39.  
  40. var pageToken="",s="";
  41. var allcnt=0,j=0,totalResults=0,resultsPerPage=0,total=0;
  42.  
  43. var requestOptions = {
  44. maxResults:opt.maxResults, //1ページ当たりの結果数最大値(0-50)デフォルト10
  45. q:opt.query, /* 検索キーワード */
  46. regionCode:opt.regionCode,
  47. type:opt.type,//video,channel,playlist
  48. order:opt.order,
  49. /*
  50. publishedAfter
  51. publishedBefore
  52. topicId
  53. videoCaption
  54. videoCategoryId
  55. videoDefinition
  56. videoDimension
  57. videoDuration
  58. videoEmbeddable
  59. videoLicense
  60. "relatedToVideoId:"0f1SLJEY6iY",//指定した動画の関連動画のみ検索対象とする
  61. videoSyndicated youtube.com外で再生できる動画のみ検索
  62. channelId チャンネル固有ID(ユーザー名ではない)を指定すると、そのチャンネル内での検索となる
  63. */
  64. "part":"id,snippet"
  65. };
  66. if(opt.fields!="") requestOptions.fields=opt.fields;
  67. makeRequest();
  68.  
  69. /* APIリクエスト */
  70. function makeRequest(){
  71. dbg("★makeRequest:"+pageToken);
  72. if(pageToken){
  73. requestOptions.pageToken=pageToken;
  74. }
  75. var request=gapi.client.request({
  76. mine:"",
  77. path:"/youtube/v3/search",
  78. params:requestOptions
  79. });
  80. request.execute(function(resp) {
  81. dbg(resp);
  82. if(resp.error){
  83. $("#message").html(resp.error.message);
  84. }else{
  85. output(resp,pageToken);
  86. }
  87. });
  88. }
  89. /* HTML出力 */
  90. function output(resp,pageTokenFLG){
  91. pageToken=resp.nextPageToken;
  92. /* dbg("output");dbg("pageToken:"+pageToken); */
  93. if(pageTokenFLG==""){
  94. var pageInfo=resp.pageInfo;
  95. resultsPerPage=resp.pageInfo.resultsPerPage; /* APIレスポンスに含まれる結果の数 */
  96. totalResults=resp.pageInfo.totalResults; /* 結果セット内の結果の合計数 */
  97. if(opt.limit>0 && totalResults> opt.limit){
  98. totalResults=opt.limit;
  99. }
  100. total=Math.floor(totalResults/resultsPerPage);
  101. if(totalResults<=resultsPerPage){
  102. total=1;
  103. }else if(totalResults%resultsPerPage!=0){
  104. total++;
  105. }
  106. dbg("total:"+total+"/resultsPerPage:"+resultsPerPage+"/totalResults:"+totalResults);
  107. s+="<li>結果数最大値の指定:"+opt.maxResults+"</li>";
  108. s+="<li>結果セット内の結果合計数:"+pageInfo.totalResults+"</li>";
  109. s+="<li>1レスポンスに含まれる結果数:"+pageInfo.resultsPerPage+"</li>";
  110. s+="<li>取得数上限:"+((opt.limit==0)?"∞":opt.limit)+"</li>";
  111. s+="<li>リクエスト回数:"+total+"</li>";
  112. $("#results").append("<h2>Results</h2>"+s);
  113. s="";
  114. if(totalResults==0){
  115. $("#message").html("検索条件に一致するデータがありませんでした");
  116. }
  117. }
  118. itemOutput(resp.items);
  119. allcnt++;
  120. if(allcnt<total){
  121. makeRequest();
  122. }else{
  123. $("#results").append("<h2>Search Results</h2>"+s);
  124. }
  125. }
  126. function itemOutput(items){
  127. //dbg("allcnt:"+allcnt+"/j:"+j);
  128. $.each(items, function(i, item){
  129. if(j>=opt.limit) return;
  130. j=(allcnt*resultsPerPage)+i+1;
  131. if(item.id && item.snippet){
  132. s+="<dl>";
  133. /* id */
  134. var id=item.id.videoId;
  135. var kind=item.id.kind;
  136. var thumbnails_default="no thumbnails";
  137. var snippet=item.snippet;
  138. var title=(snippet.title)?snippet.title:"no title";
  139. var channelId=(snippet.channelId)?snippet.channelId:"no channelId";
  140. var channelTitle=(snippet.channelTitle)?snippet.channelTitle:"no channelTitle";
  141. var pubdatedAt=(snippet.publishedAt)?formatDate(snippet.publishedAt):"no publishedAt";
  142. var description=(snippet.description)?snippet.description:"no description";
  143. if(snippet.thumbnails){
  144. $.each(snippet.thumbnails, function(y, ytem){
  145. //default, medium, height
  146. if(y=="default"){
  147. thumbnails_default=ytem.url;
  148. }
  149. });
  150. }
  151. s+="<dt>";
  152. s+="<a href='http://www.youtube.com/watch?v="+id+"'><img src='"+thumbnails_default+"'></a>";
  153. s+="</dt><dd>【"+j+"】";
  154. s+="<p>種類:"+kind+"</a></p>";
  155. s+="<p>動画タイトル(ID):<a href='http://www.youtube.com/watch?v="+id+"'>"+title+"("+id+")</a></p>";
  156. s+="<p>動画が属するチャンネルのタイトル(ID): <a href='http://www.youtube.com/channel/"+channelId+"'>"+channelTitle+"("+channelId+")</a></p>";
  157. s+="<p>動画の公開日: "+pubdatedAt+"</p>";
  158. s+="<p>動画の説明文:"+description+"</p>";
  159. /*
  160. if(snippet.resourceId && snippet.resourceId.videoId){
  161. s+="<p>resourceId.videoId:<a href='http://www.youtube.com/watch?v="+snippet.resourceId.videoId+"'>"+snippet.resourceId.videoId+"</a></p>";
  162. }
  163. */
  164. s+="</dd></dl>";
  165. }
  166. });
  167. }
  168. return this;
  169. }
  170. })(jQuery);
  171. var formatDate=function(str){
  172. var tmp=str.split("T");
  173. var ymd=tmp[0].split("-");
  174. var hms=tmp[1].split(":");
  175. var sec=hms[2].split(".")[0];
  176. var d=new Date(new Date(ymd[0], ymd[1]-1, ymd[2], hms[0], hms[1], sec).getTime()+(1000*60*60*9)); //+9h
  177. var year=d.getFullYear();
  178. var month=d.getMonth()+1;
  179. var day=d.getDate();
  180. var hour=(d.getHours() < 10 ) ? '0'+d.getHours() : d.getHours();
  181. var min =(d.getMinutes() < 10 ) ? '0'+d.getMinutes() : d.getMinutes();
  182. var sec =(d.getSeconds() < 10 ) ? '0'+d.getSeconds() : d.getSeconds();
  183. return year+"/"+month+"/"+day+" "+hour+":"+min;//+":"+sec;
  184. }
  185. var dbg=function(str){
  186. try{
  187. if(window.console && console.log){
  188. console.log(str);
  189. }
  190. }catch(err){
  191. //alert("error:"+err);
  192. }
  193. }
  194. </script>
  195. <script src="https://apis.google.com/js/client.js?onload=onJSClientLoad"></script>
  196. <link rel="stylesheet" type="text/css" href="/common/css/example.css"></head>
  197. <body id='example3' class='example'><div class="ads" style="margin:32px auto;text-align:center;"></div><h1 class='h'><a href='/'>PHP & JavaScript Room</a> :: 設置サンプル</h1>
  198. <h3 class='h'>実行結果</h3>
  199. <h1>設置サンプル:[YouTube API(v3) - 動画検索(認証なし)</h1>
  200. <p> 'ハムスター'または'hamster'がタイトルに含まれる動画を、新着順に上限50まで取得するサンプル。 取得制限数は、スクリプト側でかけてます。</p>
  201. <div id="message"></div>
  202. <div id="results"></div>
  203. </body>
  204. </html>
  【注】
「1. GIFアニメPHP」には、デッバグ用にsleep関数(javascript)を挿入配置(271~282行)しています。理由は、検索時間を長引かせて ローディングアニメの動作を確認するためです。起動は、ローディング中非表示の先頭で行います(233行目)。
<!-- ローディングアニメ動作確認用 sleep関数 -->
<script>
//引数にはミリ秒を指定します。(例:5秒の場合は5000)
function sleep(a){
  var dt1 = new Date().getTime();
  var dt2 = new Date().getTime();
  while (dt2 < dt1 + a){
    dt2 = new Date().getTime();
  }
  return;
}
</script>

1.  準備 | 2.  ローディングアニメ実装方法  | 2-1  ローディング中表示、非表示の方法| 2-2  ローディングアニメ実装方法 - 4パターン



 ソーシャルボタン関連サイト内リンク

  1. オリジナルデザインのソーシャルボタンにカウントを設置する方法 - デザインボタン 9サイト - Twitter, Facebook, Google+, Hatena, Pinterest, Feedly, LDR, Pocket, Linkedin
  2. 公式サイトへ行かずに、簡単に手元でソーシャルボタンをまとめて設置する Lightboxなどのモーダルウィンドウ上にも設置できる ~公式ボタン、非公式デザインボタンどちらでも17SNS/RSSサイト! 34種類余り~
  3. ソーシャルボタンカウント取得PHPの使い方 ~ カウントのない公式ソーシャルボタンにカウントを付ける ~ Facebook, Google+, Hatena, Pinerest, Feedly, LDR, Pocket, Linkedin, Buffer, Twitter - 10サイト -
  4. ソーシャルボタン、カウントをボタンの中に付ける ~ 公式ボタン、デザインボタン ~ Twitter, Facebook, Google+, Hatena, Pinerest, Feedly, LDR, Pocket, Linkedin, Buffer - 10サイト -
  5. 10サイト、ソーシャルボタンのカウント設置を、5つのパターンから好きな場所に付ける ソーシャルボタンのカウントを、ボタンの右、ボタンの左、ボタンの上、ボタンの下、ボタンの中の5つのパターンから好きな場所に付ける - 公式ボタン、デザインボタン 10サイト - Twitter, Facebook, Google+, Hatena, Pinerest, Feedly, LDR, Pocket, Linkedin, Buffer
  6. Lineで送るカスタムボタンのリンクウインドウを小窓で表示する
  7. 自分のページの いいね!ボタン の設置方法
  8. できる!ブログなどのレス記事に、自作のいいねボタンを動的に設置する。 KENTWEB ASKA BBS のレス記事に自作のいいねボタンといまいちボタンをカスタマイズできる。 ~ CGI + PHP + MySQL + jQuery + Ajax ~(本ページ)
  9. できる!自分のページの「いいね!ボタン」を設置する 新バージョン - いいね!ボタン Ver2 投票数のカウントは、データベースMySQLが使用できる。 いいね!ボタンをレス記事などに動的配置できる。~ PHP + MySQL + jQuery + Ajax ~
  10. まとめて設置のデモ - モーダルウィンドウにも
  11. Facebookソーシャルボタン、アクセストークンを使用して 実際の いいね!カウント数 や シェアカウント数 を表示設置する方法 現在、facebook公式のいいねボタンとシェアボタンは共に同じ値のカウント総数が表示される。
  12. 公式ソーシャルボタンのカウントをカラー吹き出しで表示する ―ソーシャルボタンカウント取得PHPとカラー吹き出しCSSの使い方 ~ カウントのないソーシャルボタンにカラフルなカウントを付ける ~ Facebook, Hatena, Pinerest, Feedly, Pocket, Buffer, Twitter 7 サイト

-

 最終更新日:2020.12.07
アクセス解析