HOME > JavaScript > JavaScriptで動くニュースティッカー(newsticker)の作り方【コピペで1分】

JavaScriptで動くニュースティッカー(newsticker)の作り方【コピペで1分】

JavaScriptで動くニュースティッカーのDEMO
DEMOページ

JavaScriptで動くニュースティッカーの作り方解説

JavaScriptを使用してlistの中身を上部にスライドさせ、次のlistが流れてくるように実装。
※このサイトのトップで実際に動いている手作りニュースティッカーです。

  • 1.HTMLは親要素とリスト(ul・li)要素で構成する。親要素に「overflow: hidden;」をかけて対象部分以外は非表示にする。
  • 2.リストのcssの切り替えアニメーションを設定。「transform: translateY;」でY軸(縦軸)にアニメーションするように設定
  • 3.Javascriptで切り替え処理を作成し、リサイズした際は調整するように指定。
  • 4.ニュースの文字数が多い場合は「…」に切り替わるようにする。
  • 5.正しく動作していれば完成です。
HTML記述

HTMLをbody内の表示位置に記載します。

<div class="ticker">
    <ul class="news">
        <li>ニュース1<a href="">サンプルサンプルサンプルサンプルサンプル</a></li>
        <li>ニュース2<a href="">サンプルサンプルサンプルサンプルサンプル</a></li>
        <li>ニュース3<a href="">サンプルサンプルサンプルサンプルサンプル</a></li>
        <!-- 追加のニュース項目 -->
    </ul>
</div>
css記述

cssを<style>~</style>または自作cssの中に記述します。

<style>
.ticker {
    overflow: hidden; /* 必須 */
    height: 50px;
    border: 1px solid #ccc;
}
    
.news {
    list-style-type: none;
    padding: 0;
    margin: 0;
    animation: newsticker infinite linear;  /* アニメーション設定 */
}
    
.news li {
    height: 50px;
    line-height: 50px;
    background-color: #fff;
}
    
@keyframes newsticker {
    /* 0%から25%までは初期状態(元の位置)から変化しない */
    0%, 25% {
        transform: translateY(0);
    }
    /* 50%ではニュースを上にスライドさせる */
    50% {
        transform: translateY(calc(-100% - 1px));
    }
    /* 75%から100%まではニュースを上にスライドしたまま変化しない */
    75%, 100% {
        transform: translateY(calc(-100% - 1px));
    }
}
</style>
Javascript記述

javascriptを<script>~</script>または自作jsの中に記述します。

<script>
// ニュースティッカー
document.addEventListener('DOMContentLoaded', function() {
    let newsList = document.querySelector('.news');
    let newsItems = newsList.getElementsByTagName('li');
    let newsHeight = newsItems[0].offsetHeight;
    let newsDisplayTime = 3000;   // ニュースが表示される時間(ミリ秒)(最初のニュース1が切り替わるまでの時間)
    let switchDelay = 2000;       // ニュースの切り替えまでの遅延時間(ミリ秒)(以降の各ニュースが切り替わるまでの時間)
    let switchDuration = 1000;    // ニュースの切り替え速度(ミリ秒)
    
    function startTickerAnimation() {
        tickerAnimation();
        setInterval(tickerAnimation, newsDisplayTime + switchDelay);
    }
    
    function tickerAnimation() {
        let ticker = newsList.firstElementChild;
        let marginTop = parseInt(window.getComputedStyle(ticker).marginTop);
        let newMarginTop = marginTop - newsHeight;
        
        ticker.style.transition = 'margin-top ' + switchDuration + 'ms ease-in-out';
        ticker.style.marginTop = newMarginTop + 'px';
    
        setTimeout(function() {
            newsList.appendChild(ticker);
            ticker.style.transition = '';
            ticker.style.marginTop = '0';
        }, switchDuration);
    }
    
    setTimeout(startTickerAnimation, newsDisplayTime);


    //はみ出した部分を3点リーダにする
    let maxLength = 18; // 上限文字数
    let originalTexts = {}; // 元のテキストを保持するオブジェクト

    function applyTextLimit() {
    if (window.innerWidth <= 767) {
        let listItems = document.querySelectorAll('.news li');
        for (let i = 0; i < listItems.length; i++) {
            let listItem = listItems[i];
            let originalText = listItem.getAttribute('data-original-text');
            if (!originalText) {
                originalText = listItem.innerHTML;
                listItem.setAttribute('data-original-text', originalText); // 元のテキストをdata属性に保存
            }
            let anchorTag = listItem.querySelector('a');
            if (anchorTag) {
                let anchorText = anchorTag.innerHTML;
                if (anchorText.length > maxLength) {
                    let truncatedText = anchorText.substr(0, maxLength) + '...';
                    anchorTag.innerHTML = truncatedText; // aタグのテキストを上限文字数で切り詰めて三点リーダを追加
                }
            }
            // ここで処理が終了し、次の要素へ移動
        }
        // 767px以下の場合の処理終了
    } else {
            let listItems = document.querySelectorAll('.news li');
            for (let i = 0; i < listItems.length; i++) {
            let listItem = listItems[i];
            let originalText = listItem.getAttribute('data-original-text');
            if (originalText) {
                listItem.innerHTML = originalText; // 元のテキストに戻す
            }
            // ここで処理が終了し、次の要素へ移動
            }
            // 767px以上の場合の処理終了
        }
    }

    // 初回実行
    applyTextLimit();

    // ウィンドウのリサイズ時に実行
    window.addEventListener('resize', function() {
        applyTextLimit();
    });
});
</script> 
関連アニメーション

その他javascriptアニメーション