回答編集履歴

1 初期表示時に一瞬すべてのスライドが見えてしまうのを修正

kura

kura score 355

2017/02/19 23:58  投稿

取りあえずこんな感じで動くと思います。
動きの補助としてCSSも追加しましたが、要点となるところはほんの一部です(`/* ! */`で印をしました)。
[サンプル https://jsfiddle.net/ubnxp7b7/1/](https://jsfiddle.net/ubnxp7b7/1/)
[サンプル https://jsfiddle.net/ubnxp7b7/2/](https://jsfiddle.net/ubnxp7b7/2/)
```javascript
/**
* スライドショー処理
*
**/
$(document).ready(function(){
  /**
  * 定数定義
  * スライドショービジネスロジック内で使用する定数
  *
  **/
 interval         = 4000; // スライドを切り替える間隔
 slide_default_num = /*1*/0;   // 画面初期表示時に表示するスライド番号
 slide_star_num   = /*2*/0;   // スライドショー開始番号
 slide_end_num    = 5;   // スライドショー終了番号
 /**
  * 画像の初期化
  *
  **/
 init();
});
/**
* 画像の初期化
*
**/
function init() {
 // すべての画像を非表示
 $('.slide_show_box li').hide();
 // 1番目の画像を表示
 $('.slide_show_box li').eq(slide_default_num).show();
 
 main(); // ← mainを実行するよう追加
}
/**
* メイン処理
*
**/
function main() {
 // 各項目
 $('.slide_show_box li').hide();                  // すべての画像を非表示
 $('.slide_show_box li').eq(slide_star_num).show(); //最初の画像を表示
 // 画像の縦スクロール
 scroll_down();
 // 次の画像を設定
 slide_star_num++;
 // 画像のフェードイン
 setTimeout(slideShow, interval);
}
/**
* 画像の縦スクロール
*
**/
var scroll_y = 0;
function scroll_down() {
 $('.slide_show_box li').eq(slide_star_num).css({top: "200px"}).animate({top: 0}, 1000); /* ! */
}
/**
* 画像のフェードイン
*
**/
function slideShow() {
 // 終了番号を超えた場合
 if (slide_star_num > slide_end_num/* - 1*/) { // ← -1はいらない?
   // スライドショーを終了
   return;
 }
 $('.slide_show_box li').eq(slide_star_num - 1).delay(1500).fadeOut(3000).queue(function() {
   // すべての画像を非表示
   $('.slide_show_box li').hide();
   $('.slide_show_box li').eq(slide_star_num).fadeIn(3000);
   slide_star_num++;
 });
 setTimeout(slideShow, interval);
}
```
```css
#main_contents {
 display: table;
 outline: 3px solid #000;
 overflow: hidden; /* ! */
}
#main_contents ul {
 margin: 0;
 padding: 0;
 list-style-type: none;
}
#main_contents li {
 position: relative; /* ! */
 display: none;  
}
#main_contents img {
 vertical-align: bottom;
}
```
## 要点1 CSS
`#main_contents { overflow: hidden; }` と `#main_contents li { position: relative; }` が重要なポイントになります。
`position: relative;` は、**要素の位置を元の場所から指定した長さだけ移動できる**指定です。[MDN position](https://developer.mozilla.org/ja/docs/Web/CSS/position)
通常はこれを用いると同時に`top: 50px;`(=上から50px移動させる)などを指定して使います。
今回は`top`の指定をJavaScriptの方で行っています。
`overflow: hidden;`は、その**要素からはみ出した子要素を非表示にする**という指定です。[MDN overflow](https://developer.mozilla.org/ja/docs/Web/CSS/overflow)
この指定がない場合、親要素からはみ出した子要素が表示されます。つまり、上の`position: relative;`で`<li>`の位置をずらしても、はみ出た部分まで表示されてしまします。
`overflow: hidden;`を指定することで、div枠内で映画のエンドロールのように下から上へスクロールするように見せることができるのです。
## 要点2 JavaScript
`$('.slide_show_box li').eq(slide_star_num).css({top: "200px"}).animate({top: 0}, 1000);`
まず`.css({top: "200px"})`で画面初期表示時に表示するスライドの初期位置を指定します。この場合、上から200pxの位置にスライドをずらすので、最初はスライドが下に完全に埋まっている状態になります。
(200pxの値は画像の縦の長さに合わせて変更してください。)
次に`.animate({top: 0}, 1000);`とすることで、1秒かけてスライドを枠内に表示することが出来ます。
尚、`setTimeout`を使って`scroll_down`を再帰的に呼び出す必要はありません。`.animate()`を一度実行することで最後までアニメーションを実行してくれるからです。
また、残念ながら`scrollTop`は用途が違います。`scrollTop`は、その要素にスクロールバーがある場合に、そのスクロール位置を変更するためのものです。(ページをスクロールするときによく使います。)

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る