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>
関連アニメーション