日記ブログ、または雑多なメモ
2014年1月16日

埋め込みギャラリーまだ終わらない/Javascript ajax または jquery deferred






 swiperに乗り換え、ネット上に落ちてたlazyloadのコードを仕込み、完了ぉ~~と思ってたら完了してなかった件。

落ちてたコードはlazyloadはlazyloadだが、html上のdata-srcをページ読込み完了時に一気にsrcに変換するだけで、そらまあ、一気に読み込むわな。
で、swiperの機能でスライドのappend機能があるので、それを併用してlazyloadを発火させれば逐次画像ロードとなり結果オッケーなわけである。

 さあ、改造だ。

 ……なんか、swiper、人気ないのか情報がめちゃ少ないのであれやこれやとトライしつつ、仕事をしつつ、ぼちぼちとスライド追加のコードを書いてみた。 で、いざ動かしてみるとスライドの追加自体はできたのだが、追加の途中で描画をやめてしまう。 エレメントとしては読み込み済みなのだが、先頭の5個辺りまでくらいしか描画しない。 ブラウザの窓の大きさを変えたりして再描画させると出てくる。

 もう、はにゃーん ですよ。

 しばらくなんでやねーん、とのたまいながらも、ふと、連続でぶち込みすぎてアップアップしてるんだろうと思いつき、 setTimeOutで200msずつずらして読み込んだらちゃんと描画してくれた。 しかし、単にsetTimeoutでずらすのはちょっとダサい……。 ここはajaxとか使ってみたい!と思うが、実はajaxが何かあまりよくわかっていなかったのであった。 どうしてもコナミのゲームが出てくるし。

 いろいろ調べてみるとajaxのくくりで調べると間口が広すぎてさっぱりなので、jqueryのdeferredで検索してみると、ばっちりそのままのコードを発見。

jQuery.Deferred を使って非同期な繰り返し処理を行う


 そのまま、for文+setTimeoutで組んでいたところをこのコードに置き換えて、非同期読込み(ほぼ)完璧。

onclick.wrapper.js (deleted) (要fancybox)
ajax.deferred.js (deleted)
myswiper.css (deleted) swiper用追加css
<script src="js/onclick.wrapper.js"></script> // 自前onclickラッパー
<script src="js/ajax.deferred.js"></script> // deferredループ処理ルーチン

<script type='text/javascript'>//<![CDATA[
liveSlide = new Array(); // 追加していくスライドの塊をページとして配列管理。 0なら未処理。 1なら追加済み
compo = document.getElementById("compo"); // 各ページのindexをbodyに埋め込んだdivから取得
compoData = compo.innerHTML.split(" ");

function loadImage( $item ) { // 画像lazyloadルーチン
    var img = new Image();
    img.onload = function() {
        $item
        .prop('src', img.src )
        .removeAttr('data-src')
        .data('src', null)
        .addClass('fadein');
    };
    img.src = $item.data('src');
}

var swiper = new Swiper('.swiper-container', { // swiper 初期化
    updateOnImagesReady : false,
    slidesPerView: 'auto',
    onSlideChangeEnd: function(){
      loadSlideRoutine(); // スライド追加メインルーチン呼び出し
    }
});

loadSlideRoutine = function(){ // メインルーチン
if ( compoData.length <1 ) return;
      var maxPage = 0;
      for ( var i = 0 ; i < 10 ; i++) {
        if ( liveSlide[i] != 1 && swiper.activeIndex > compoData[i]-10 && compoData[i] > 0 ) {
          liveSlide[i] = 1;
          swiper.params.onlyExternal=true // swiperのユーザーによる操作受付禁止
          $('.preloader').addClass('visible'); // ローディング中divを表示化
//          console.log("add slide",i+1,"current index",swiper.activeIndex,"compo",compoData[i]);
          loadNewSlides(i+1); //追加したいpage番号を入れて追加ルーチン呼び出し
        }
      }
}

