JavaScript
JavaScriptに連動して動きが決まっているパーツもあります。

data-scroll

スクロールされたらbodyタグにdata-scroll="true"が設定されます。.js-mvが存在する場合は、そこのクラスの領域を超えたタイミングでスクロール判定となります。

jQuery(window).on('scroll', function() {
	let length = 100;
	if (jQuery('.js-mv').length) {
		length = jQuery('.js-mv').innerHeight();
	}
	if (length < jQuery(this).scrollTop()) {
		jQuery('body').attr('data-scroll', 'true');
	} else {
		jQuery('body').attr('data-scroll', 'false');
	}
});

data-loading

画面が読み込まれたらbodyタグにdata-loading="true"が設定されます。読み込みが終わらなくても3秒後には解除されます。

jQuery("body")
	.delay(3000)
	.queue(function() {
		jQuery(this)
			.attr("data-loading", "true")
			.dequeue();
	});
jQuery(window).on("load", function() {
	jQuery("body").attr("data-loading", "true");
});

使用例

<div class="c-loading">
	<div class="c-loading__content">loading...</div>
</div>

.js-file

ファイルが読み込まれると.c-file__resultに結果(ファイル名)が表示されます。

jQuery(".js-file").change(function() {
	jQuery(this)
		.siblings(".c-file__result")
		.show();
	jQuery(this)
		.siblings(".c-file__result")
		.text(jQuery(this).val());
});

使用例

<div class="c-file">
	<label class="c-file__label" for="your-file">ファイル添付</label>
	<input type="file" name="your-file" id="your-file" class="c-file__input js-file" />
	<span class="c-file__result"></span>
</div>

.js-drawer

.js-drawerがクリックされるとdata-target属性で指定したクラスに.is-checkedが付与されます。

jQuery(".js-drawer").on("click", function(e) {
	e.preventDefault();
	let targetClass = jQuery(this).attr("data-target");
	jQuery("." + targetClass).toggleClass("is-checked");
	return false;
});

使用例

<div class="c-drawer">
	<div class="c-drawer__icon js-drawer for-drawer01" data-target="for-drawer01">
		<div class="c-drawer__bars">
			<span class="c-drawer__bar"></span>
			<span class="c-drawer__bar"></span>
			<span class="c-drawer__bar"></span>
		</div>
	</div>
	<div class="c-drawer__close js-drawer for-drawer01" data-target="for-drawer01"></div>
	<div class="c-drawer__content for-drawer01">コンテンツ部分</div>
</div>

.js-drawer-close

.js-drawer-close内のa要素がクリックされるとドロワーが閉じます。

jQuery(".js-drawer-close a").on("click", function(e) {
	e.preventDefault();
	jQuery(this)
		.parents(".js-drawer-close")
		.parent()
		.toggleClass("is-checked");
	return false;
});

使用例

<div class="c-drawer">
	<div class="c-drawer__icon js-drawer">
		<div class="c-drawer__bars">
			<span class="c-drawer__bar"></span>
			<span class="c-drawer__bar"></span>
			<span class="c-drawer__bar"></span>
		</div>
	</div>
	<div class="c-drawer__close js-drawer"></div>
	<div class="c-drawer__content js-drawer-close">コンテンツ部分</div>
</div>

.js-modal

.js-modalがクリックされると、data-targetに指定したコンテンツに.is-checkedが付与されます。

jQuery(".js-modal").on("click", function(e) {
	e.preventDefault();
	let target = jQuery(this).attr("data-target");
	jQuery("#" + target).toggleClass("is-checked");
	return false;
});

使用例

<a href="" class="c-btn js-modal" data-target="for-modal">モーダルを開く</a>
<div id="for-modal" class="c-modal">
	<div class="c-modal__content">
		<p>モーダルのコンテンツ</p>
	</div>
	<div class="c-modal__close js-modal" data-target="for-modal"></div>
</div>

.js-accordion

.js-accordionがクリックされると、自身に.is-checkedが付与されて.js-accordion-contentの表示/非表示が切り替わります。

jQuery(".js-accordion").on("click", function(e) {
	e.preventDefault();
	jQuery(this)
		.siblings(".js-accordion-content")
		.slideToggle(500);
	jQuery(this)
		.parent(".c-accordion")
		.toggleClass("is-checked");
	return false;
});

使用例

<div class="c-accordion">
	<div class="c-accordion__title js-accordion">タイトル</div>
	<div class="c-accordion__content js-accordion-content">
		コンテンツ部分
	</div>
