jQuery samples - Ajax時にローディングを表示

jQuery samples - Ajax時にローディングを表示

本エントリーは「to-R JavaScript Advent Calendar 2015」17日目のエントリー、今回のjQuery samplesは、Ajax時にローディングを表示する方法についての解説です。

単純に Ajax時にローディングを表示する方法から僅かに遅延させる方法、共通設定にする方法まで解説していきます。

CSS3でローディングを設定

まずは以下の様なHTML/CSSでローディングを作成しておきましょう。

<button id="ajax">ajax</button>
<ul id="list"></ul>
<div class="loading">
	<div class="loading_icon"></div>
</div>
.is-hide{
 display:none; 
}
.loading{
  position:fixed;
  top:0;
  right:0;
  bottom:0;
  left:0;
  background:rgba(0,0,0,.5);
}
.loading::before{
  content:"";
  display:block;
  position:fixed;
  left:50%;
  top:50%;
  width:50px;
  height:50px;
  border-radius:5px;
  margin-top:-15px;
  margin-left:-15px;
  background:white;
}
.loading::after{
  content:"";
  display:block;
  position:fixed;
  left:50%;
  top:50%;
  width:32px;
  height:32px;
  border-radius:20px;
  margin-top:-10px;
  margin-left:-10px;
  border:4px solid #60ABB9;
  border-right:4px solid white;
  animation: rotate 1s infinite linear;
}
@keyframes rotate {
  0%    { transform: rotate(0deg); }
  100%  { transform: rotate(360deg); }
}

これは以下のように表示されます。

See the Pen CSS3でローディングを設定 by Kazuma Nishihata (@to-r) on CodePen.

.loadingに対するis-hideクラスの取り外しでローディングの表示・非表示を切り替えますので、実際には初期表示時では.loadingにis-hideクラスが付与されています。

単純に Ajax時にローディングを表示する方法

$.ajaxはAjax送信前にbeforeSendイベントがAjax成功時にsuccessイベントが発火しますのでそれらのイベント時にis-hideクラスの取り外しを行います。

$("#ajax").click(function(){
	var $loading = $(".loading");
	$.ajax({
		url:"http://codepen.io/to-r/pen/bEeBrP.js",
		dataType:"json",
		beforeSend:function(){
			$loading.removeClass("is-hide");
		},
		success: function(data){
			$loading.addClass("is-hide");
			data.items.forEach(function(item){
				$("#list").append("<li>"+item.title+"</li>");
			});
		}
	});
});

これは以下のように表示されます。

See the Pen jQuery samples - Ajax時にローディングを表示 by Kazuma Nishihata (@to-r) on CodePen.

通信環境によってはローディングは一瞬しか表示されないでしょう。あまり早すぎるとユーザーは何がおこったかわかりませんので、ローディング画像は最低限400msは表示するように修正します。

僅かに遅延させる方法

通信環境が遅い場合は遅延させる必要はありませんので、400ms以内に通信が完了した場合のみ遅延させるようにします。

JavaScriptは以下のように改造します。

$("#ajax").click(function(){
	var $loading = $(".loading");
	var def = $.ajax({
		url:"http://codepen.io/to-r/pen/bEeBrP.js",
		dataType:"json",
		beforeSend:function(){
			$loading.removeClass("is-hide");
		}
	});
	setTimeout(function(){
		$.when(def).done(function(data){
			$loading.addClass("is-hide");
			data.items.forEach(function(item){
				$("#list").append("<li>"+item.title+"</li>");
			});
		});
	},400);
});

Defferdを利用して$.ajaxが成功時のイベント(done)は400ms待ってから出ないと発火しないように設定しています。

See the Pen jQuery samples - Ajax時にローディングを表示2 by Kazuma Nishihata (@to-r) on CodePen.

共通設定にする方法

全部のAjax通信がある箇所で上記のような記述をイチイチしていると面倒ですのでAjaxの共通設定にしてしまいましょう。

documentのajaxSendというイベントで全部のAjaxで通信が発生する前に発火するイベントが設定可能です。また、新たにloadingHideというイベントを定義しておきloadingが消えたタイミングでこのイベントが発火するように設定しておきます。

//共通設定
$(document).on("ajaxSend", function(e,jqXHR,obj){
	var $loading = $(".loading");
	$loading.removeClass("is-hide");
	setTimeout(function(){
		$.when(jqXHR).done(function(data){
			$loading.addClass("is-hide");
			obj.loadingHide(data);
		});
	},400);
});
//個別設定
$("#ajax").click(function(){
	$.ajax({
		url:"http://codepen.io/to-r/pen/bEeBrP.js",
		dataType:"json",
		loadingHide:function(data){
			data.items.forEach(function(item){
				$("#list").append("<li>"+item.title+"</li>");
			});
		}
	});
});

これは以下のように表示されます。

See the Pen jQuery samples - Ajax時にローディングを表示3 by Kazuma Nishihata (@to-r) on CodePen.

スポンサードリンク

«jQuery samples - jQueryでCSSの!importantを設定 | メイン | npmとBrowserifyでjQueryを管理する»