web-wizardry

インターネット・スマホ、そしてテレビにwebの魔法をWizardry

jQueryで作る右から左へテキストが移動するニュースティッカー

2015年07月21日 · jQuery

新幹線のニュース掲示板のように右から左へテキストが移動するニュースティッカーがなかなか良いのが見つからない

HTMLとCSSで1行を移動させるものや
複数行でいっぺんに流れるニュースティッカーというのもはあったが、

1行流れた後に次の内容を表示するような
ニュースティッカーは探してみても見当たらないので作ってみました。

今回はその作り方を紹介します。

仕様の確認

・テキストが左から右へ流れる
・テキストが右へ流れきったら、次のテキストがあれば次のテキストが流れる
 次のテキストがなければ同じテキストが流れる
・テキストにマウスを当てるとテキストが停止する
・マウスが離れるとテキストが停止した位置からスタートする
という項目の流れを作っていきます。

HTMLを構築

<ul id="ticker_area">
	<li class="first"><a href="#">ニュースティッカー1</a></li>
</ul>

Ulにid名「ticker_area」とします
liの初めの項目にクラス名firstととします
複数行の文字を流したい場合はHTMLを以下のようにします

<ul id="ticker_area">
	<li class="first"><a href="#">ニュースティッカー1</a></li>
	<li><a href="#">ニュースティッカー2</a></li>
</ul>

liの項目を増やすようにしていきます

CSSの構築

#ticker_area {
	width: 100%;
	height: 20px;
	background: #000;
	color: #fff;
	padding: 5px 0;
	overflow: hidden;
	position: relative;
}
#ticker_area li{
	margin: 0;
	color: #fff;
	white-space: nowrap;
	position: absolute;
	top:7px;
	left: 2000px;
}
#ticker_area li a {
	color: #fff;
	text-decoration: none;
}

CSSのポイントとして
1:「ticker_area」の「overflow: hidden;」としている箇所
要素がはみ出している箇所は全部非表示にするという箇所です
2:「#ticker_area li」の「position: absolute;」としている箇所
left:xxxで右から左へ移動することが可能になります
3:「#ticker_area li」の「left: 2000px;」としている箇所
スクリプトで位置の調整をおこなうのですが、初期値は大きめに指定して予期せぬ表示を避けるようにしました。

スクリプトの構築

全体のスクリプトは以下のようになります。

<script >
$(window).load(function () {
var w = $(window).width();
var ticker_area_p = null;
var text_w = null;
var total_w = null;
var sec = null;
var move = null;
var timerId = null;


setText();
function setText(){
	ticker_area_p = $("#ticker_area .first");
	text_w = $(ticker_area_p).width()+50;
	total_w = w+text_w;
	sec = 3000;
	move = total_w / sec;//移動値
	$(ticker_area_p).css("left", w); //テキスト端に移動
}
 
moveText();
//アニメーション
function moveText(){
	timerId = setInterval(function(){
		var pos = $(ticker_area_p).position();
		if(text_w*-1 > pos.left ){
			clearInterval(timerId);
			textChange();
		}else{
			$(ticker_area_p).css("left", pos.left-move);
		}
		
	},0.1);
}

//ホバー時
$(document).on('mouseenter', "#ticker_area .first",function(){
    clearInterval(timerId);
});
$(document).on('mouseleave', "#ticker_area .first",function(){
    moveText();
});
function textChange(){
	var elm = $("#ticker_area").children();
	
	$(ticker_area_p).css("left", w); //テキスト端に移動
	
	if(elm.length > 1){
		$("#ticker_area").append(ticker_area_p);
		$("#ticker_area .first").removeClass("first");
		$($("#ticker_area").children()[0]).addClass("first");
	}
	setText();
	moveText();
}
});

1:各種の変数を宣言をおこないます。

var w = $(window).width();
var ticker_area_p = null;
var text_w = null;
var total_w = null;
var sec = null;
var move = null;
var timerId = null;