function loadNewSlides(page) { // スライド追加処理開始
  if ( document.getElementById("page"+page)) {
    var d = document.getElementById("page"+page); // idによりページ情報取得
    var elm = d.getElementsByTagName('div');  // divを抜き取り
    var deferred = async_loop( {
        begin : 0,
        end : elm.length, // divの数だけループ
        inc : 1,
        duration : 0
    } );
    deferred.progress( function( index,deferred ) {
        //console.log( index, 'start' );
        insertSlide (elm[index]) ; // deferredを使ってスライド追加ルーチン呼び出し
        setTimeout( function( ) {
            //console.log( index, 'finish' );
            deferred.resolve( );
        }, 0 );
    } );
    deferred.always( function( ) {
        //console.log( 'finish' );
    } );
    swiper.params.onlyExternal=false;
  }
  swiper.updateActiveSlide(0);
  onloadWrapper(); // 新しくスライドを追加したので自前onloadラッパー再読み込み
  setTimeout( function( ) {
    $('.preloader').removeClass('visible') // ユーザーによる操作受付再開

  }, 600);
}

insertSlide = function(elm) { // スライド追加処理ルーチン
      var target = elm.getAttribute("rel");
      var image = elm.getElementsByTagName('img');
      var img = image[0].outerHTML;
      swiper.appendSlide('<div class=\'swiper-slide mypopup\' rel=\''+target+'\'>'+img+'</div>'); // スライド追加
      $('.swiper-wrapper img').each(function(){
        loadImage( $(this) ); // 画像lazyloadsrc書き換え
      });
}

//]]> 
</script>

<div class="swiper-container"> <!-- swiperスライド本体 -->
  <div class="swiper-wrapper">
    <div class="swiper-slide mypopup" rel="ugallery2_cvt/66-big.jpg" style="width:49px;"><img src="ajax-loader.gif" data-src="ugallery2_cvt/66.jpg"></div>
    <div class="swiper-slide mypopup" rel="ugallery2_cvt/65-big.jpg" style="width:55px;"><img src="ajax-loader.gif" data-src="ugallery2_cvt/65.jpg"></div>
    <!-- 以下続く... -->
.
  </div>
</div>

<div id="page1" style="display:none;"> <!-- 1ページ目情報・自動生成 -->
  <div class="swiper-slide mypopup" rel="ugallery2_cvt/49-big.jpg" style="width:55px;"><img src="ajax-loader.gif" data-src="ugallery2_cvt/49.jpg"></div>
  <div class="swiper-slide mypopup" rel="ugallery2_cvt/48-big.jpg" style="width:54px;"><img src="ajax-loader.gif" data-src="ugallery2_cvt/48.jpg"></div>
. <!-- 以下続く... -->
.
</div>

<div id="page2" style="display:none;"> <!-- 2ページ目情報・自動生成 -->
  <div class="swiper-slide mypopup" rel="ugallery2_cvt/30-big.jpg" style="width:55px;"><img src="ajax-loader.gif" data-src="ugallery2_cvt/30.jpg"></div>
  <div class="swiper-slide mypopup" rel="ugallery2_cvt/29-big.jpg" style="width:54px;"><img src="ajax-loader.gif" data-src="ugallery2_cvt/29.jpg"></div>
. <!-- 以下続く... -->
.
</div>


<div class="preloader"> <!-- ローディング中表示div -->
  <img src="ajax-loader.gif" alt="loading" style="margin:-4px;"> Loading</div>
<div class="swiper-scrollbar"></div>

<div id="compo" style="display:none;">
18 37 50 63 <!-- 各ページのindex。 自動生成。 画像の横幅がまちまちなのでindexを総横幅で決める必要がある -->
</div>


 なが~いが、swiperのonSlideChangeEndとかを使ってloadSlideRoutine();を呼び出せば bodyに埋め込んだページデータを元にスライドを追加してくれる。
 多少回りくどいことをしているのと、データの書式を手抜きで整理しないままコードの方で無理やり対応させたので、追加されるスライドの書式が若干アレになる。
あと、呼び出し方をもうちょっと考えないと、読み込み不具合がまれに起こることがあるかもしれない。

swiper スライド追加


 こんな感じに追加したスライドのdivが入れ子に。 でもちゃんと表示される。 しかしchromeはデバグに便利である。

今から直すのは面倒だし、動いてるのでとりあえずはよしとする。 スライド追加だけじゃなくて削除もしたいとかなると、さらにだいぶ改造しないといけないねぇ……。 まあ、削除しないといけないほどそんなに絵が急激に増えるわけでもないから……今度こそ、完!


コメント欄
(投稿なし)

コメントなどありましたらこちらからどうぞ
名前
内容
 ※名前、内容ともに入力必須です
- C'sGallery Blogっぽく見えるシステム3.2 -
小武 (管理人) eta2@tim.hi-ho.ne.jp