swiper内に動的htmlを置くとコンテンツエリアの高さが0になる
Q&A
Closed
「スワイプでタブ切り替えができるアプリ風メニューを実装する方法」
という記事を参考にswiperを使ってスワイプでタブ切り替えができるメニューを実装しました。
タブ内にAPIから取得した商品リストを動的なHTMLで描画しているのですが、
恐らく読み込み順の問題で、swiperが発火した時点では商品リストが取り込まれないため
コンテンツエリアの高さが0になり、商品リストが隠れてしまいます。
横のタブに移動(スワイプ)し、表示したいタブに戻る動作をすれば
正常にコンテンツ分の高さまでエリアが広がるのですが。。
(すでにコンテンツ取得できている状態からエリアを表示するため)
試しにswiper.min.jsをbodyの最下部に置くと、今度はswiperのjsが動かなくなってしまいます。
どのように記述を変更すれば、どちらも動作するようになりますでしょうか。
■現状困っていること
➀swiper.min.js→API取得の順で記述した場合
→コンテンツエリアの高さが0になり商品リストが表示できない(下部までのスクロールでページを追加するjsも効かなくなる)
➁API取得→swiper.min.jsの順で記述した場合
→コンテンツエリアは商品リストが収まる高さで表示されるが、swiperのjsがすべて動作しない
■実現したいこと
swiperのコンテンツエリアを、取得した商品件数分の高さで表示したい。
タブ内を再下部までスクロールすると次ページの商品が表示される処理を入れているため、
追加表示するたびにコンテンツエリアも広がるようにしたい。
■コード
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="css/reset.css" />
<link rel="stylesheet" href="css/style.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.5.0/css/swiper.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.5.0/js/swiper.min.js"></script>
<script src="js/jquery-2.1.3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<title>Document</title>
</head>
<body>
<div class="container">
<!-- メニュー部分 -->
<div class="swiper-container tab-menu">
<div class="swiper-wrapper">
<div class="swiper-slide">コンテンツ表示</div>
<div class="swiper-slide">タブ2</div>
<div class="swiper-slide">タブ3</div>
<div class="swiper-slide">タブ4</div>
</div>
<!-- コンテンツ部分 -->
<div class="swiper-container tab-contents">
<div class="swiper-wrapper">
<div class="swiper-slide"><div class="cssgrid"></div></div>
<div class="swiper-slide">タブ2</div>
<div class="swiper-slide">タブ3</div>
<div class="swiper-slide">タブ4</div>
</div>
</div>
<script>
// ------------------
// グローバル変数
// ------------------
let APPID = "------------アプリID------------"; //アプリID *必須
let MAX_PAGE = 100; //最大取得ページ件数
let HITS = 30; //1ページ当たりの表示件数
let KEYWORD = encodeURIComponent("カラコン"); //絞り込みしたい単語
// ------------------
// 楽天API
// ------------------
$(function () {
let n = 1;
$(window).bind("scroll", function () {
scrollHeight = $(document).height();
scrollPosition = $(window).height() + $(window).scrollTop();
if ((scrollHeight - scrollPosition) / scrollHeight <= 0.0005) {
//スクロールの位置が下部0.05%の範囲に来た場合
if (n < MAX_PAGE) {
search_rakuten(n+1);
}
}
});
function put_item(item) {
let h = '<div class="item">'
+ '<img src="'
+ item.mediumImageUrls[0].imageUrl.replace("?_ex=128x128","")
+ '" class="img">'
+ '<span><a href="'
+ item.affiliateUrl
+ '" class="url" target="_blank">商品リンク</a></span></div>';
//ループで表示したいHTML部分を作成
$(".cssgrid").append(h);
}
//ajax
function search_rakuten(page) {
$.ajax({
url:
"https://app.rakuten.co.jp/services/api/IchibaItem/Search/20170706?format=json&applicationId=" +
APPID +
"&affiliateId=" +
AFF +
"&shopCode=" +
SHOP +
"&page=" +
page +
"&hits=" +
HITS,
type: "get",
dataType: "json",
timeout: 10000,
async: "true",
})
//読み込み成功時の処理
.done(function (data) {
// 1商品ずつhtml置く
for (let i in data.Items) {
put_item(data.Items[i].Item);
}
})
//読み込み失敗時の処理
.fail(function (data) {
console.log("読み込みエラー");
});
}
search_rakuten(n);
});
// ------------------
// タブスワイプ
// ------------------
//初期化
var galleryThumbs = new Swiper('.tab-menu', {
spaceBetween: 20,
slidesPerView: 'auto',
freeMode: false,
watchSlidesVisibility: true,
watchSlidesProgress: true,
slideActiveClass: 'swiper-slide-active'
});
// タップした時にスライドに合わせてメニューに動きをつける
galleryThumbs.on('tap', function () {
var current = galleryTop.activeIndex;
galleryThumbs.slideTo(current, 500, true);
});
var galleryTop = new Swiper('.tab-contents', {
autoHeight: true,
thumbs: {
swiper: galleryThumbs
}
});
</script>
</body>
</html>
0