質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.34%

rails4でスライドショーの実装しているのですが、スライドが動かない

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 644

avicii

score 40

今rails4でスライドショーを実装しようとしています。しかし、javascriptのprevの部分から問題が発生して、動かない状態になっています。javascriptに詳しい方、どうぞ教えて頂けたら嬉しいです。

イメージ説明
イメージ説明
![イメージ説明](1aaefd953bfee0681437ba55ff9dbad7.png)
イメージ説明

 <!DOCTYPE html>
<html lang="ja">
<html>
  <head>
    <title>Chance to Chance</title>
    <meta name="viewpoint" content="width=devise-width,initial-scale=1.0">
    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous">
    <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
    <%= csrf_meta_tags  %>
    <script type="text/javascript">
      WebFontConfig = {
        google: { families: [ 'Unica+One::latin' ] }
      };
      (function() {
        var wf = document.createElement('script');
        wf.src = ('https:' == document.location.protocol ? 'https' : 'http') +
          '://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
        wf.type = 'text/javascript';
        wf.async = 'true';
        var s = document.getElementsByTagName('script')[0];
        s.parentNode.insertBefore(wf, s);
      })();
    </script>
  </head>
  <div class="main">
    <i class="fas fa-chevron-circle-left" aria-hidden="true" id="prev"></i>
    <img src="<%= @plan.image %>" id="target" style="width: 950px; height: 400px; padding-bottom: 15px; padding-top: 20px; ">
    <i class="fas fa-chevron-circle-right" aria-hidden="true" id="next"></i>
  </div>
  <div class="king">
    <ul class="example">
        <li class="current"><img src="<%= @plan.copy_image %>"></li>
        <li><img src="<%= @plan.copy_image %>"></li>
        <li><img src="<%= @plan.copy_image %>"></li>
        <li><img src="<%= @plan.copy_image %>"></li>
        <li><img src="<%= @plan.copy_image %>"></li>
    </ul>
  </div>
  <script src="javascripts/main.js"></script>
 (function() {
  'use strict';

  var files = [
    '<%= @plans.copy_image %>',
    '<%= @plans.copy_image %>',
    '<%= @plans.copy_image %>',
    '<%= @plans.copy_image %>',
    '<%= @plans.copy_image %>'
  ];

  var currentNum = 0;
  var prev = document.getElementById('prev');
  var next = document.getElementById('next');
  var target = document.getElementById('target');

  prev.addEventListener('click', function() {
    currentNum--;
    if (currentNum < 0) {
      currentNum = files.length - 1;
    }
    target.src = files[currentNum];
  });

  next.addEventListener('click', function() {
    currentNum++;
    if (currentNum > files.length - 1) {
      currentNum = 0;
    }
    target.src = files[currentNum];
  });

})();
 div.david {
  width: 350px;
  height: 20px;
  padding-left: 10px;
  font-size: 13px;
  strong {
    font-size: 20px;
    padding-left: 15px;
  }
}

#prev, #next {
  cursor: pointer;
  font-size: 42px;
  color: #bbb;
  position: absolute;
  top: 90px;
}

.main {
  position: relative;
}

#prev {
  top: 180px;
  left: -60px;
}

#next {
  top: 180px;
  right: -60px;
}


div.king {
  width: 1000px;
  height: 100px;
}

div.example {
  padding: 0;
  margin: 0;
  list-style: none;
}

.example ul {
  padding: 0;
  margin: 0;
  list-style: none;
}

.example li {
  float: left;
  vertical-align: middle;
  width: 185px;
  height: 50px;
  cursor: pointer;
  opacity: 0.6;
}

.example li + li {
  margin-left: 6px;
}

.example li:hover {
  opacity: 1;
}