「$(window).width();」でブラウザーの幅を取得しておきます。

2:テキストの情報を設定

setText();
function setText(){
	ticker_area_p = $("#ticker_area .first");
	text_w = $(ticker_area_p).width()+50;
	total_w = w+text_w;
	sec = 3000;
	move = total_w / sec;//移動値
	$(ticker_area_p).css("left", w); //テキスト端に移動
}

「text_w = $(ticker_area_p).width()+50;」でテキストの長さプラス余白50pxとします
「total_w = w+text_w;」でブラウザーの幅とテキストの長さを「total_w」に格納
「sec = 3000;」アニメーションする速度
「move = total_w / sec;」長さと速度で移動する値を算出
「$(ticker_area_p).css(“left”, w);」テキストを左端に移動

3:アニメーション指示

moveText();
//アニメーション
function moveText(){
	timerId = setInterval(function(){
		var pos = $(ticker_area_p).position();
		if(text_w*-1 > pos.left ){
			clearInterval(timerId);
			textChange();
		}else{
			$(ticker_area_p).css("left", pos.left-move);
		}
		
	},0.1);
}

「timerId = setInterval(function(){」setIntervalで処理をグルグルと動作させる
ホバーじに停止をさせる為にtimerIdでsetIntervalの情報を保持させておく
「var pos = $(ticker_area_p).position();」で現在のleftの位置を所得
「if(text_w*-1 > pos.left ){」現在の位置が表示幅を超えたかどうかの確認
超えていない場合は、移動する処理へ
超えた場合は、次のテキストを読みにいく処理へ
「$(ticker_area_p).css(“left”, pos.left-move);」テキストを移動する
「clearInterval(timerId);
textChange();」でIntervalを停止させtextChangeの関数内容へ移動させます。

4:テキスト移動が表示範囲を超えた場合(一番左側へ移動したとき)

function textChange(){
	var elm = $("#ticker_area").children();
	
	$(ticker_area_p).css("left", w); //テキスト端に移動
	
	if(elm.length > 1){
		$("#ticker_area").append(ticker_area_p);
		$("#ticker_area .first").removeClass("first");
		$($("#ticker_area").children()[0]).addClass("first");
	}
	setText();
	moveText();
}

「var elm = $(“#ticker_area”).children();」でliの要素を取得します
「$(ticker_area_p).css(“left”, w);」左端に移動したので右端に移動させる
「if(elm.length > 1){」もし、要素が複数あれば処理をおこないます
「$(“#ticker_area”).append(ticker_area_p);」一番上にある項目を下へ移動
「$(“#ticker_area .first”).removeClass(“first”);」クラスfirstを削除
「$($(“#ticker_area”).children()[0]).addClass(“first”);」ticker_areaの一番上の要素にクラスfirstを付ける
「setText();」の処理をおこなう
「moveText();」アニメーションの処理をおこなう

5:テキストにマウスホバーした場合処理を止める
今回ちょっと特殊な書き方をしております
以前ブログで紹介した方法の応用をしております。
通常のhoverだと「$(“#ticker_area”).hover(function(){」のような形で書くのですが、
複数の項目になった場合、毎回「hover」イベントを発行する必要性がでてきます。
毎回処理を発行すると予期せぬ動作を招いてしまうので以下のような形で今回は定義しました。

$(document).on('mouseenter', "#ticker_area .first",function(){
    clearInterval(timerId);
});
$(document).on('mouseleave', "#ticker_area .first",function(){
    moveText();
});

こちらの大枠の説明はこちらをご覧下さい
簡単!要素追加時のクリックイベント登録
onイベントに
「mouseenter」マウスが当たったときに「clearInterval(timerId);」Intervalを停止
「mouseleave」マウスが離れたときに「moveText()」テキストアニメーションをスタート
という処理を加えました。
この処理マウスが当たると停止し離れるとその場からスタートするようになりました。

以上で作り方になります。
みなさんも参考にして作ってみてください


Page top