tacky4
@tacky4 (Tacky4 .)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

【プレビュー機能】inputとプレビューが一対一対応になるようにするには?

解決したいこと

inputとプレビュー部分が一対一対応になるようにするには?

例)
Ruby on Railsで紹介ページを作成しています。
プレビュー機能をつけたいのですが、選択した画像が、いずれも画像1-0のプレビュー部分(灰色)に表示されてしまいます。
もし解決方法をご存知の方がいれば、知恵を分けていただけるとありがたいです。

目的とするイメージ

スクリーンショット 2021-09-11 1.00.55.png

問題のコード HTML(RubyonRails Javascript)

<div class="before-fots">
   <!--順に12345-->
      <% for n in 1..5 %>
        <div class="before-fot">
          <p>画像<%= n %>-0</p>
          <div class="before-img-form">
            <img  id="preview" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==">
          </div>
          <div class=before-img-setting>
            <form>
              <input class="before-img" type="file" accept='image/*' onchange="previewImage(this);">
            </form>
          </div>
        </div>
      <% end %>

</div>  


<script>
function previewImage(obj)
{
    var fileReader = new FileReader();
    fileReader.onload = (function() {
        document.getElementById('preview').src = fileReader.result;
    });
    fileReader.readAsDataURL(obj.files[0]);
}
</script>

自分で試したこと

<%= n %>を使って、プレビュー部分のimgのid(7行目)とプレビュー機能(scrpit5行目)を変数に直してみました。が、今度は画像5-0のプレビュー部分に、選択した画像が表示されてしまいました。

<div class="before-fots">
   <!--順に12345-->
      <% for n in 1..5 %>
        <div class="before-fot">
          <p>画像<%= n %>-0</p>
          <div class="before-img-form">
            <img  id="preview<%= n %>" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==">
          </div>
          <div class=before-img-setting>
            <form>
              <input class="before-img" type="file" accept='image/*' onchange="previewImage(this);">
            </form>
          </div>
        </div>
      <% end %>

</div> 

<script>
function previewImage(obj)
{
    var fileReader = new FileReader();
    fileReader.onload = (function() {
        document.getElementById('preview<%= n %>').src = fileReader.result;
    });
    fileReader.readAsDataURL(obj.files[0]);
}
</script>
0

2Answer

document.getElementById('preview').src = fileReader.result;


を

```js:
obj.closest('.before-fot').querySelector('img').src = fileReader.result;

に変更すればいけると思います。
(当方で確認した限りでは大丈夫でした)

1Like

Comments

  1. @tacky4

    Questioner

    d9203さん、ありがとうございました! 無事動作するようになりました。

<% for n in 1..5 %>
...
<img  id="preview" src="data:...">
...
<% end %>

...
...

<script>
...
document.getElementById('preview').src = fileReader.result;
...
</script>

全ての画像とgetElementByIdが同じpreviewなので、getElementByIdでどこを指定しても最初のpreviewID画像が選択されるので最初の画像が変わる。

<%= n %>をつけた場合for n in 1..5で使ったnが最終的に5という値を持つ変数として存在するようになるので、今度はどの画像を変更してもdocument.getElementById('preview5').src = fileReader.result;になってしまい、最後の画像だけが変わる(出力されるHTMLソースを見れば分かるはず)。

今そのままのソースを活かすなら、previewImageにindexを渡すのが早いと思います。

あとrubyでfor文はほぼ間違いなく書くことがないので、rubyっぽい書き方にしたほうが良いと思います。

# for n in 1..5
5.times{|n| ... }
1.upto(5){|n| ... }
(1..5).each{|n| ... }

0Like

Comments

  1. @tacky4

    Questioner

    github0013さん、ありがとうございました!
    コードは他の方に教えていただいたコードで改善しました。

    ただ、イメージしていたコードはgithub0013さんの「previewImageにIndexを渡す」というものです。もしよろしければ、解答のコードを教えていただけないでしょうか?

Your answer might help someone💌