lebronkoukou
@lebronkoukou (光聖 西田)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

rubyのeach文で取得した値にjavascriptは効かすことができますか?

解決したいこと

ruby on railsで投稿アプリを作っているのですが、
アクティブハッシュを用いて投稿をカテゴリー分けし、そのカテゴリーのアイディの数値ごとにif分で見た目を変えています。
その後、投稿の中身の文章が現状詳細画面に行かないと見れないためjavascriptを用いて実装したのですが、document.getElementByIdでアイディを取得する方法で実装したところ同じカテゴリーの二つ目以降はjavascriptが効かずに困っています。

 現状

  以下動画のように二つ目からはjavascriptが効かず、、、

Image from Gyazo

または、問題・エラーが起きている画像をここにドラッグアンドドロップ

該当するソースコード

やたらめったら長く書いてますが単純に投稿に対するカテゴリーによって見た目を変えているだけです。

<div class='item-lists'>
  <% @lives.each do |life| %>

    <% if life.tired_id == 2 %>

      <div class='item-img-content' id="test-a">
        <%= link_to life_path(life.id) do %>
          <div class="life-title-content">
            <div class="tired-name">種類</div><%= life.tired.name%>
          </div>
          <div class='life-title-content'>
            <div class="tired-name">季節</div><%= life.month.name %>
          </div>
          <div class="created">
            <div class="c-1"><%= image_tag 'family.png' , size: '30x30' %></div>
            <%= time_ago_in_words(life.created_at) %>
          </div>
        <% end %>
        <div class='item-img-content-z hidden' id="test-b">
          <%= link_to life_path(life.id) do %>
            <div class="life-title-content-z">
              <div class="tired-name">悩み</div><%= life.bad_thing %>
            </div>
            <div class="life-title-content-z">
              <div class="tired-name">感謝</div><%= life.hope%>
            </div>
          <% end %>
        </div>
      </div>
    <% elsif life.tired_id == 3 %>
      <div class='item-img-content-2' id="test-c">
        <%= link_to life_path(life.id) do %>
          <div class="life-title-content">
            <div class="tired-name">種類</div><%= life.tired.name%>
          </div>
          <div class='life-title-content'>
            <div class="tired-name">季節</div><%= life.month.name %>
          </div>
          <div class="created">
            <div class="c-1"><%= image_tag 'work.png' , size: '30x30' %></div>
            <%= time_ago_in_words(life.created_at) %>
          </div>
        <% end %>
        <div class='item-img-content-2-z hidden' id="test-d">
          <%= link_to life_path(life.id) do %>
            <div class="life-title-content-z">
              <div class="tired-name">悩み</div><%= life.bad_thing %>
            </div>
            <div class="life-title-content-z">
              <div class="tired-name">感謝</div><%= life.hope%>
            </div>
          <% end %>
        </div>
      </div>

javascriptはこんな感じ

function test() {
  const testMove = document.getElementsByClassName("test-a")
  const testMoveParents = document.getElementsByClassName("test-b")

  testMove.addEventListener('mouseover', function(){
    testMoveParents.setAttribute("style", "display:block;")
  })
  testMove.addEventListener('mouseout', function(){
    testMoveParents.removeAttribute("style", "display:block;")
  })

  const test_2Move = document.getElementById("test-c")
  const test_2MoveParents = document.getElementById("test-d")

  test_2Move.addEventListener('mouseover', function(){
    test_2MoveParents.setAttribute("style", "display:block;")
  })
  test_2Move.addEventListener('mouseout', function(){
    test_2MoveParents.removeAttribute("style", "display:block;")
  })




  const test_3Move = document.getElementById("test-e")
  const test_3MoveParents = document.getElementById("test-f")

  test_3Move.addEventListener('mouseover', function(){
    test_3MoveParents.setAttribute("style", "display:block;")
  })
  test_3Move.addEventListener('mouseout', function(){
    test_3MoveParents.removeAttribute("style", "display:block;")
  })


  const test_4Move = document.getElementById("test-g")
  const test_4MoveParents = document.getElementById("test-h")

  test_4Move.addEventListener('mouseover', function(){
    test_4MoveParents.setAttribute("style", "display:block;")
  })
  test_4Move.addEventListener('mouseout', function(){
    test_4MoveParents.removeAttribute("style", "display:block;")
  })


  const test_5Move = document.getElementById("test-i")
  const test_5MoveParents = document.getElementById("test-j")

  test_5Move.addEventListener('mouseover', function(){
    test_5MoveParents.setAttribute("style", "display:block;")
  })
  test_5Move.addEventListener('mouseout', function(){
    test_5MoveParents.removeAttribute("style", "display:block;")
  })


  const test_6Move = document.getElementById("test-k")
  const test_6MoveParents = document.getElementById("test-l")

  test_6Move.addEventListener('mouseover', function(){
    test_6MoveParents.setAttribute("style", "display:block;")
  })
  test_6Move.addEventListener('mouseout', function(){
    test_6MoveParents.removeAttribute("style", "display:block;")
  })


}
window.addEventListener('load', test)

自分で試したこと

調べたところgetElementByIdは一つしか取得できないため上記動画のような現象が出ているのは理解できたのですが、ではeach文で取り出した投稿にどのようにjavascriptを作動させれるのかが分からず、、
class名から引っ張ってきたりもしたのですが上手く行かず、もしわかる方がいらっしゃれば教えて頂けないでしょうか?

0

1Answer

getElementByIdは一つしか取得できない

というより、idの値は一意でなければならない、というのが適切です。
今回のようなケースでidをつけたい場合は、データのidなどを使って次のように付けたりします。

<div id="item-<%= item.id %>">
</div>

本題のJavaScriptの部分ですが、複数の要素を対象とする場合は主にclassを使います。

<div class="item">
  <div class="item-inner">
    <p>item 1</p>
  </div>
</div>
<div class="item">
  <div class="item-inner">
    <p>item 2</p>
  </div>
</div>
<div class="item">
  <div class="item-inner">
    <p>item 3</p>
  </div>
</div>

このようなHTMLからitemの要素を取得するには次のようになります。

const items = document.getElementsByClassName("item");

getElementsByClassName()の返り値はHTMLCollectionです。
次はこれをループ処理していくことになります。
次のコードは、itemに対してマウスオーバー、マウスアウトでイベントを設定し、item-innerの背景色を変更します。

function init() {
  const items = document.getElementsByClassName("item");
  for (let i = 0; i < items.length; i++) {
    let item = items.item(i);
    let itemInner = item.getElementsByClassName("item-inner").item(0);
    item.addEventListener("mouseover", function(){
      itemInner.setAttribute("style", "background-color:#0000ff;");
    });
    item.addEventListener("mouseout", function(){
      itemInner.removeAttribute("style", "background-color:#ffffff;");
    });
  }
}
window.addEventListener('load', init);
2Like

Comments

  1. @lebronkoukou

    Questioner

    @blue32aさん
    ありがとうございます!!
    早速実装してみます!javascriptは一切理解できていなかったので助かりました!!

Your answer might help someone💌