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

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

ただいまの
回答率

88.91%

スクロールで要素を表示範囲を設定したい

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 147

bakio

score 16

<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="utf-8">
  <link rel="stylesheet" href="css/style.css">
  <script src="js/jquery-3.4.1.min.js"></script>
  <script type="text/javascript" src="js/fixed_offer.js"></script>

  <title>フローティングの表示範囲設定</title>

</head>

<body>

  <div><img src="img/fv.jpg"></div>
  <div><img src="img/view.jpg"></div>
  <a id="fixed-offer-start" href="#fixed-offer-start"></a>
  <div><img src="img/img01.jpg"></div>
  <div><img src="img/img02.jpg"></div>
  <div><img src="img/img03.jpg"></div>
  <div><img src="img/img04.jpg"></div>
  <div><img src="img/img05.jpg"></div>
  <div><img src="img/img06.jpg"></div>
  <div><img src="img/img07.jpg"></div>
  <div><img src="img/img08.jpg"></div>
</div><a id="fixed-offer-end" href="#fixed-offer-end"></a>
<div><img src="img/not_view.jpg"></div>

  <div class="fixed-cta" id="fixed-cta">
    <a class="fixed-cta_button"><img src="img/float.png"></a>
  </div>
</body>

</html>
*{
  margin: 0;
  padding: 0;
}
body{
  text-align: center;
  background-color: #EBE5ED;
  width: 50%;
  margin: 0 auto;
}
img{
  width: 50%;
  vertical-align: bottom;
}

.fixed-cta {
  bottom: 0;
  left: 0;
  opacity: 0;
  position: fixed;
  text-align: center;
  width: 100%;
  z-index: 100;
}


.fixed-cta_button {
  animation: beat linear 1s 0s infinite;
  display: inline-block;
  padding: 0 ;
  transform-origin: bottom;
}
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var FixedOffer = /** @class */ (function () {
    function FixedOffer(element, options, labels) {
        var _this = this;
        if (element === void 0) { element = ''; }
        if (labels === void 0) { labels = {
            ended: 'fixed-offer-is-ended',
            initialized: 'fixed-offer-is-initialized',
            invisible: 'fixed-offer-is-invisible',
            visible: 'fixed-offer-is-visible',
        }; }
        this.labels = labels;
        this.isShown = false;
        this.isClosedOnPurpose = false;
        this.options = __assign({
            elementClass: 'fixed-offer',
            startSelector: '#fixed-offer-start',
            endSelector: '#fixed-offer-end',
            closeButtons: '.fixed-offer-closer',
            revivalMinutes: 0,
            startCondition: 'entered',
            isShownEternally: false,
            endCondition: 'entered'
        }, options);
        this.element = document.querySelector(element) || document.createElement('div');
        this.element.classList.add(this.options.elementClass);
        this.start = document.querySelector(this.options.startSelector);
        this.end = document.querySelector(this.options.endSelector);
        this.closeButtons = document.querySelectorAll(this.options.closeButtons);
        if (this.closeButtons.length) {
            this.closeButtons.forEach(function (item) {
                item.addEventListener('click', function (e) {
                    e.preventDefault;
                    _this.close();
                    _this.isClosedOnPurpose = true;
                    if (typeof _this.options.revivalMinutes === 'number' && _this.options.revivalMinutes > 0) {
                        _this.startRevivalTimer();
                    }
                });
            });
        }
        if (IntersectionObserver) {
            var observer = new IntersectionObserver(function (entries) {
                _this.toggleOnScroll();
            }, {
                threshold: 0
            });
            if (this.start)
                observer.observe(this.start);
            if (this.end)
                observer.observe(this.end);
        }
        else {
            var scrollTimer_1;
            window.addEventListener('scroll', function () {
                if (scrollTimer_1) {
                    return;
                }
                scrollTimer_1 = setTimeout(function () {
                    scrollTimer_1 = 0;
                    _this.toggleOnScroll();
                }, 500);
            });
            window.addEventListener('load', function () {
                _this.toggleOnScroll();
            });
            window.addEventListener('resize', function () {
                _this.toggleOnScroll();
            });
        }
        this.element.addEventListener('transitionend', function () {
            _this.element.classList.add(_this.labels.ended);
        });
        this.element.classList.add(this.labels.initialized);
        this.element.classList.add(this.labels.ended);
        this.toggleOnScroll();
    }
    FixedOffer.prototype.show = function () {
        if (!this.isShown && !this.isClosedOnPurpose) {
            this.element.classList.remove(this.labels.ended);
            this.element.classList.remove(this.labels.invisible);
            this.element.classList.add(this.labels.visible);
            this.isShown = true;
        }
    };
    FixedOffer.prototype.close = function () {
        if (this.isShown) {
            this.element.classList.remove(this.labels.ended);
            this.element.classList.remove(this.labels.visible);
            this.element.classList.add(this.labels.invisible);
            this.isShown = false;
        }
    };
    FixedOffer.prototype.toggleOnScroll = function () {
        var scroll = this.testScroll();
        if (scroll.start && !scroll.end) {
            this.show();
        }
        else if (!this.options.isShownEternally || scroll.end) {
            this.close();
        }
    };
    FixedOffer.prototype.testScroll = function () {
        return {
            start: this.start !== null ? this.testScrollState(this.start, this.options.startCondition) : true,
            end: this.end !== null ? this.testScrollState(this.end, this.options.endCondition) : false
        };
    };
    FixedOffer.prototype.startRevivalTimer = function () {
        var _this = this;
        var timer = setTimeout(function () {
            _this.isClosedOnPurpose = false;
        }, this.options.revivalMinutes);
    };
    FixedOffer.prototype.getY = function (element) {
        return window.pageYOffset + element.getBoundingClientRect().top;
    };
    FixedOffer.prototype.testScrollState = function (element, condition) {
        switch (condition) {
            case 'arrived':
                return window.pageYOffset >= this.getY(element) - window.innerHeight;
            case 'top':
                return window.pageYOffset >= this.getY(element);
            case 'entered':
                return window.pageYOffset >= (this.getY(element) + element.offsetHeight - window.innerHeight);
            case 'left':
                return window.pageYOffset >= this.getY(element) + element.offsetHeight;
            default:
                return false;
        }
    };
    return FixedOffer;
}());

