1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

railsアプリでの追従バナーの実装サンプル

Posted at

概要

Webページの左下に追従表示される画像バナーの参考レシピを記載しています。
※一番肝心な「jsのaddScrollListener関数」の解説がまだできていないので、そのあたりよしなに準備できる方の参考程度に。。。そのうち追記します。

画像ファイル

任意の画像を準備しanavi/app/assets/images配下に格納します。以降のサンプルコードでは「xxxx.png」とします。

ビューファイル

Ruby on Rails(slim表記)

以下のようなパーシャルファイルを作成し、追従バナーの表示が必要なページでrenderして呼び出します。
slim表記で記載しています。

app/views/shared/_fixed_banner.html.slim
.fixed_banner
  = link_to "リンクさせたいページURL", target: :_blank, rel: :noopener
    = image_tag "xxxx.png", alt: "代替文言を記載"

- content_for :local_js do
  script type="text/javascript" src="/assets/javascripts/xxxx.min.js"
  javascript:
    setStartScroll();
app/views/xxxx/xxxx.html.slim(追従バナーを設置したいビューファイル)
- # 追従バナーを描画する
= render 'shared/fixed_banner'

- content_for :local_js doの部分は個別のviewファイル内にjavascriptを直接書き込む場所として利用していて、ここでライブラリ読み込んだり、処理を直接書いたりしておいたものを、全ページ共通のテンプレートに呼び出した時に、以下のように生成させています。

全ページ共通レイアウト(application.html.erbに当たるようなファイル)
 = yield :local_js

HTMLに変換された後

<div class="fixed_banner">
  <a target="_blank" rel="noopener" href="リンクさせたいページURL">
    <img alt="代替文言を記載" src="/assets/xxxx.png">
  </a>
</div>

・・・

<!-- content_for :local_js doで書いていたものも読み込まれている-->
<script>省略</script>
<script>省略</script>

スタイルシート

scss記法のsassで書いています。画面が表示された段階では非表示で、下にスクロールすると画面左下に追従表示され、ページ最下部まで画面スクロールすると非表示となるようにしています。 &.show と &.endが それぞれの状態でのスタイル。またスマートフォン表示では非表示となるようにしています。

scss

app/assets/stylesheets/xxxx.css.scss
/* 画面追従のバナー */
.fixed_banner {
  bottom: 14px;
  display: flex;
  left: 14px;
  opacity: 0;
  position: fixed;
  transition: opacity 400ms ease-in-out, transform 600ms cubic-bezier(0.165, 0.84, 0.44, 1);
  width: 350px;
  z-index: 99;
  &.show {
    opacity: 1;
  }
  &.end {
    opacity: 0;
  }
  img{
    border-radius: 4px;
    width: 100%;
  }
}
/*sp style*/
@media screen and (max-width: 767px) {
  .fixed_banner{
    display: none;
  }
}

cssに変換された後

/* 画面追従のバナー */
.fixed_banner {
  bottom: 14px;
  display: flex;
  left: 14px;
  opacity: 0;
  position: fixed;
  transition: opacity 400ms ease-in-out, transform 600ms cubic-bezier(0.165, 0.84, 0.44, 1);
  width: 350px;
  z-index: 99;
}

.fixed_banner.show {
  opacity: 1;
}

.fixed_banner.end {
  opacity: 0;
}

.fixed_banner img {
  border-radius: 4px;
  width: 100%;
}

/*sp style*/
@media screen and (max-width: 767px) {
  .fixed_banner {
    display: none;
  }
}

DOM操作

共通レイアウトとして、「ページ最上部のヘッダー」や「ページ最下部のコピーライト表記」があるためそれらの位置を基準にページのスクロール位置を判定して、それに応じて<div class="fixed_banner">・・・</div>要素に"show"や"end"のclassを追加したり、削除したりしています。それに応じて適応されるcssが変わり、表示や非表示が制御されます。

app/assets/javascripts/xxxx.js
//画面スクロールをトリガーに、追従バナーの表示と非表示を制御する
function setStartScroll(){
  var _target = $('header.fixed-top');
  if (_target[0]){
    var _targetT = _target.offset().top;
    var $fixed_banner = $('.fixed_banner');

    Shared.util.addScrollListener(function(t,b) {
      if (t > 40) {
        $fixed_banner.addClass('show');
      }else {
        $fixed_banner.removeClass('show');
      }
      if (b > $('.copyright_wrap').offset().top) {
        $fixed_banner.addClass('end');
      }else {
        $fixed_banner.removeClass('end');
      }
    });
  }
};

addScrollListenerは別のライブラリで定義している関数です。パーシャルファイルのlocal_jsなかでxxxx.min.jsで読み込んでいます。位置判定しています。

参考文献

slimについて
content_forやyieldについて

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?