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

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

ただいまの
回答率

87.78%

javascriptのfunction実行優先度(画像拡大機能)

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 3,898

score 52

こんにちは。
javascript初心者です。
運営中のサイトで要望があり、機能を追加することになりましたが、
動作が安定しないため、質問させていただきます。

現在運営しているECサイトの商品画像を、
マウスオーバーで拡大したいとの要望です。

現在の状態は、
メインの画像と、サムネイル(サブの画像)×n枚
という感じになっていて、
サムネイルにマウスオーバーすると、
メイン画像のゾーンの画像が切り替わるという状態になっています。

まずはサムネイルをマウスオーバーで切り替えるところを、
クリックで切り替え、
メイン画像にマウスオーバーで拡大機能を追加するというやり方にしようと思いました。

拡大するためのjsは、
SergeLand Image Zoomer
を使うことにいたしました。

書いたものがこちらです。

<script src="http://◯◯◯.jp/js/zoomsl-3.0.min.js" type="text/javascript"></script>
<div class="detail_wrapper_left">
<div id="product_img">
<img id="product_large_image" class="large" src="@(imageUrl)?@ViewBag.RCC" data-image-source="@imageUrl" alt="" data-large="@(imageUrl)?@ViewBag.RCC" title=""/>
</div>
<div>
@if(descriptionImages.Count() > 0) {
foreach(var descImage in descriptionImages) {
string imgPath = string.IsNullOrEmpty(descImage.FilePath)?
  "product/item/images/"+ descImage.ProductId +"/Description/"+ descImage.ViewOrder: descImage.FilePath;
imgPath = GenLinkUri(imgPath, "~/");
<img class="thmbnail" src="@(imgPath)?@ViewBag.RCC" alt="" />
}}
</div>

<script type="text/javascript" defer>
$(function(){ 
$('.thmbnail').bind("click",
function(){
$("#product_large_image").attr('src', $(this).attr('src'));
$("#product_large_image").imagezoomsl({
zoomrange: [1, 10]
});
},
function(){
$("#product_large_image").attr('src', $("#product_large_image").attr('data-image-source')); 
}
); 
});
</script>


こちらのサイトは、商品画像を商品のIDから引用しているため、
通常であれば◯◯.jpeg等で画像を指定できるところを、
パスが固定ではないため、上記のような書き方になりました。
(おそらく間違っている部分も多いかと思いますが。)

上記の書き方の問題点としては、
・画像が切り替わらない
・ズーム機能は動作するが、サムネイルを切り替えてもズームウインドウ内に表示されない

です。
もしかしたらjavascriptの実行に優先度等があり、
順序がおかしく動作しないのかと予想しております...


詳しい方いらっしゃいましたら力お貸しいただけると幸いです。
どうぞよろしくお願いいたします。


追記

サムネイルも、大きな画像も、同じ画像を使っています。
@(imgPath)?@ViewBag.RCC というのが画像のパスで、
800x800の画像をサムネイルでは縮小表示、
メイン画像でも少しだけ縮小して表示しているものを
スコープ内では800x800のまま表示したいと思っています。

スコープ内の画像は@(imgPath)?@ViewBag.RCCを
そのまま入れれば800x800で表示されることはわかっています。

追記2
js部分を
<script type="text/javascript" defer>
$(function(){  
      $('.thmbnail').bind(
        "click",
        function(){
          $("#product_large_image").attr('src', $(this).attr('src')); 
          $("#product_large_image").imagezoomsl({ zoomrange: [1, 10] }); 
        }
      );  
    }); 
</script>
に書き換えることで、サムネイルをクリックして
メイン画像が変わるようになりました。
ズーム機能も動作しておりますが、
1枚目メイン画像のみしかズームされません。
画像切り替え後マウスオーバーしても、
1枚目のメイン画像がズームされてしまいます。
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • orange0190

    2015/07/21 11:06

    載せているコードはそのままコピーしたものですか?
    "click"のあとに「,」がないため、エラーになると思いますが・・・

    キャンセル

回答 2

checkベストアンサー

0