position: fixed;で追従させる要素

<div class="fixed-cta" id="fixed-cta">     <a class="fixed-cta_button"><img src="img/float.png"></a>   </div>

何をどこで表示開始、非表示にさせるか

<div class="fixed-cta" id="fixed-cta">     <a class="fixed-cta_button"><img src="img/float.png"></a>   </div>

<a id="fixed-offer-start" href="#fixed-offer-start"></a>
で1度表示開始
</div><a id="fixed-offer-end" href="#fixed-offer-end"></a>
のタグ地点で上記追従要素を非表示

 エラーメッセージ・具体的な不具合

追従の要素が指定の範囲で表示・非表示されない(指定の範囲は上記の通り)
そもそも追従要素すら表示されない

詳しい方ご教授いただけますと幸いです。

  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • bakio

    2020/07/10 11:47

    【関数の呼び出し】
    こちらでしょうか?間違っていたらすみません。



    const fixedOffer = new FixedOffer('#fixed-cta')

    const voiceSwitch = document.getElementById('voice_switch')
    const voiceContent = document.getElementById('voice_content')
    if (voiceSwitch && voiceContent) {
    voiceSwitch.classList.add('is-hidden')
    voiceContent.classList.add('is-hidden')
    voiceSwitch.addEventListener('click', function(e){
    e.preventDefault()
    voiceSwitch.classList.toggle('is-hidden')
    voiceContent.classList.toggle('is-hidden')
    })
    }

    キャンセル

  • Lhankor_Mhy

    2020/07/10 12:27

    1行目がそれっぽいですね。
    動作しましたか?

    キャンセル

  • bakio

    2020/07/10 16:05

    動作せずでした....
    たくさんお時間割いていただいて申し訳ございません

    キャンセル

回答 1

0

以下のようにすると、当方の環境では動作しました。

CSSを追加。

  .fixed-offer-is-visible{
    opacity: 1;
  }

JavaScriptを追加。(ロードイベントの中か、bodyの末尾で)

const fixedOffer = new FixedOffer('#fixed-cta');

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/07/10 21:19

    早速実践しましたが何も反応せずでした。もう少し粘ります。
    お時間いただき大変恐縮です。ありがとうございます。

    キャンセル

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

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

関連した質問

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