.example li.current {
  opacity: 1;
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • 退会済みユーザー

    2019/01/15 13:41

    複数のユーザーから「やってほしいことだけを記載した丸投げの質問」という意見がありました
    「質問を編集する」ボタンから編集を行い、調査したこと・試したことを記入していただくと、回答が得られやすくなります。

回答 2

checkベストアンサー

0

ちょっと長くなるので回答に書きます&レスが遅くて申し訳ないです
せっかく現在のサムネイルにclass="current"をつけているのでこんな感じでどうでしょう
nextを押したら次の画像を表示まで書いてみました
https://codepen.io/uzr0401/pen/MZZYVG

var target = document.getElementById('target');
window.addEventListener("load", function(){
  var next = document.getElementById('next');
  // nextクリックで発火
  next.addEventListener('click', function() {
    // class=crrentをcurrentに格納
    var current = document.querySelector('.example .current');
    // currentの次エレメントをnextに格納
    var next = current.nextElementSibling;
    if (!next){ // nextがnullならclass=example内最初のliを取得
      next = document.querySelector('.example li');
    }
    // currentクラスをcrrentからnextに移す
    current.classList.remove('current');
    next.classList.add('current');

    // targetのsrcをnext内のimgのsrcと同じにする
    target.setAttribute('src', next.firstElementChild.getAttribute('src'));
  });
});


ところでライブラリ等を使わずにピュアなJavaScriptで書いているようですが、
使いたくないとか、使ってはいけない環境とかでなければJQueryを使ってみるのはどうでしょうか。
無論ReactやVueなどのフレームワークを使うのもとても良いですが、
学習コストが多少かかるのと、ggって出てくる情報が(現状おそらく)JQueryの方が多いです。
特に特殊な仕様でもないのでJQuery+何かしらのJQueryライブラリで実現できるのではないかなと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/01/15 06:55

    度々回答ありがとうございます。私の返答が分かりづらくて、申し訳ありません。
    右クリックをクリックすると、下の画像が上の画像に表示されるようにしたいと考えてました。
    教えて頂けたら、幸いです。

    キャンセル

0

エラーの原因ですがおそらく,
HTMLが読み込まれる前なのでdocument.getElementById('prev')で取得できず、
null(何も入っていない)のprevにaddEventListener しているのでエラーになっているように見えます。
貼られているJavaScriptのコードをそのまま使いたいのであれば、
bodyの一番下にscriptタグ作って、その中に移植してあげれば動くんじゃないかなと思います。

以下はその方法をとりたくない場合についての話ですが、
外部読み込みのJavaScriptファイル内ではerbの埋め込みは使えないので、
<%= @plans.copy_image %>では画像のパスをとれません。
他の方法を考える必要があります。
例えばスライドの画像が下のサムネイルと同じならそこから取り出すとかですね。

あとHTMLが読み込まれた後にJavaScriptが発火する必要があるので、

document.addEventListener("turbolinks:load", function(){
    // スライドショーのスクリプト
})


みたいな感じで発火タイミングを調整する必要があると思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/01/09 20:37

    大変申し訳ないのですが、「スライドの画像が下のサムネイルと同じなら、そこから取り出す」という部分の下のサムネイルの場所はどこでしょうか?

    キャンセル

  • 2019/01/10 10:39

    下のサムネイルというのはviewの
    ```
    <ul class="example">
    <li class="current"><img src="<%= @plan.copy_image %>"></li>
    <li><img src="<%= @plan.copy_image %>"></li>
    <li><img src="<%= @plan.copy_image %>"></li>
    <li><img src="<%= @plan.copy_image %>"></li>
    <li><img src="<%= @plan.copy_image %>"></li>
    </ul>
    ```
    の部分のことをさしました。
    スクリーンショットでは、`id="target"`のJobsの格言の画像と、その下のリストのうち`class="current"`の画像が違うものみたいなんですが、
    `id="next"`をクリックしたらリストの画像を順々に大きくスライドに表示していくのかなと察したので、リストの画像を取得すればいいのではないかなという意味です。
    勘違いかもしれませんし、わかり辛いですね。。。
    あと、スライドショーの実装として全ての画像をHTMLには書いておいて、それをJavaScriptで表示、非表示切り替えていく方法をよく見ますし、簡単かもしれません。

    キャンセル

  • 2019/01/11 04:50 編集

    そうです!!画像をクリックしたら、スライドが変わるようにしたいと思ってます。
    下のサムネイルを取り出す場合は、どう書くのでしょうか?

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.34%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る