質問欄に書かれたスクリプト部分をインデントをつけて書き出してみました。
<script type="text/javascript" defer> 
  $(function(){  
    $('.thmbnail').bind(
      "click,"
      function(){
        $("#product_large_image").attr('src', $(this).attr('src')); 
        $("#product_large_image").imagezoomsl({ zoomrange: [1, 10] }); 
      }, 
      function(){
        $("#product_large_image").attr('src', $("#product_large_image").attr('data-image-source'));  
      }
    );  
  }); 
</script> 
変な部分ですが
1. "click,"
 "click", にしないとシンタックスエラーが出るように思います。
 ズームは動いたとありますが、質問作成時のコード記述ミスでしょうか?

2. bind(type,fnc(),fnc())
 bindのシンタックスはbind(type, [data], fn)こうですが、コードではbind(type,関数,関数)です。
 クリック時には後半の関数のみが動いているようです。
 fncを1つにまとめてbind("click",fnc());とすれば期待通り動作するかも知れません。

3. data-largeやproduct_large_imageは変更されていない。
 変更しないとこの部分には古い画像のコードが残りそうですが大丈夫ですか?
 ※@関数ってIE専用でしたっけ?あまり詳しくないので

確認用のコードを追記します。
<html>
<head>
  <script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
  <script src="http://zoomsl.sergeland.ru/js/zoomsl-3.0.min.js"></script>
</head>

<body>
  <div class="detail_wrapper_left"> 
    <div id="product_img"> 
      <img id="product_large_image" class="large" src="l.png" data-image-source="l.png" alt="" data-large="l.png" title=""/> 
    </div>
  <div>
    <img class="thmbnail" src="s.png" alt="" /> 
  </div> 

  <script type="text/javascript" defer> 
    $(function(){  
      $('.thmbnail').bind(
        "click",
        function(){
          $("#product_large_image").attr('src', $(this).attr('src')); 
          $("#product_large_image").imagezoomsl({ zoomrange: [1, 10] }); 
        }
      );  
    }); 
  </script> 
</body>

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2015/07/22 15:19 編集

    こうです。
    が、何をどういう構造で実装しようとしているか理解して反映しないと、自分でメンテナンスできませんし、後々苦しむことになるかも知れませんよ。
    私の方では要求仕様を完全に理解しているわけでもありませんし、質問に回答を付けているだけなので全体として正しい方向を向いているかも分かりません。
    下手すると違うゴールに向かって進んでいるかもしれませんので……注意してくださいね
    <script type="text/javascript">
    //HTMLを全て読み込み終わった時に1回だけ実行
    $(document).ready(){
    $("#product_large_image").imagezoomsl({ zoomrange: [1, 10] });
    }
    //クリックイベントをトリガーにメインの画像を差し替えるメソッドを追加
    $(function(){
    $('.thmbnail').bind(
    "click",
    function(){
    $("#product_large_image").attr('src', $(this).attr('src'));
    $("#product_large_image").attr('data-large', $(this).attr('src'));
    });
    });
    </script>

    キャンセル

  • 2015/07/22 15:39

    そうですね、自分で学習しつつ進める部分だとは思っているのですが...
    入社してまだ間もないグラフィックデザイナーなのですが...突然上司に頼まれてしまったもので時間もなく頼らせてもらってしまっています。

    こちらの記述だと読み込み直後にズーム機能を実行するよう指定しているのかと思うのですが、サムネイルの切り替えも、ズームの機能も動作しなくなってしまいます。

    質問のところで提示しているURLの飛び先の設置方法も参考にし、
    下記のような記述にしてみたところ無事動作いたしました。

    <script type="text/javascript" defer>
    jQuery(function(){
    $("#product_large_image").imagezoomsl({ zoomrange: [1, 10] });
    $('.thmbnail').bind(
    "click",
    function(){
    $("#product_large_image").attr('src', $(this).attr('src'));
    $("#product_large_image").attr('data-large', $(this).attr('src'));
    }
    );
    });
    </script>

    数々の回答ありがとうございました。
    今回この問題を解決したことにより、多少時間ができますので、
    もっとJavascriptの基礎から勉強していきたいと思います。

    ありがとうございます。

    キャンセル

  • 2015/07/22 15:48 編集

    あら、添付したコードは駄目でしたか、すみません。
    最終的に動作するコードが出きたようでよかったです。

    そういう事情でしたら目の前の課題を解決するのが優先ですし、ある程度仕方ないですね。大変でしょうががんばってください。

    キャンセル

0