</div>

.js-tab

.js-tabがクリックされると、.is-checkedの切り替えと、data-targetに指定したコンテンツを表示します。

jQuery(".js-tab").on("click", function(e) {
	e.preventDefault();
	jQuery(this)
		.parent()
		.children()
		.removeClass("is-checked");
	jQuery(this).addClass("is-checked");
	let target = jQuery(this).attr("data-target");
	jQuery("#" + target)
		.parent()
		.children()
		.removeClass("is-checked");
	jQuery("#" + target).addClass("is-checked");
	return false;
});

使用例

<div class="c-tab">
	<nav class="c-tab__nav">
		<div class="c-tab__item js-tab is-checked" data-target="for-tab1">タブ1</div>
		<div class="c-tab__item js-tab" data-target="for-tab2">タブ2</div>
		<div class="c-tab__item js-tab" data-target="for-tab3">タブ3</div>
	</nav>
	<div class="c-tab__contents">
		<div id="for-tab1" class="c-tab__content is-checked">
			タブ1のコンテンツ
		</div>
		<div id="for-tab2" class="c-tab__content">
			タブ2のコンテンツ
		</div>
		<div id="for-tab3" class="c-tab__content">
			タブ3のコンテンツ
		</div>
	</div>
</div>

スムーススクロール

ページ内リンクをクリックされた時に300のスピードで移動します。固定ヘッダーがある場合は、.l-headerの分の高さが考慮されます。

jQuery('a[href^="#"]').click(function() {
	let header = jQuery(".l-header").height();
	let speed = 300;
	let id = jQuery(this).attr("href");
	let target = jQuery("#" == id ? "html" : id);
	let position = jQuery(target).offset().top - header;
	if ("fixed" !== jQuery(".l-header").css("position")) {
		position = jQuery(target).offset().top;
	}
	if (0 > position) {
		position = 0;
	}
	jQuery("html, body").animate(
		{
			scrollTop: position
		},
		speed
	);
	return false;
});

パララックス

画面に登場した時に.js-animが指定されたコンテンツに.is-animクラスを付与します。

const parallaxOptions = { root: null, rootMargin: "0px", threshold: [0.25] };
var parallaxItems = [].slice.call(document.querySelectorAll(".js-anim"));
let parallaxItemObserver = new IntersectionObserver(function(entries, observer) {
	entries.forEach(function(entry) {
		if (entry.isIntersecting) {
			let parallaxItem = entry.target;
			parallaxItem.classList.add("is-anim");
			parallaxItemObserver.unobserve(parallaxItem);
		}
	});
}, parallaxOptions);

parallaxItems.forEach(function(parallaxItem) {
	parallaxItemObserver.observe(parallaxItem);
});

使用例

<div class="js-anim u-fadein-up">FadeIn UP</div>

スマホのみ電話リンク

スマホ時のみ電話リンクにします。

let ua = navigator.userAgent;
if (ua.indexOf("iPhone") < 0 && ua.indexOf("Android") < 0) {
	jQuery('a[href^="tel:"]')
		.css("cursor", "default")
		.on("click", function(e) {
			e.preventDefault();
		});
}

使用例

<a href="tel:00000000000">000-0000-0000</a>

LazyLoad

表示エリアに入ったら画像を読み込みます。Google推奨のIntersectionObserverを使用した方法を取り入れました。(https://developers.google.com/web/fundamentals/performance/lazy-loading-guidance/images-and-video/?hl=ja

const lazyOptions = { root: null, rootMargin: "0px", threshold: [0] };
var lazyItems = [].slice.call(document.querySelectorAll(".js-lazy"));
lazyItems.forEach(function(lazyItem) {
	lazyItem.setAttribute("data-src", lazyItem.src);
	lazyItem.src = "";
});
let lazyItemObserver = new IntersectionObserver(function(entries, observer) {
	entries.forEach(function(entry) {
		if (entry.isIntersecting) {
			let lazyItem = entry.target;
			if (lazyItem.dataset.hasOwnProperty("src")) {
				lazyItem.src = lazyItem.dataset.src;
			}
			if (lazyItem.dataset.hasOwnProperty("srcset")) {
				lazyItem.srcset = lazyItem.dataset.srcset;
			}
			lazyItem.classList.remove("js-lazy");
			lazyItemObserver.unobserve(lazyItem);
		}
	});
}, lazyOptions);

lazyItems.forEach(function(lazyItem) {
	lazyItemObserver.observe(lazyItem);
});
loading...