PageSourceSearch

https://www.wakura.or.jp/assets/js/common.js

js wakura.or.jp collected 2026-09-24 21:00:17 UTC 16,159 bytes, 584 lines download raw bytes

1'use strict';
2
3
4// ======================================================
5// 375px未満のものには死んでもらう。
6// ======================================================
7!(function () {
8	const viewport = document.querySelector('meta[name="viewport"]');
9
10	function switchViewport() {
11		const value =
12			window.outerWidth > 375 ?
13			'width=device-width,initial-scale=1' :
14			'width=375';
15		if (viewport.getAttribute('content') !== value) {
16			viewport.setAttribute('content', value);
17		}
18	}
19	addEventListener('resize', switchViewport, false);
20	switchViewport();
21
22	function switchViewport2() {
23		const value2 =
24			window.outerWidth < 1920 ?
25			'width=device-width,initial-scale=1' :
26			'width=1920';
27		if (viewport.getAttribute('content') !== value2) {
28			viewport.setAttribute('content', value2);
29		}
30	}
31	addEventListener('resize', switchViewport2, false);
32	switchViewport2();
33})();
34
35// スクロールアニメーション
36let scrollPx = window.pageYOffset;
37let scrollFlag = false;
38let nowscrollPx = window.pageYOffset;
39
40const element = document.getElementById('header');
41
42function scrollTranslate() {
43	if (!scrollFlag) {
44		window.requestAnimationFrame(function () {
45			scrollFlag = false;
46			scrollPx = window.pageYOffset;
47			if (scrollPx < 20) {
48				element.style.transform = 'translateY(0)';
49				nowscrollPx = scrollPx;
50			} else {
51				if (window.matchMedia('(max-width: 770px)').matches) {
52					element.style.transform = 'translateY(-80px)';
53				} else if (window.matchMedia('(min-width:771px)').matches) {
54					element.style.transform = 'translateY(-42px)';
55				}
56			}
57		})
58		scrollFlag = true;
59	}
60	nowscrollPx = scrollPx;
61}
62
63window.addEventListener('scroll', function () {
64	if (window.matchMedia('(max-width: 770px)').matches) {
65		//スマホ処理
66		if (scrollPx < 120) {
67			scrollPx = window.pageYOffset;
68			element.style.transform = 'translateY(0)';
69			setTimeout(function () {
70				nowscrollPx = scrollPx;
71			}, 1000);
72		} else {
73			scrollPx = window.pageYOffset;
74			scrollPx = window.pageYOffset;
75			if (scrollPx <= nowscrollPx) {
76				// scrollTranslate();
77				element.style.transform = 'translateY(0)';
78				setTimeout(function () {
79					nowscrollPx = scrollPx;
80				}, 1000);
81			} else if (scrollPx > nowscrollPx) {
82				element.style.transform = 'translateY(-240px)';
83				setTimeout(function () {
84					nowscrollPx = scrollPx;
85				}, 1000);
86			}
87		}
88	} else if (window.matchMedia('(min-width:771px)').matches) {
89		//PC処理
90		if (scrollPx < 120) {
91			scrollPx = window.pageYOffset;
92			element.style.transform = 'translateY(0)';
93			setTimeout(function () {
94				nowscrollPx = scrollPx;
95			}, 1000);
96		} else {
97			scrollPx = window.pageYOffset;
98			scrollPx = window.pageYOffset;
99			if (scrollPx <= nowscrollPx) {
100				// scrollTranslate();
101				element.style.transform = 'translateY(0)';
102				setTimeout(function () {
103					nowscrollPx = scrollPx;
104				}, 1000);
105			} else if (scrollPx > nowscrollPx) {
106				element.style.transform = 'translateY(-240px)';
107				setTimeout(function () {
108					nowscrollPx = scrollPx;
109				}, 1000);
110			}
111		}
112	}
113}, {
114	passive: true
115});
116
117
118// ======================================================
119// ハンバーガーちゃん
120// https://codepen.io/tak-dcxi/pen/MWjzyjO
121// ======================================================
122const attachEvent = (element, event, handler, options) => {
123	element.addEventListener(event, handler, options);
124	return {
125		unsubscribe() {
126			element.removeEventListener(event, handler);
127		}
128	};
129};
130
131const backfaceFixed = (fixed) => {
132	/**
133	 * 表示されているスクロールバーとの差分を計測し、背面固定時はその差分body要素に余白を生成する
134	 */
135	const scrollbarWidth = window.innerWidth - document.body.clientWidth;
136	document.body.style.paddingRight = fixed ? `${scrollbarWidth}px` : "";
137
138	/**
139	 * 背面固定する対象を決定する
140	 */
141	const scrollingElement =
142		"scrollingElement" in document ?
143		document.scrollingElement :
144		document.documentElement;
145
146	/**
147	 * 背面固定時に変数にスクロール量を格納
148	 */
149	const scrollY = fixed ?
150		scrollingElement.scrollTop :
151		parseInt(scrollingElement.style.top || "0");
152
153	/**
154	 * CSSで背面を固定
155	 */
156	const styles = {
157		height: "100vh",
158		left: "0",
159		overflow: "hidden",
160		position: "fixed",
161		top: `${scrollY * -1}px`,
162		width: "100vw"
163	};
164
165	Object.keys(styles).forEach((key) => {
166		scrollingElement.style[key] = fixed ? styles[key] : "";
167	});
168
169	/**
170	 * 背面固定解除時に元の位置にスクロールする
171	 */
172	if (!fixed) window.scrollTo(0, scrollY * -1);
173};
174
175
176class DrawerMenu {
177	constructor(drawer, button, options) {
178		this.drawerElement = drawer;
179		if (!this.drawerElement)
180			throw TypeError("指定したモーダルメニュー本体のセレクタが見つかりません");
181
182		this.hamburgerElement = button;
183		if (!this.hamburgerElement)
184			throw TypeError("指定したメニューボタンのセレクタが見つかりません");
185
186		const defaultOptions = {
187			headerSelector: "#header",
188			closeTriggerSelector: ".js-drawer-close-trigger", // ボタンとは別にクリック時にメニューを閉じるトリガーとなるセレクタ
189			inertTarget: "main, footer", // 開いている時はこのセレクタを読み上げ対象外にする
190			clickLinkToClose: false, // メニュー内のリンクをクリック時にメニューを閉じるか
191			toggleDuration: 500 // メニューの遷移時間
192		};
193
194
195		const mergedOptions = Object.assign(defaultOptions, options);
196		this.options = mergedOptions;
197
198		this.headerElement = document.querySelector(this.options.headerSelector);
199		if (!this.headerElement) throw TypeError("固定ヘッダーの指定は必須です");
200
201		/**
202		 * ボタンとは別にメニューを閉じるトリガーとなるセレクタの設定
203		 * メニュー内のリンクをクリック時にメニューを閉じる設定をしている場合はメニュー内のa要素をクリック時にもメニューを閉じる
204		 */
205		this.closeTrigger = document.querySelectorAll(
206			this.options.closeTriggerSelector
207		);
208
209		/**
210		 * メニュー内のリンクをクリック時にメニューを閉じる設定をしている場合はメニュー内のa要素をクリック時にもメニューを閉じる
211		 */
212		this.innerLink = this.drawerElement.querySelectorAll(
213			"a:not(.js-ignore-target)"
214		);
215
216		/**
217		 * メニューオープン時に読み上げおよびに対象外にするセレクタの設定
218		 */
219		this.inertTarget = document.querySelectorAll(this.options.inertTarget);
220		if (!this.inertTarget.length)
221			throw TypeError("inert対象のセレクタの指定は必須です");
222
223		/**
224		 * イベントリスナーの設定
225		 */
226		this.buttonHandler = this.handleButtonClick.bind(this);
227		this.closeTriggerHandler = this.handleCloseTriggerClick.bind(this);
228		this.innerLinkHandler = this.handleInnerLinkClick.bind(this);
229		this.keyupHandler = this.handleKeyup.bind(this);
230	}
231
232	init() {
233		/**
234		 * 状態格納で使用する変数
235		 */
236		this.isExpanded = false; // メニューの開閉状態を格納する
237
238		/**
239		 * 初期化時に属性を付与する
240		 */
241		this.prepareAttributes();
242
243		attachEvent(this.hamburgerElement, "click", this.buttonHandler);
244	}
245
246	prepareAttributes() {
247		//this.drawerElement.setAttribute("inert", "");
248
249		this.hamburgerElement.setAttribute(
250			"aria-controls",
251			this.drawerElement.getAttribute("id")
252		);
253		this.hamburgerElement.setAttribute("aria-expanded", true);
254		this.hamburgerElement.setAttribute("aria-haspopup", true);
255
256		this.headerElement.setAttribute("data-drawer-opened", false);
257		document.documentElement.style.setProperty(
258			"--drawer-toggle-duration",
259			`${this.options.toggleDuration}ms`
260		);
261	}
262
263	handleButtonClick(event) {
264		event.preventDefault();
265
266		if (!this.isExpanded) {
267			this.open();
268		} else {
269			this.close();
270		}
271	}
272
273	handleCloseTriggerClick(event) {
274		event.preventDefault();
275		this.close();
276	}
277
278	handleInnerLinkClick(event) {
279		this.close();
280	}
281
282	handleKeyup(event) {
283		if (event.key === "Escape" || event.key === "Esc") this.close();
284	}
285
286	open() {
287		attachEvent(document, "keyup", this.keyupHandler);
288
289		this.closeTrigger.forEach((trigger) => {
290			attachEvent(trigger, "click", this.closeTriggerHandler);
291		});
292
293		if (this.options.clickLinkToClose) {
294			this.innerLink.forEach((link) => {
295				attachEvent(link, "click", this.innerLinkHandler);
296			});
297		}
298
299		this.changeAttribute(true);
300		backfaceFixed(true);
301
302		setTimeout(() => {
303			this.isExpanded = true;
304		}, 100);
305	}
306
307	close() {
308		attachEvent(
309			this.hamburgerElement,
310			"click",
311			this.buttonHandler
312		).unsubscribe();
313
314		attachEvent(document, "keyup", this.keyupHandler).unsubscribe();
315
316		this.closeTrigger.forEach((trigger) => {
317			attachEvent(trigger, "click", this.closeTriggerHandler).unsubscribe();
318		});
319
320		if (this.options.clickLinkToClose) {
321			this.innerLink.forEach((link) => {
322				attachEvent(link, "click", this.innerLinkHandler).unsubscribe();
323			});
324		}
325
326		this.changeAttribute(false);
327		backfaceFixed(false);
328
329		setTimeout(() => {
330			attachEvent(this.hamburgerElement, "click", this.buttonHandler);
331			this.isExpanded = false;
332		}, this.options.toggleDuration);
333	}
334
335	changeAttribute(expanded) {
336		if (expanded) {
337			this.drawerElement.removeAttribute("inert");
338		} else {
339			this.drawerElement.setAttribute("inert", "");
340		}
341
342		this.hamburgerElement.setAttribute("aria-expanded", expanded);
343		this.headerElement.setAttribute("data-drawer-opened", expanded);
344
345		this.inertTarget.forEach((element) => {
346			if (expanded) {
347				element.setAttribute("inert", "");
348			} else {
349				element.removeAttribute("inert");
350			}
351		});
352	}
353}
354window.addEventListener("DOMContentLoaded", function () {
355	const drawerElement = document.querySelector("#js-drawer");
356	const hamburgerElement = document.querySelector("#js-hamburger-button");
357	const attachDrawer = new DrawerMenu(drawerElement, hamburgerElement);
358	attachDrawer.init();
359});
360
361// ======================================================
362// Androidの時は、androidクラスをつける。
363// ======================================================
364if (navigator.userAgent.indexOf('Android') > 0) {
365	let android = true;
366	document.addEventListener('DOMContentLoaded', function () {
367		// const body = document.getElementsByTagName('body')[0];
368		document.body.classList.add('android');
369	});
370} else {
371	let android = false;
372}
373
374// ======================================================
375// DOMツリーまで構築されたら発火(こっちのが早い!)
376// ======================================================
377document.addEventListener('DOMContentLoaded', function () {
378
379}, false);
380
381// ======================================================
382// 画像も読み込まれたら発火
383// ======================================================
384window.addEventListener("load", function () {
385
386}, false);
387
388// ======================================================
389// inview設定
390// https://www.6666666.jp/html/20191212/
391// ======================================================
392// window.addEventListener('load', function () {
393	const observer = new IntersectionObserver(function (entries) {
394		for (let i = 0; i < entries.length; i++) {
395			if (entries[i].intersectionRatio <= 0) continue;
396			showElm(entries[i].target);
397		}
398	}, {
399		// オプション
400		rootMargin: '-5% 0% -5% 0%'
401	});
402
403	const elements = document.querySelectorAll('[data-san]');
404	for (let i = 0; i < elements.length; i++) {
405		observer.observe(elements[i]);
406	}
407
408	function showElm(e) {
409		if (e.getAttribute('data-san') == 'fade') {
410			e.classList.add('fade');
411		} else if (e.getAttribute('data-san') == 'img') {
412			e.classList.add('img');
413		} else {
414			e.classList.add('inview');
415		}
416		observer.unobserve(e);
417	}
418
419	const observersns = new IntersectionObserver(function (entries) {
420		for (let i = 0; i < entries.length; i++) {
421			if (entries[i].intersectionRatio <= 0) continue;
422			showElm(entries[i].target);
423		}
424	}, {
425		// オプション
426		rootMargin: '-5% 0% -5% 0%'
427	});
428
429	const elementsns = document.querySelectorAll('[data-sns]');
430	for (let i = 0; i < elementsns.length; i++) {
431		observer.observe(elementsns[i]);
432	}
433// }, false);
434
435// ======================================================
436// スムーススクロール(jQuery...)
437// ======================================================
438$(function () {
439	//ページとトップ
440	$('.pagetop').click(function () {
441		var objBlock = $("body");
442		if (objBlock.size() > 0) {
443			$('body,html').animate({
444				scrollTop: 0
445			}, 700, 'swing');
446		}
447		return false;
448	});
449
450	$(function () {
451	//$('a[href^="#"]:not(.et_smooth_scroll_disabled)').click(function (e) {
452	$('a[href^="#"]:not(.et_smooth_scroll_disabled)').on('click', function (e) {
453		e.preventDefault();
454		// var objBlock = $("body");
455		// if (objBlock.size() > 0) {
456		// 	$('body,html').animate({
457		// 		scrollTop: 0
458		// 	}, 700, 'swing');
459		// }
460		// return false;
461
462		var speed = 700,
463		href = $(this).attr("href"),
464		target = $(href === "#" || href === "" ? 'html' : href),
465		 position = target.offset().top;
466		$("html, body").animate({scrollTop:position}, speed, "swing");
467		return false;
468
469	});
470	});
471
472	//ページトップボタンスクロール多くなったら
473	$(function () {
474		var topBtn = $('.pagetop');
475		var showFlag = false;
476		topBtn.css('bottom', '-100px');
477		if (navigator.userAgent.match(/(iPhone|iPod|Android.*Mobile)/i)) {
478			//スクロールが200に達したらボタン表示
479			$(window).scroll(function () {
480				if ($(this).scrollTop() > 200) {
481					if (showFlag == false) {
482						showFlag = true;
483						topBtn.stop().animate({
484							'bottom': '90px'
485						}, 600);
486					}
487				} else {
488					if (showFlag) {
489						showFlag = false;
490						topBtn.stop().animate({
491							'bottom': '-100px'
492						}, 200);
493					}
494				}
495			});
496		} else {
497			//  PC・タブレットの場合の処理を記述
498			//  スクロールが200に達したらボタン表示
499			$(window).scroll(function () {
500				if ($(this).scrollTop() > 200) {
501					if (showFlag == false) {
502						showFlag = true;
503						topBtn.stop().animate({
504							'bottom': '70px'
505						}, 600);
506					}
507				} else {
508					if (showFlag) {
509						showFlag = false;
510						topBtn.stop().animate({
511							'bottom': '-100px'
512						}, 200);
513					}
514				}
515			});
516		}
517	});
518
519	$(function () {
520		let url = "";
521		// ハッシュリンク(#)と別ウィンドウでページを開く場合はスルー
522		$('a:not([href^="#"]):not([target])').on('click', function (e) {
523			e.preventDefault(); // ナビゲートをキャンセル
524			url = $(this).attr('href'); // 遷移先のURLを取得
525			if (url !== '') {
526				$('body').addClass('fadeout'); // bodyに class="fadeout"を挿入
527				setTimeout(function () {
528					window.location = url; // 0.8秒後に取得したURLに遷移
529				}, 800);
530			}
531			return false;
532		});
533	});
534});
535
536// =========================================================================================
537
538
539// ======================================================
540// language 言語表示 & プルダウン
541// ======================================================
542$(function () {
543	var target = $('.js_lang_target');
544  let url = location.href.split("/");
545  let url_param = $.inArray('en', url);
546
547  if(url_param != -1){
548	  target.text('English');
549  }
550
551	$('.js_lang_btn').on('click', function (e) {
552		e.preventDefault();
553		$('.js_lang_list').slideToggle();
554	});
555});
556
557
558
559// ======================================================
560// わくたまくんメニュー
561// ======================================================
562$(function () {
563	$('.section__sublink__button').on('click', function (e) {
564		e.preventDefault();
565		if (this.getAttribute('aria-expanded') == 'false') {
566			this.setAttribute('aria-expanded', true);
567		} else {
568			this.setAttribute('aria-expanded', false);
569		}
570	});
571});
572//document.addEventListener("DOMContentLoaded", function() {
573//
574//	const accodion_btn = document.querySelector(".section__sublink__button");
575//	accodion_btn.addEventListener('click', function(e) {
576//		if (this.getAttribute('aria-expanded') == 'false') {
577//			this.setAttribute('aria-expanded', true);
578//		} else {
579//			this.setAttribute('aria-expanded', false);
580//		}
581//	});
582//});
583
584

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.