はじめに
ショッピングサイトなどを作成する際各商品のyoutube動画をポップアップで表示させたい時、データベース内のそれぞれのyoutube埋め込みリンクを呼び出す方法を以下に記します。
htmlはhamlを使用して記述しています。
##今回記述したコード
class EffectorsController < ApplicationController
def index
@effectors = Effector.all.includes(:genre)
end
end
.main
.main__list
- @effectors.each do |effector|
.main__list__effector{data: {genre: effector.genre.id}}
.main__list__effector__info
.main__list__effector__info__visual
%h.main__list__effector__info__visual__name
= effector.name
.main__list__effector__info__visual__image
%img{alt: "image1", class: "main__list__effector__info__visual__image__file", src: "#{- effector.image1}"}
%img{alt: "image2", class: "main__list__effector__info__visual__image__file", src: "#{- effector.image2}"}
.main__list__effector__info__text
%h.main__list__effector__info__text__genre
= effector.genre.genre
%h.main__list__effector__info__text__point
= effector.point
pt
%br
%h.main__list__effector__info__text__detail
= effector.text
.main__list__effector__info__btns
- if effector.youtube != nil
.main__list__effector__info__btns__video
%button.main__list__effector__info__btns__video__btn{onclick: "test(#{effector.youtube})"}
動画を視聴
-# onclick: を使うことでクリックされた時jsのtestという関数をeffector.youtubeを引数として発火することができる
- if effector.link != nil
.main__list__effector__info__btns__official
= link_to "#{effector.link}", class: "main__list__effector__info__btns__official__btn" do
.main__list__effector__info__btns__official__btn__text
公式サイト
- if user_signed_in?
.main__list__effector__info__btns__cart
%button.main__list__effector__info__btns__cart__btn{onclick: "createCart(#{current_user.id},#{effector.id})"}
カートに入れる
.popup
-# popupのdivをeach文の外に作ることでビューページを読み込んだ際に商品数分popupのdivが生成されないようにする
.popup__content
.popup__content__youtube
%iframe(width="560" height="315" id = "youtube_test" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen)
-# 本来youtube埋め込みタグには動画固有のsrc属性値を持っている。今回はそれを商品のテーブルのカラムyoutubeに格納してある。
%button#close
閉じる
$(function(){
//closeボタンが押された時の処理
$('#close').on('click',function(){
$('.popup').removeClass('show');
$('.popup').fadeOut();
$('#youtube_test').attr('src', '');
});
});
// html上のonclick: "test(#{effector.youtube})"で呼び出される関数
function test(url){
//ここで埋め込みタグの中にsrc属性値を仮引数(url)を用いて追加
$('#youtube_test').attr('src', url);
$('.popup').attr('id','show').css('display', 'none').fadeIn();
};
###ポップアップのcssは自由ですが参考までに今回popupに当てたscssを記載しておきます。
.popup {
display: none;
height: 100vh;
width: 100%;
background: rgba(45,45,45, 0.7);
position: fixed;
top: 0;
left: 0;
&__content{
background: #fff;
padding: 30px;
height: 400px;
width: 55%;
display: flex;
}
}
#show {
display: flex;
justify-content: center;
align-items: center;
}
#close{
margin:130px 0 0 30px;
height: 70px;
width: 300px;
border: 1px solid #3e9eec;
background-color: #7aa2c2;
color: white;
font-size: 15px
}
#ポイント
今回はそれぞれの商品が持つyoutubeの埋め込みタグの情報をどのように利用してdivクラスpopupを作成するかが焦点となりました。
まず考えたことはeach文以下にdivクラスpopupを記述する方法でした。
そうした場合テーブル内の商品数分popupが生成されてしまい、どの動画視聴ボタンを押しても全てのdivクラスpopupがfadeInしてくるという現象が起きました(動画を視聴ボタンに固有のidをeffector.idとして振る方法も考えましたが商品数分divクラスpopupを作成するのは望ましくない)。
そのため、each文の外にdivクラスpopupを作成しyoutubeの埋め込みタグ内に動画を視聴ボタンがクリックされた商品のsrc属性値を追加してあげればいい!という結論になりました。
各商品のsrc属性値の取得方法
ここで焦点になってくるのはボタンが押された際にどのようにその商品のsrc属性値をdivクラスpopup内のyoutube埋め込みタグに追加してあげるかということです。
ここでhtml内にクリックされた時に関数を呼び出すことができるonclickの使用をします。
htmlの上にonclick: "関数名(引数)"とすることで引数を持ちながらjsの関数を呼び出せます。
今回は
%button.main__list__effector__info__btns__video__btn{onclick: "test(#{effector.youtube})"}
動画を視聴
とすることでボタンが押された商品のeffector.youtube(今回はeffectorテーブルのyoutubeカラムにsrc属性値が格納されています)を実引数としてjsのtest(url)を呼び出していることがわかると思います。
function test(url){
//ここで埋め込みタグの中にsrc属性値を仮引数(url)を用いて追加
$('#youtube_test').attr('src', url);
$('.popup').attr('id','show').css('display', 'none').fadeIn();
};
呼び出された際にpopup内のyoutube埋め込みタグに.attr('src',url)とすることで各商品のyoutube埋め込みようのsrc属性値を追加できたことがわかると思います。
そのあとはdivクラスpopupをfadeInしてあげればdisplay: none;で画面上に隠してあったpopupが表示されます。
#終わりに
onclick: "関数名(引数)"これが結構使うことが多いなと感じたので覚えるべきものだと感じました。
初めての投稿で文章力もコードも拙いものだと思いますがご精読ありがとうございました。