クリックするたびにメイン画像のsrcを入れ替えて、拡大機能を設定しようとされているようですが、
あらかじめメインの画像もHTML上に全て書いて、それに拡大機能を設定しておいて、
サムネイルをクリックしたときに表示するメイン画像を切り替えるだけにするほうがシンプルで分かりやすいと思います。
以下サンプルです。参考にどうぞ。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://zoomsl.sergeland.ru/js/zoomsl-3.0.min.js"></script>
<script>
$(function(){
    //要素の取得
    var $large = $(".large");
    var $thmbnail = $(".thmbnail");
    
    //全てのメイン画像にimagezoomslを実行し最初の画像以外を非表示にする
    $large.imagezoomsl({
        zoomrange: [1, 10]
    }).hide().eq(0).show();
    
    $thmbnail.bind("click",
        function(e){
            //クリックしたサムネイルと同じ順番のメイン画像を表示してそれ以外は非表示にする
            $large.eq($thmbnail.index($(this))).show().siblings().hide();
        }
    ); 
});
</script> 
</head>
<body>
    <div>
        <img class="large" src="http://zoomsl.sergeland.ru/images/fashion-056.jpg" alt="" width="247" />
        <img class="large" src="http://zoomsl.sergeland.ru/images/fashion-054.jpg" alt="" width="247" />
        <img class="large" src="http://zoomsl.sergeland.ru/images/fashion-033.jpg" alt="" width="247" />
        <img class="large" src="http://zoomsl.sergeland.ru/images/fashion-072.jpg" alt="" width="247" />
    </div>
    <div>
        <img class="thmbnail" src="http://zoomsl.sergeland.ru/images/fashion-056.jpg" alt="" width="58" />
        <img class="thmbnail" src="http://zoomsl.sergeland.ru/images/fashion-054.jpg" alt="" width="58" />
        <img class="thmbnail" src="http://zoomsl.sergeland.ru/images/fashion-033.jpg" alt="" width="58" />
        <img class="thmbnail" src="http://zoomsl.sergeland.ru/images/fashion-072.jpg" alt="" width="58" />
    </div>
</body>
</html>

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2015/07/21 15:36

    回答ありがとうございます。
    本来であればそのように画像を一枚一枚指定したいのですが、
    画像のパスが自動的に生成されるため、
    その使い方が厳しく...

    @if(descriptionImages.Count() > 0) {
    foreach(var descImage in descriptionImages) {
    string imgPath = string.IsNullOrEmpty(descImage.FilePath)?
    "product/item/images/"+ descImage.ProductId +"/Description/"+ descImage.ViewOrder: descImage.FilePath;
    imgPath = GenLinkUri(imgPath, "~/");
    <img class="thmbnail" src="@(imgPath)?@ViewBag.RCC" alt="" />
    }}

    このあたりが画像のパスを生成しているかと思います。

    すみません、補足等ありましたら追記いただけると幸いです。
    よろしくお願いいたします。

    キャンセル

  • 2015/07/21 15:48

    サムネイルでされているのと同様にメイン画像もループを使って複数のimg要素として出力できないのでしょうか?

    キャンセル

  • 2015/07/22 12:20

    すみません、初心者なものでその意味がよく理解できません...
    申し訳ありません。具体例を提示していただけるとありがたく思います。

    キャンセル

  • 2015/07/22 12:58

    サムネイル部分の記述が正しいことが前提ですが、
    メイン画像の部分を以下のようにすればできるんじゃないでしょうか。

    ■修正前
    <img id="product_large_image" class="large" src="@(imageUrl)?@ViewBag.RCC" data-image-source="@imageUrl" alt="" data-large="@(imageUrl)?@ViewBag.RCC" title=""/>

    ■修正後
    @if(descriptionImages.Count() > 0) {
    foreach(var descImage in descriptionImages) {
    string imgPath = string.IsNullOrEmpty(descImage.FilePath)?
    "product/item/images/"+ descImage.ProductId +"/Description/"+ descImage.ViewOrder: descImage.FilePath;
    imgPath = GenLinkUri(imgPath, "~/");
    <img class="large" src="@(imgPath)?@ViewBag.RCC" alt="" title=""/>
    }}

    あと、全て同じサイズの画像を使われるとのことなので、サンプルコードを修正しました。

    キャンセル

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

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

関連した質問

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