/* * SUMAOU LICENSE * (c) Copyright 2016 Section9 Inc. * * 本ソースコードは全て株式会社9課へと帰属し、 * 無断での複製・変更・再配布を固く禁じます。 * * 規約違反が見つかりました場合はご連絡の上、 * 使用停止とさせて頂きますので何卒ご注意ください。 * * 出来る限り多くの店舗様に低価格で良質なスマホサイトを * ご提供したいと始めたサービスです。 * 恐れ入りますが、ご理解のほど宜しくお願い致します。 *///*************************************************************************** // 設定 //*************************************************************************** var LISTVIEW_ITEMS_HITS = 12; var SEARCH_ITEMS_HITS = 30; var API_URL = 'https://api.sumaou.com/20140815/rakuten.php'; var SUMAOU_ACCOUNT = 'O8EeE3LqR7aNgmfVlu9kkLNNLa8HeHQO'; var API_ACCESS_CODE = 'Hy5OsslWcwcG3GiugFAC98WpoFuwdkw9'; // 次のブロックを読み込むまでのインターバル(ミリ秒)。 // 短くすることで素早く読み込むことができるが API への負荷が増加する。 var INTERVAL_NEXT_BLOCK_ACCESS = 100; // ブロックの読み込みに失敗した場合にリトライを行うインターバル(ミリ秒)。 // 短くすることで素早くリトライすることができるが API への負荷が増加する。 var INTERVAL_RETRY_ERROR_BLOCK = 1000; //*************************************************************************** // 定数宣言 //*************************************************************************** // 各ブロックの要素名 var ELEMENT_NAME = { Search: '#searchitems-wrap', NewUpdate: '#newitems-wrap', Pickup: '#pickup-wrap', Sale: '#saleitems-wrap', Point: '#pointitems-wrap', ReviewCount: '#reviewitems-wrap', PostageFree: '#fshipping-wrap', ReviewAverage: '#reviewavg-wrap', Block1: '#block1-wrap', Block2: '#block2-wrap', Html1: '', Html2: '' }; //*************************************************************************** // 変数宣言 //*************************************************************************** //各種APIを呼び出す順番をまとめた変数 accessOrder のインデックス var accessOrderIndex = 0; //現在表示しているページ番号 var itemsPage = { Search: 1, NewUpdate: 1, Sale: 1, Point: 1, ReviewCount: 1, PostageFree: 1, ReviewAverage: 1, Block1: 1, Block2: 1 }; //取得対象となる商品IDのインデックス var itemCodeIndex = { Pickup: 0, Sale: 0, Block1: 0, Block2: 0 }; //ページ移動中フラグ var pageMoving = { Search: false, NewUpdate: false, Sale: false, Point: false, ReviewCount: false, PostageFree: false, ReviewAverage: false, Block1: false, Block2: false }; //検索ワード var searchWord = ''; //ヘッダー追加フラグ var requestHeaderAndFooter = true; //連続エラー回数 var errorCount = 0; //*************************************************************************** // 読み込み完了時処理 //*************************************************************************** $(function(){ //クリック制御 $(document).on("click", "a[href=#]", function(event) { event.preventDefault(); return false; }); //トップへ戻るリンク制御 $('#backTop a').click(function() { $('body,html').animate({ scrollTop: 0 }, 800); return false; }); //検索ボタン制御 $('#searchform').submit(function(event) { //サブミット キャンセル event.preventDefault(); //検索ワード保持 searchWord = $(':text[name="keyword"]').val(); //検索結果ページ クリア itemsPage['Search'] = 1; //検索開始 moveBlockSearch(); }); //スライドバナー初期化処理 var slide = $('.topBnr .slides .slide'); if (slide.length > 1) { $('.topBnr').glide({ autoplay: 5500, arrowRightText: '', arrowLeftText: '', arrowRightClass:'slider-arrow--right', arrowLeftClass:'slider-arrow--left', navigation: false }); } else slide.css('float', 'none'); }); //*************************************************************************** // 指定された順番に従って各種ブロック処理を実行する。 // 初回起動は HTML 側の「スクリプト制御ブロック」から実行される。 // // [補足] // accessOrder 変数 は HTML 側の「スクリプト制御ブロック」にて // 宣言されている。 //*************************************************************************** function startAccess() { //全ての処理が完了していたら何もしない if (accessOrderIndex >= accessOrder.length) return; //ローディング表示 if (accessOrderIndex == 0) setHtmlLoading(); //各種処理 generateBlock(accessOrder[accessOrderIndex]) .then({}, function(e) { accessOrderIndex++; }) .done(function() { setTimeout(function(){ startAccess(); }, INTERVAL_NEXT_BLOCK_ACCESS); }); } //*************************************************************************** // 指定されたオーダーのブロック処理を実行する。 // // [パラメータ] // name … オーダー名 // // [戻り値] // Promise オブジェクトを返す。 //*************************************************************************** function generateBlock(name) { switch (name) { case 'NewUpdate': return generateBlockNewUpdate(false); case 'Pickup': return generateBlockPickup(); case 'Sale': return generateBlockSale(false); case 'Point': return generateBlockPoint(false); case 'ReviewCount': return generateBlockReviewCount(false); case 'PostageFree': return generateBlockPostageFree(false); case 'ReviewAverage': return generateBlockReviewAverage(false); case 'Block1': return generateBlockBlock(1, false); case 'Block2': return generateBlockBlock(2, false); default: accessOrderIndex++; return $.Deferred().rejected().promise(); } } //*************************************************************************** // 新着・更新アイテム ブロックのページを移動する。 // // [パラメータ] // add … ページ増加数 //*************************************************************************** function moveBlockNewUpdate(add) { //既にページ移動中なら何もしない if (pageMoving['NewUpdate']) return; pageMoving['NewUpdate'] = true; //ローディング表示 $(ELEMENT_NAME['NewUpdate']).html('
'); setHtmlLoading(); //スクロール位置調整 toScroll("#newdate"); //ページ増減 itemsPage['NewUpdate'] += add; //移動開始 generateBlockNewUpdate(true); } //*************************************************************************** // 新着・更新アイテム ブロックの HTML を生成する。 // // [パラメータ] // paging … 「次へ」「前へ」を持つページング形式で表示するかどうか //*************************************************************************** function generateBlockNewUpdate(paging) { //Deferred オブジェクト生成 var deferred = new $.Deferred; //パラメータ生成 var parameter = 'sort=-updateTimestamp&imageFlag=1'; if (paging) parameter += '&hits=' + LISTVIEW_ITEMS_HITS + '&page=' + itemsPage['NewUpdate']; else parameter += '&hits=6'; //API アクセス開始 $.ajax({ type: 'POST', url: API_URL, data: { sumaou_account: SUMAOU_ACCOUNT, api_access_code: API_ACCESS_CODE, parameter: parameter } //アクセス成功 }).done(function(data) { //ローディング非表示 $(ELEMENT_NAME['NewUpdate'] + ' .loading').remove(); //試用期限が来ていたら、メッセージ追加 if (data.error == 'access deny') setHtmlItemError(ELEMENT_NAME['NewUpdate']); //試用期限が来ていなかったら else { //日付表示 var getdate = $.now(); var now = new Date(getdate); var m = now.getMonth() + 1; var d = now.getDate(); var w = now.getDay(); var wNames = ['日', '月', '火', '水', '木', '金', '土']; var nowdate = m + '月' + d + '日 (' + wNames[w] + ')' + 'の最新情報!'; $('#newdate').text(nowdate); //商品表示 generateGoods('NewUpdate', data, paging); //追加された商品数を取得 var count = $(ELEMENT_NAME['NewUpdate']).children('div.newitem').length; //商品が存在しなかったら、メッセージを追加 if (count == 0) setHtmlItemNull(ELEMENT_NAME['NewUpdate']); //商品が存在するか、ページング形式なら、ナビゲーション表示 if ((count > 0) || paging) generateNavigationFromData('NewUpdate', paging, data); } //ページング形式なら、ページ移動中を解除する if (paging) pageMoving['NewUpdate'] = false; //初期表示形式なら、読み込み対象ブロックを進める else accessOrderIndex++; //正常終了 deferred.resolve(); //アクセス失敗 }).fail(function(jqXHR, textStatus, errorThrown) { //試用期限が来ていたら if ((jqXHR.responseJSON.error != null) && (jqXHR.responseJSON.error == 'access deny')) { //メッセージ追加 setHtmlItemError(ELEMENT_NAME['NewUpdate']); //ページング形式なら、ページ移動中を解除する if (paging) pageMoving['NewUpdate'] = false; //初期表示形式なら、読み込み対象ブロックを進める else accessOrderIndex++; //正常終了 deferred.resolve(); //それ以外ならリトライ } else { setTimeout(function() { generateBlockNewUpdate(paging); }, INTERVAL_RETRY_ERROR_BLOCK); } }); //Promise オブジェクトを返す return deferred.promise(); } //*************************************************************************** // 売れ筋ピックアップ ブロックの HTML を生成する。 // // [補足] // pickupKeywords 変数、pickupGoods 変数 は // HTML 側の「スクリプト制御ブロック」にて宣言されている。 //*************************************************************************** function generateBlockPickup() { //Deferred オブジェクト生成 var deferred = new $.Deferred; //処理定義 var access = { //アクセス開始 start: function() { //キーワードが設定されていたら if (pickupKeywords.length > 0) { //キーワードが5つ以上設定されていたら、オーバーしている分を削除 if (pickupKeywords.length > 5) pickupKeywords.splice(5, pickupKeywords.length - 5); //キーワード検索用のパラメータを生成 var parameter = 'keyword=' + encodeURIComponent(pickupKeywords.join(' ')) + '&orFlag=1&sort=-updateTimestamp&hits=20&imageFlag=1'; //キーワードが設定されておらず、商品IDが設定されていたら、商品ID検索用のパラメータ生成を行う } else if (pickupGoods.length > 0) var parameter = 'itemCode=' + encodeURIComponent(pickupGoods[itemCodeIndex['Pickup']]) + '&imageFlag=1'; //キーワードも商品IDも設定されていなかったら、完了処理を行う else { this.success(); return; } //this オブジェクト保持 var parentThis = this; //API アクセス $.ajax({ type: 'POST', url: API_URL, data: { sumaou_account: SUMAOU_ACCOUNT, api_access_code: API_ACCESS_CODE, parameter: parameter } //アクセス成功 }).done(function(data){ //試用期限が来ていたら if (data.error == 'access deny') { //メッセージ追加 setHtmlItemError(ELEMENT_NAME['Pickup']); //読み込み対象ブロックを進める accessOrderIndex++; //正常終了 deferred.resolve(); //試用期限が来ていなかったら } else { //商品表示 generateGoods('Pickup', data, false); //アクセス完了処理 parentThis.success(); } //アクセス失敗 }).fail(function(jqXHR, textStatus, errorThrown) { //試用期限が来ていたら if ((jqXHR.responseJSON.error != null) && (jqXHR.responseJSON.error == 'access deny')) { //メッセージ追加 setHtmlItemError(ELEMENT_NAME['Pickup']); //読み込み対象ブロックを進める accessOrderIndex++; //パラメータエラーなら、商品IDが該当しなかったものと判断して、アクセス完了処理を実行する } else if ((jqXHR.responseJSON.error != null) && (jqXHR.responseJSON.error_description == 'itemCode is not valid')) parentThis.success(); //それ以外のエラーならリトライ else { setTimeout(function(){ generateBlockPickup(); }, INTERVAL_RETRY_ERROR_BLOCK); return; } //正常終了 deferred.resolve(); }); }, //アクセス完了 success: function() { //キーワードが設定されているか、全ての商品IDの読み込みが終わっていたら if ((pickupKeywords.length > 0) || (itemCodeIndex['Pickup'] >= (pickupGoods.length - 1))) { //ローディング非表示 $(ELEMENT_NAME['Pickup'] + ' .loading').remove(); //商品が存在したら if ($('#picitems').children('li').length > 0) { //商品表示 $('#effects').show(); //Sly初期化 $(function($) { 'use strict'; (function(){ var $frame = $('#effects'); var $wrap = $frame.parent(); $frame.sly({ horizontal: 1, itemNav: 'forceCentered', smart: 1, activateMiddle: 1, activateOn: 'click', touchDragging: 1, releaseSwing: 1, startAt: 0, speed: 300, easing: 'swing', cycleBy: 'items', cycleInterval: 2800 }); }()); }); //商品が存在しなかったら、メッセージを追加 } else setHtmlItemNull(ELEMENT_NAME['Pickup']); //読み込み対象ブロックを進める accessOrderIndex++; //商品IDによる検索なら、処理する商品IDを進める } else itemCodeIndex['Pickup']++; //正常終了 deferred.resolve(); } }; //処理開始 access.start(); //Promise オブジェクトを返す return deferred.promise(); } //*************************************************************************** // SALE ブロックのページを移動する。 // // [パラメータ] // add … ページ増加数 // first … 初期ページ移動かどうか // // [補足] // saleKeywords 変数、saleGoods 変数 は // HTML 側の「スクリプト制御ブロック」にて宣言されている。 //*************************************************************************** function moveBlockSale(add, first) { //省略引数デフォルト設定 if (first === undefined) first = true; //初期ページ移動なら if (first) { //既にページ移動中なら何もしない if (pageMoving['Sale']) return; pageMoving['Sale'] = true; //ローディング表示 $(ELEMENT_NAME['Sale']).html(''); setHtmlLoading(); //スクロール位置調整 toScroll(ELEMENT_NAME['Sale']); //ページ増減 itemsPage['Sale'] += add; //キーワードが設定されておらず、商品IDが設定されていたら、参照商品IDを調整 if ((saleKeywords.length == 0) && (saleGoods.length > 0)) itemCodeIndex['Sale'] = (itemsPage['Sale'] - 1) * LISTVIEW_ITEMS_HITS; } //アクセス開始 generateBlockSale(true) .done(function() { //ページ移動中が解除されていなかったら、アクセスを継続する if (pageMoving['Sale']) setTimeout(function(){ moveBlockSale(0, false); }, INTERVAL_NEXT_BLOCK_ACCESS); }); } //*************************************************************************** // SALE ブロックの HTML を生成する。 // // [パラメータ] // paging … 「次へ」「前へ」を持つページング形式で表示するかどうか // // [補足] // saleKeywords 変数、saleGoods 変数 は // HTML 側の「スクリプト制御ブロック」にて宣言されている。 //*************************************************************************** function generateBlockSale(paging) { //Deferred オブジェクト生成 var deferred = new $.Deferred; //処理定義 var access = { //アクセス開始 start: function() { //キーワードが設定されていたら、キーワード検索用のパラメータを生成 if (saleKeywords.length > 0) { var goods = false; var parameter = 'keyword=' + encodeURIComponent(saleKeywords.join(' ')) + '&sort=-updateTimestamp&availability=1&orFlag=1&imageFlag=1'; if (paging) parameter += '&hits=' + LISTVIEW_ITEMS_HITS + '&page=' + itemsPage['Sale']; else parameter += '&hits=6'; //キーワードが設定されておらず、商品IDが設定されていたら、商品ID検索用のパラメータ生成を行う } else if (saleGoods.length > 0) { var goods = true; var parameter = 'itemCode=' + encodeURIComponent(saleGoods[itemCodeIndex['Sale']]) + '&imageFlag=1&hits=1'; //キーワードも商品IDも設定されていなかったら、完了処理を行う } else { this.success(); return; } //this オブジェクト保持 var parentThis = this; //API アクセス $.ajax({ type: 'POST', url: API_URL, data: { sumaou_account: SUMAOU_ACCOUNT, api_access_code: API_ACCESS_CODE, parameter: parameter } //アクセス成功 }).done(function(data){ //試用期限が来ていたら、メッセージ追加 if (data.error == 'access deny') { //メッセージ追加 setHtmlItemError(ELEMENT_NAME['Sale']); //ページング形式なら、ページ移動中を解除する if (paging) pageMoving['Sale'] = false; //初期表示形式なら、読み込み対象ブロックを進める else accessOrderIndex++; //正常終了 deferred.resolve(); //試用期限が来ていなかったら } else { //キーワードによる検索か、商品IDによる検索かつ初期表示形式か、商品IDによる検索かつページング形式でヒット数が範囲なら、商品表示 if ((goods == false) || (goods && (paging == false)) || (goods && paging && (itemCodeIndex['Sale'] < (itemsPage['Sale'] * LISTVIEW_ITEMS_HITS)))) generateGoods('Sale', data, paging, $(ELEMENT_NAME['Sale']).children('div.item').length); //アクセス完了処理 parentThis.success(goods, data); } //アクセス失敗 }).fail(function(jqXHR, textStatus, errorThrown) { //試用期限が来ていたら if ((jqXHR.responseJSON.error != null) && (jqXHR.responseJSON.error == 'access deny')) { //メッセージ追加 setHtmlItemError(ELEMENT_NAME['Sale']); //ページング形式なら、ページ移動中を解除する if (paging) pageMoving['Sale'] = false; //初期表示形式なら、読み込み対象ブロックを進める else accessOrderIndex++; //パラメータエラーなら、商品IDが該当しなかったものと判断して、アクセス完了処理を実行する } else if ((jqXHR.responseJSON.error != null) && (jqXHR.responseJSON.error_description == 'itemCode is not valid')) parentThis.success(true); //それ以外のエラーならリトライ else { setTimeout(function(){ generateBlockSale(paging); }, INTERVAL_RETRY_ERROR_BLOCK); return; } //正常終了 deferred.resolve(); }); }, //アクセス完了 // goods … 商品IDによる検索かどうか。キーワードによる検索の場合は false を指定する。 // data … ヒットしたデータ。 success: function(goods, data) { //省略引数デフォルト設定 if (goods === undefined) goods = false; if (data === undefined) data = null; //商品IDによる検索なら if (goods) { //データが存在しないか、ヒット数が 0 だったら、該当商品IDを削除する if ((data == null) || (data.count == 0)) saleGoods.splice(itemCodeIndex['Sale'], 1); //ヒット数が 1 以上なら、商品IDのインデックスを進める else itemCodeIndex['Sale'] += data.count; //全ての商品IDの検索が終わっているか、ページング形式かつ現在のページを越えて商品が存在するか、初期表示形式で初期表示件数分の検索が完了したら、 //読み込み対象ブロックを進める if ((itemCodeIndex['Sale'] >= saleGoods.length) || (paging && (itemCodeIndex['Sale'] >= (itemsPage['Sale'] * LISTVIEW_ITEMS_HITS + 1))) || ((paging == false) && (itemCodeIndex['Sale'] >= 6))) this.nextOrder(goods, data); //キーワードによる検索なら、読み込み対象ブロックを進める } else this.nextOrder(goods, data); //正常終了 deferred.resolve(); }, //読み込み対象ブロックを進める。 //ローディングを非表示にし、商品が存在しなかった場合はメッセージを追加する。 //また、必要に応じてナビゲーションを追加する。 // goods … 商品IDによる検索かどうか。キーワードによる検索の場合は false を指定する。 // data … ヒットしたデータ。 nextOrder: function(goods, data) { //ローディング非表示 $(ELEMENT_NAME['Sale'] + ' .loading').remove(); //追加された商品数を取得 var count = $(ELEMENT_NAME['Sale']).children('div.item').length; //商品が存在しなかったら、メッセージを追加 if (count == 0) setHtmlItemNull(ELEMENT_NAME['Sale']); //商品が存在するか、ページング形式なら、商品ナビゲーション追加 if ((count > 0) || paging) if (goods) { var prev = (itemsPage['Sale'] > 1); var next = (itemCodeIndex['Sale'] >= (itemsPage['Sale'] * LISTVIEW_ITEMS_HITS + 1)); generateNavigation('Sale', paging, prev, next); } else if (data != null) generateNavigationFromData('Sale', paging, data); //ページング形式なら、ページ移動中を解除する if (paging) pageMoving['Sale'] = false; //初期表示形式なら、読み込み対象ブロックを進める else accessOrderIndex++; } }; //処理開始 access.start(); //Promise オブジェクトを返す return deferred.promise(); } //*************************************************************************** // ポイント ブロックのページを移動する。 // // [パラメータ] // add … ページ増加数 //*************************************************************************** function moveBlockPoint(add) { //既にページ移動中なら何もしない if (pageMoving['Point']) return; pageMoving['Point'] = true; //ローディング表示 $(ELEMENT_NAME['Point']).html(''); setHtmlLoading(); //スクロール位置調整 toScroll(ELEMENT_NAME['Point']); //ページ増減 itemsPage['Point'] += add; //移動開始 generateBlockPoint(true); } //*************************************************************************** // ポイント ブロックの HTML を生成する。 // // [パラメータ] // paging … 「次へ」「前へ」を持つページング形式で表示するかどうか //*************************************************************************** function generateBlockPoint(paging) { //Deferred オブジェクト生成 var deferred = new $.Deferred; //パラメータ生成 var parameter = 'pointRateFlag=1&imageFlag=1'; if (paging) parameter += '&hits=' + LISTVIEW_ITEMS_HITS + '&page=' + itemsPage['Point']; else parameter += '&hits=6'; //API アクセス開始 $.ajax({ type: 'POST', url: API_URL, data: { sumaou_account: SUMAOU_ACCOUNT, api_access_code: API_ACCESS_CODE, parameter: parameter } //アクセス成功 }).done(function(data) { //ローディング非表示 $(ELEMENT_NAME['Point'] + ' .loading').remove(); //試用期限が来ていたら、メッセージ追加 if (data.error == 'access deny') setHtmlItemError(ELEMENT_NAME['Point']); //試用期限が来ていなかったら else { //商品表示 generateGoods('Point', data, paging); //追加された商品数を取得 var count = data.count; //商品が存在しなかったら、メッセージを追加 if (count == 0) setHtmlItemNull(ELEMENT_NAME['Point']); //商品が存在するか、ページング形式なら、ナビゲーション表示 if ((count > 0) || paging) generateNavigationFromData('Point', paging, data); } //ページング形式なら、ページ移動中を解除する if (paging) pageMoving['Point'] = false; //初期表示形式なら、読み込み対象ブロックを進める else accessOrderIndex++; //正常終了 deferred.resolve(); //アクセス失敗 }).fail(function(jqXHR, textStatus, errorThrown) { //試用期限が来ていたら if ((jqXHR.responseJSON.error != null) && (jqXHR.responseJSON.error == 'access deny')) { //メッセージ追加 setHtmlItemError(ELEMENT_NAME['Point']); //ページング形式なら、ページ移動中を解除する if (paging) pageMoving['Point'] = false; //初期表示形式なら、読み込み対象ブロックを進める else accessOrderIndex++; //正常終了 deferred.resolve(); //それ以外ならリトライ } else { setTimeout(function() { generateBlockPoint(paging); }, INTERVAL_RETRY_ERROR_BLOCK); } }); //Promise オブジェクトを返す return deferred.promise(); } //*************************************************************************** // レビュー件数順ブロックのページを移動する。 // // [パラメータ] // add … ページ増加数 //*************************************************************************** function moveBlockReviewCount(add) { //既にページ移動中なら何もしない if (pageMoving['ReviewCount']) return; pageMoving['ReviewCount'] = true; //ローディング表示 $(ELEMENT_NAME['ReviewCount']).html(''); setHtmlLoading(); //スクロール位置調整 toScroll(ELEMENT_NAME['ReviewCount']); //ページ増減 itemsPage['ReviewCount'] += add; //移動開始 generateBlockReviewCount(true); } //*************************************************************************** // レビュー件数順ブロックの HTML を生成する。 // // [パラメータ] // paging … 「次へ」「前へ」を持つページング形式で表示するかどうか //*************************************************************************** function generateBlockReviewCount(paging) { //Deferred オブジェクト生成 var deferred = new $.Deferred; //パラメータ生成 var parameter = 'sort=' + encodeURIComponent('-reviewCount') + '&availability=1&imageFlag=1'; if (paging) parameter += '&hits=' + LISTVIEW_ITEMS_HITS + '&page=' + itemsPage['ReviewCount']; else parameter += '&hits=3'; //API アクセス開始 $.ajax({ type: 'POST', url: API_URL, data: { sumaou_account: SUMAOU_ACCOUNT, api_access_code: API_ACCESS_CODE, parameter: parameter } //アクセス成功 }).done(function(data) { //ローディング非表示 $(ELEMENT_NAME['ReviewCount'] + ' .loading').remove(); //試用期限が来ていたら、メッセージ追加 if (data.error == 'access deny') setHtmlItemError(ELEMENT_NAME['ReviewCount']); //試用期限が来ていなかったら else { //商品表示 generateGoods('ReviewCount', data, paging); //追加された商品数を取得 var count = data.count; //商品が存在しなかったら、メッセージを追加 if (count == 0) setHtmlItemNull(ELEMENT_NAME['ReviewCount']); //商品が存在するか、ページング形式なら、ナビゲーション表示 if ((count > 0) || paging) generateNavigationFromData('ReviewCount', paging, data); } //ページング形式なら、ページ移動中を解除する if (paging) pageMoving['ReviewCount'] = false; //初期表示形式なら、読み込み対象ブロックを進める else accessOrderIndex++; //正常終了 deferred.resolve(); //アクセス失敗 }).fail(function(jqXHR, textStatus, errorThrown) { //試用期限が来ていたら if ((jqXHR.responseJSON.error != null) && (jqXHR.responseJSON.error == 'access deny')) { //メッセージ追加 setHtmlItemError(ELEMENT_NAME['ReviewCount']); //ページング形式なら、ページ移動中を解除する if (paging) pageMoving['ReviewCount'] = false; //初期表示形式なら、読み込み対象ブロックを進める else accessOrderIndex++; //正常終了 deferred.resolve(); //それ以外ならリトライ } else { setTimeout(function(){ generateBlockReviewCount(paging); }, INTERVAL_RETRY_ERROR_BLOCK); } }); //Promise オブジェクトを返す return deferred.promise(); } //*************************************************************************** // 送料無料ブロックのページを移動する。 // // [パラメータ] // add … ページ増加数 //*************************************************************************** function moveBlockPostageFree(add) { //既にページ移動中なら何もしない if (pageMoving['PostageFree']) return; pageMoving['PostageFree'] = true; //ローディング表示 $(ELEMENT_NAME['PostageFree']).html(''); setHtmlLoading(); //スクロール位置調整 toScroll(ELEMENT_NAME['PostageFree']); //ページ増減 itemsPage['PostageFree'] += add; //移動開始 generateBlockPostageFree(true); } //*************************************************************************** // 送料無料ブロックの HTML を生成する。 // // [パラメータ] // paging … 「次へ」「前へ」を持つページング形式で表示するかどうか //*************************************************************************** function generateBlockPostageFree(paging) { //Deferred オブジェクト生成 var deferred = new $.Deferred; //パラメータ生成 var parameter = 'postageFlag=1&sort=' + encodeURIComponent('+itemPrice') + '&availability=1&imageFlag=1'; if (paging) parameter += '&hits=' + LISTVIEW_ITEMS_HITS + '&page=' + itemsPage['PostageFree']; else parameter += '&hits=6'; //API アクセス開始 $.ajax({ type: 'POST', url: API_URL, data: { sumaou_account: SUMAOU_ACCOUNT, api_access_code: API_ACCESS_CODE, parameter: parameter } //アクセス成功 }).done(function(data) { //ローディング非表示 $(ELEMENT_NAME['PostageFree'] + ' .loading').remove(); //試用期限が来ていたら、メッセージ追加 if (data.error == 'access deny') setHtmlItemError(ELEMENT_NAME['PostageFree']); //試用期限が来ていなかったら else { //商品表示 generateGoods('PostageFree', data, paging); //追加された商品数を取得 var count = data.count; //商品が存在しなかったら、メッセージを追加 if (count == 0) setHtmlItemNull(ELEMENT_NAME['PostageFree']); //商品が存在するか、ページング形式なら、ナビゲーション表示 if ((count > 0) || paging) generateNavigationFromData('PostageFree', paging, data); } //ページング形式なら、ページ移動中を解除する if (paging) pageMoving['PostageFree'] = false; //初期表示形式なら、読み込み対象ブロックを進める else accessOrderIndex++; //正常終了 deferred.resolve(); //アクセス失敗 }).fail(function(jqXHR, textStatus, errorThrown) { //試用期限が来ていたら if ((jqXHR.responseJSON.error != null) && (jqXHR.responseJSON.error == 'access deny')) { //メッセージ追加 setHtmlItemError(ELEMENT_NAME['PostageFree']); //ページング形式なら、ページ移動中を解除する if (paging) pageMoving['PostageFree'] = false; //初期表示形式なら、読み込み対象ブロックを進める else accessOrderIndex++; //正常終了 deferred.resolve(); //それ以外ならリトライ } else { setTimeout(function(){ generateBlockPostageFree(paging); }, INTERVAL_RETRY_ERROR_BLOCK); } }); //Promise オブジェクトを返す return deferred.promise(); } //*************************************************************************** // レビュー平均点順ブロックのページを移動する。 // // [パラメータ] // add … ページ増加数 //*************************************************************************** function moveBlockReviewAverage(add) { //既にページ移動中なら何もしない if (pageMoving['ReviewAverage']) return; pageMoving['ReviewAverage'] = true; //ローディング表示 $(ELEMENT_NAME['ReviewAverage']).html(''); setHtmlLoading(); //スクロール位置調整 toScroll(ELEMENT_NAME['ReviewAverage']); //ページ増減 itemsPage['ReviewAverage'] += add; //移動開始 generateBlockReviewAverage(true); } //*************************************************************************** // レビュー平均点順ブロックの HTML を生成する。 // // [パラメータ] // paging … 「次へ」「前へ」を持つページング形式で表示するかどうか //*************************************************************************** function generateBlockReviewAverage(paging) { //Deferred オブジェクト生成 var deferred = new $.Deferred; //パラメータ生成 var parameter = 'sort=' + encodeURIComponent('-reviewAverage') + '&availability=1&imageFlag=1'; if (paging) parameter += '&hits=' + LISTVIEW_ITEMS_HITS + '&page=' + itemsPage['ReviewAverage']; else parameter += '&hits=9'; //API アクセス開始 $.ajax({ type: 'POST', url: API_URL, data: { sumaou_account: SUMAOU_ACCOUNT, api_access_code: API_ACCESS_CODE, parameter: parameter } //アクセス成功 }).done(function(data) { //ローディング非表示 $(ELEMENT_NAME['ReviewAverage'] + ' .loading').remove(); //試用期限が来ていたら、メッセージ追加 if (data.error == 'access deny') setHtmlItemError(ELEMENT_NAME['ReviewAverage']); //試用期限が来ていなかったら else { //商品表示 generateGoods('ReviewAverage', data, paging); //追加された商品数を取得 var count = data.count; //商品が存在しなかったら、メッセージを追加 if (count == 0) setHtmlItemNull(ELEMENT_NAME['ReviewAverage']); //商品が存在するか、ページング形式なら、ナビゲーション表示 if ((count > 0) || paging) generateNavigationFromData('ReviewAverage', paging, data); } //ページング形式なら、ページ移動中を解除する if (paging) pageMoving['ReviewAverage'] = false; //初期表示形式なら、読み込み対象ブロックを進める else accessOrderIndex++; //正常終了 deferred.resolve(); //アクセス失敗 }).fail(function(jqXHR, textStatus, errorThrown) { //試用期限が来ていたら if ((jqXHR.responseJSON.error != null) && (jqXHR.responseJSON.error == 'access deny')) { //メッセージ追加 setHtmlItemError(ELEMENT_NAME['ReviewAverage']); //ページング形式なら、ページ移動中を解除する if (paging) pageMoving['ReviewAverage'] = false; //初期表示形式なら、読み込み対象ブロックを進める else accessOrderIndex++; //正常終了 deferred.resolve(); //それ以外ならリトライ } else { setTimeout(function(){ generateBlockReviewAverage(paging); }, INTERVAL_RETRY_ERROR_BLOCK); } }); //Promise オブジェクトを返す return deferred.promise(); } //*************************************************************************** // 追加ブロックのページを移動する。 // // [パラメータ] // no … 追加ブロックの番号(1 か 2) // add … ページ増加数 // first … 初期ページ移動かどうか // // [補足] // blockKeywords 変数、blockGoods 変数 は // HTML 側の「スクリプト制御ブロック」にて宣言されている。 //*************************************************************************** function moveBlockBlock(no, add, first) { //省略引数デフォルト設定 if (first === undefined) first = true; //初期ページ移動なら if (first) { //既にページ移動中なら何もしない if (pageMoving['Block' + no]) return; pageMoving['Block' + no] = true; //ローディング表示 $(ELEMENT_NAME['Block' + no]).html(''); setHtmlLoading(); //スクロール位置調整 toScroll(ELEMENT_NAME['Block' + no]); //ページ増減 itemsPage['Block' + no] += add; //キーワードが設定されておらず、商品IDが設定されていたら、参照商品IDを調整 if ((blockKeywords[no].length == 0) && (blockGoods[no].length > 0)) itemCodeIndex['Block' + no] = (itemsPage['Block' + no] - 1) * LISTVIEW_ITEMS_HITS; } //アクセス開始 generateBlockBlock(no, true) .done(function() { //ページ移動中が解除されていなかったら、アクセスを継続する if (pageMoving['Block' + no]) setTimeout(function(){ moveBlockBlock(no, 0, false); }, INTERVAL_NEXT_BLOCK_ACCESS); }); } //*************************************************************************** // 追加ブロックの HTML を生成する。 // // [パラメータ] // no … 追加ブロックの番号(1 か 2) // paging … 「次へ」「前へ」を持つページング形式で表示するかどうか // // [補足] // blockKeywords 変数、blockGoods 変数 は // HTML 側の「スクリプト制御ブロック」にて宣言されている。 //*************************************************************************** function generateBlockBlock(no, paging) { //Deferred オブジェクト生成 var deferred = new $.Deferred; //処理定義 var access = { //アクセス開始 start: function() { //キーワードが設定されていたら、キーワード検索用のパラメータを生成 if (blockKeywords[no].length > 0) { var goods = false; var parameter = 'keyword=' + encodeURIComponent(blockKeywords[no].join(' ')) + '&sort=-updateTimestamp&availability=1&orFlag=1&imageFlag=1'; if (paging) parameter += '&hits=' + LISTVIEW_ITEMS_HITS + '&page=' + itemsPage['Block' + no]; else parameter += '&hits=6'; //キーワードが設定されておらず、商品IDが設定されていたら、商品ID検索用のパラメータ生成を行う } else if (blockGoods[no].length > 0) { var goods = true; var parameter = 'itemCode=' + encodeURIComponent(blockGoods[no][itemCodeIndex['Block' + no]]) + '&imageFlag=1&hits=1'; //キーワードも商品IDも設定されていなかったら、完了処理を行う } else { this.success(); return; } //this オブジェクト保持 var parentThis = this; //API アクセス $.ajax({ type: 'POST', url: API_URL, data: { sumaou_account: SUMAOU_ACCOUNT, api_access_code: API_ACCESS_CODE, parameter: parameter } //アクセス成功 }).done(function(data){ //試用期限が来ていたら、メッセージ追加 if (data.error == 'access deny') { //メッセージ追加 setHtmlItemError(ELEMENT_NAME['Block' + no]); //ページング形式なら、ページ移動中を解除する if (paging) pageMoving['Block' + no] = false; //初期表示形式なら、読み込み対象ブロックを進める else accessOrderIndex++; //正常終了 deferred.resolve(); //試用期限が来ていなかったら } else { //キーワードによる検索か、商品IDによる検索かつ初期表示形式か、商品IDによる検索かつページング形式でヒット数が範囲なら、商品表示 if ((goods == false) || (goods && (paging == false)) || (goods && paging && (itemCodeIndex['Block' + no] < (itemsPage['Block' + no] * LISTVIEW_ITEMS_HITS)))) generateGoods('Block' + no, data, paging, $(ELEMENT_NAME['Block' + no]).children('div.item').length); //アクセス完了処理 parentThis.success(goods, data); } //アクセス失敗 }).fail(function(jqXHR, textStatus, errorThrown) { //試用期限が来ていたら if ((jqXHR.responseJSON.error != null) && (jqXHR.responseJSON.error == 'access deny')) { //メッセージ追加 setHtmlItemError(ELEMENT_NAME['Block' + no]); //ページング形式なら、ページ移動中を解除する if (paging) pageMoving['Block' + no] = false; //初期表示形式なら、読み込み対象ブロックを進める else accessOrderIndex++; //パラメータエラーなら、商品IDが該当しなかったものと判断して、アクセス完了処理を実行する } else if ((jqXHR.responseJSON.error != null) && (jqXHR.responseJSON.error_description == 'itemCode is not valid')) parentThis.success(true); //それ以外のエラーならリトライ else { setTimeout(function(){ generateBlockBlock(no, paging); }, INTERVAL_RETRY_ERROR_BLOCK); return; } //正常終了 deferred.resolve(); }); }, //アクセス完了 // goods … 商品IDによる検索かどうか。キーワードによる検索の場合は false を指定する。 // data … ヒットしたデータ。 success: function(goods, data) { //省略引数デフォルト設定 if (goods === undefined) goods = false; if (data === undefined) data = null; //商品IDによる検索なら if (goods) { //データが存在しないか、ヒット数が 0 だったら、該当商品IDを削除する if ((data == null) || (data.count == 0)) blockGoods[no].splice(itemCodeIndex['Block' + no], 1); //ヒット数が 1 以上なら、商品IDのインデックスを進める else itemCodeIndex['Block' + no] += data.count; //全ての商品IDの検索が終わっているか、ページング形式かつ現在のページを越えて商品が存在するか、初期表示形式で初期表示件数分の検索が完了したら、 //読み込み対象ブロックを進める if ((itemCodeIndex['Block' + no] >= blockGoods[no].length) || (paging && (itemCodeIndex['Block' + no] >= (itemsPage['Block' + no] * LISTVIEW_ITEMS_HITS + 1))) || ((paging == false) && (itemCodeIndex['Block' + no] >= 6))) this.nextOrder(goods, data); //キーワードによる検索なら、読み込み対象ブロックを進める } else this.nextOrder(goods, data); //正常終了 deferred.resolve(); }, //読み込み対象ブロックを進める。 //ローディングを非表示にし、商品が存在しなかった場合はメッセージを追加する。 //また、必要に応じてナビゲーションを追加する。 // goods … 商品IDによる検索かどうか。キーワードによる検索の場合は false を指定する。 // data … ヒットしたデータ。 nextOrder: function(goods, data) { //ローディング非表示 $(ELEMENT_NAME['Block' + no] + ' .loading').remove(); //追加された商品数を取得 var count = $(ELEMENT_NAME['Block' + no]).children('div.item').length; //商品が存在しなかったら、メッセージを追加 if (count == 0) setHtmlItemNull(ELEMENT_NAME['Block' + no]); //商品が存在するか、ページング形式なら、商品ナビゲーション追加 if ((count > 0) || paging) if (goods) { var prev = (itemsPage['Block' + no] > 1); var next = (itemCodeIndex['Block' + no] >= (itemsPage['Block' + no] * LISTVIEW_ITEMS_HITS + 1)); generateNavigation('Block' + no, paging, prev, next); } else if (data != null) generateNavigationFromData('Block' + no, paging, data); //ページング形式なら、ページ移動中を解除する if (paging) pageMoving['Block' + no] = false; //初期表示形式なら、読み込み対象ブロックを進める else accessOrderIndex++; } }; //処理開始 access.start(); //Promise オブジェクトを返す return deferred.promise(); } //*************************************************************************** // 検索結果ブロックのページを移動する。 // // [パラメータ] // add … ページ増加数 //*************************************************************************** function moveBlockSearch(add) { //省略引数デフォルト設定 if (add === undefined) add = 0; //既にページ移動中なら何もしない if (pageMoving['Search']) return; pageMoving['Search'] = true; //ヘッダー設定 $('#searchttl').html('