<div class="container">
    <section class="slide">
        <div class="slide__content">
            <h1>ミツエーリンクスについて</h1>
        </div>
        <p class="slide__ruby">本日はミツエーリンクスについてお話します。</p>
    </section>
    <section class="slide">
        <div class="slide__content">
            <h2>会社情報</h2>
        </div>
        <p class="slide__ruby">ミツエーリンクスは、顧客企業さまのビジネスを持続的発展に導く、国内屈指のコミュニケーション・デザイン・カンパニーです。</p>
    </section>
</div>
* {
    margin: 0;
    padding: 0;
}
html {
    height: 100%;
}
body {
    height: 100%;
}
body.is-presentation .slide__ruby {
    display: none;
}
.container {
    height: 100%;
    display: flex;
    scroll-snap-type: x mandatory;
    overflow: auto;
}
.slide {
    display: grid;
    grid-template-columns: 1fr;
    grid-template-rows: 1fr 0.2fr;
    min-width: 100%;
    scroll-snap-align: start;
}
.slide__content {
    display: grid;
    place-items: center;
}
.slide__ruby {
    background: #eee;
    padding: 20px;
}
let currentPageIdx = 0;
const bc = new BroadcastChannel('app');
const container = document.querySelector('.container');
const nodeListOfSlide = document.querySelectorAll('.slide');
const isPresentation = /presentation/.test(location.search);
/**
 * 各スライドのid属性にindex番号を割り振る
 * @returns {void}
 */
const setIndexOnSlide = () => {
    nodeListOfSlide.forEach((slide, i) => {
        slide.id = `page-index_${i}`;
    });
};
/**
 * スライドの切り替わりを監視し、他閲覧コンテキストにスライドの切り替え信号を送る
 * @returns {void}
 */
const observeSlide = () => {
    const slideObserver = new IntersectionObserver((entries) => {
        for (entry of entries) {
            if (entry.isIntersecting) {
                const pageIdx = entry.target.id.split('_')[1];
                currentPageIdx = pageIdx;
                bc.postMessage({name: 'changeSlide', value: pageIdx});
            }
        }
    }, {threshold: 1});

    nodeListOfSlide.forEach((slide) => {
        slideObserver.observe(slide);
    });
};
/**
 * 他閲覧コンテキストからメッセージを受け取った時の処理
 * @param {MessageEvent} e
 * @returns {void}
 */
const onMessage = (e) => {
    const {name, value} = e.data;

    if (name === 'pageSyncRequest' && !isPresentation) {
        bc.postMessage({name: 'syncCurrentPageIdx', value: currentPageIdx});
    }
    if (name === 'changeSlide') {
        currentPageIdx = value;

        const target = document.querySelector(`#page-index_${value}`);
        container.scrollBy({
            left: target.getBoundingClientRect().left,
            behavior: 'smooth'
        });
    }
};
/**
 * 初期化
 * @returns {void}
 */
const init = () => {
    setIndexOnSlide();
    observeSlide();

    bc.onmessage = onMessage

    if (isPresentation) {
        document.body.classList.add('is-presentation');
        bc.postMessage({name: 'pageSyncRequest', value: null});
    }
};

init();
})();

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.