最終更新日
記事公開日

スクロールを途中で止めて(指定した要素の位置)、YES・NOの選択画面を表示する【jQuery】

スクロールの途中に「YES」or「NO」の選択画面を表示したいの。

その選択肢によって、表示する内容を変えたいんだけど、どうしたらいい?

スクロールの位置を検知して、指定した要素のところに来たら、モーダルを表示するのが良いと思います。

今回は、jQueryとCSSを使った方法を紹介します。

実装する際に注意すべきことが2つあります。

1.YES/NOの選択が終わるまで、スクロールが動かないように画面を固定する必要があります。

2.スマホ(特にiPhone)は指でスクロールした際に勢いがあると、スクロールのストップ位置を超えた場所で止まってしまいます。強制的にポジションを戻す調整が必要です。

DEMO

<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="robots" content="noindex">
<title>DEMO</title>

<!-- jQuery -->
<script src='js/jquery.min.js'></script>

<script>
$(function() {

	var flag = 0;

	// 画面の高さを取得
	var window_height = $(window).height();

	// 最初はモーダルを隠しておく
	$('#modal').hide();

	// スクロールしたときに実行
	$(window).on("scroll", function() {


		// スクロールの座標を取得
		var scroll = $(window).scrollTop();

		// スクロールを止める要素の座標
		var stop = $("#modal_point").offset().top;

		// 画面半分くらいで検知するように微調整
		var adj = window_height / 2;

		// 選択画面の位置までスクロールがきたらモーダルを表示
		if(scroll + window_height > stop + adj) {

			// 一度選択したら、スクロールで戻ってもモーダルを表示しない
			if (flag == 0) {

				flag = 1;

				// スクロールバーを非表示にする
				$('body').css('overflow-y', 'hidden');

				// ゆっくりフェードインしながらモーダルを表示
				$("#modal").fadeIn("slow");
			}
		}

		// デバッグ用(座標ステータスの表示)
		var scroll_y = scroll + window_height;
		var stop_y = stop + adj;
		$('#status').html('スクロールのY軸/bottom座標:' + scroll_y + '<br>' + 'モーダル表示のY軸/top座標:'+ stop_y);

	});


	// YESをクリック
	$("#yes_btn").click(function () {

		// スクロールバーを表示する
	 	$('body').css('overflow-y','auto');

		// モーダルを隠す
		$('#modal').hide();

		// 選択後の内容を隠しておいたマスクを非表示にする
		$('.mask').css('display','none');

		// NOが選択された場合の内容を非表示にしておく
		$('#no').css('display','none');

		// 内容の表示位置まで自動スクロール
		$("html").animate({scrollTop: $('#scroll_point').offset().top});

	});

	// NOボタンをクリック
	$("#no_btn").click(function () {

		// スクロールバーを表示する
	 	$('body').css('overflow-y','auto');

		// モーダルを隠す
		$('#modal').hide();

		// 選択後の内容を隠しておいたマスクを非表示にする
		$('.mask').css('display','none');

		// YESが選択された場合の内容を非表示にしておく
		$('#yes').css('display','none');

		// 内容の表示位置まで自動スクロール
		$("html").animate({scrollTop: $('#scroll_point').offset().top});

	});

});
</script>


<style>

* {
	margin:0;
	padding:0;
}

#container {
	text-align:center;
}

.block1 {
	background:#ffa595;
	height:100vh;
}
.block2 {
	background:#faffc7;
	height:100vh;
}
.block3 {
	background:#a3ffe0;
	height:100vh;
}
.block4 {
	background:#a8d9ff;
	height:100vh;
}

#modal {
	display:none;
	position:fixed;
	top:0;
	left:0;
	width:100%;
	height:100%;
	z-index:10;
	background:rgba(0,0,0,0.8);
}

#modal_inner {
	position:absolute;
	top:50%;
	left:50%;
	transform:translateY(-50%) translateX(-50%);
	background:#fff;
	padding:2em;
	width:60%;
}
#choice_btn {
	display:flex;
	text-align:center;
	justify-content: space-between;
}
#choice_btn div {
	flex-basis:48%;
	color:#fff;
	font-weight:bold;
	font-size:2em;
	padding:2em 0;
}
#yes_btn {
	background:#da0000;
}

#no_btn {
	background:#1e00d7;
}

#choice {
	position:relative;
	height:100%;
}
.mask {
	position:absolute;
	left:0;
	top:0;
	width:100%;
	height:100%;
	background:#fff;
	z-index:6;
}

#yes ,
#no {
	position:absolute;
	top:50%;
	left:50%;
	transform:translateY(-50%) translateX(-50%);
}
#yes span ,
#no span {
	display:block;
	font-size:5em;
	font-weight:bold;
}
#yes span {
	color:red;
}
#no span {
	color:blue;
}

.retry {
	margin:3em;
}
.retry a {
	text-decoration:none;
}

#status {
	position:fixed;
	top:1em;
	right:1em;
	text-align:left;
}

</style>
</head>

<body>

<div id="container">

	<div class="block1"></div>
	
	<div class="block2"></div>

	<!-- 選択肢が表示されるポイント -->
	<div class="block3" id="modal_point">

		<div id="modal">

			<div id="modal_inner">

			    	<div id="choice_btn">
					<div id="yes_btn">YES</div>
					<div id="no_btn">NO</div>
			    	</div>

			</div>

		</div>

	</div>

	<!-- スクロールバーの移動ポイント -->
	<div class="block4" id="scroll_point">

		<div id="choice"> 

			<div class="mask"></div>

			<div id="yes">
				<span>YES</span>が選択されました。
			</div>
			
			<div id="no">
				<span>NO</span>が選択されました。
			</div>

		</div>
	
	</div>

	<div class="retry">
		<a href="scroll_stop.html">もう一度最初から</a>
	</div>

	<div id="status"></div>

</div>

</body>
</html>

関連情報

運営者プロフィール
隊員1号

IT系フリーランスとして10年の経験を持つレスキュー隊。HTML・CSS・JS・PHPなど幅広いスキルを持つ。

詳しいプロフィール