PageSourceSearch

https://gs-hojo-web-ukr.jp/assets/js/functions.js?251205

js gs-hojo-web-ukr.jp collected 2026-09-29 15:26:08 UTC 20,224 bytes, 602 lines download raw bytes

1/* スムーススクロール */
2$(function(){
3  $('a[href^="#"]').click(function(){
4    var adjust = $('header').outerHeight() + 30;
5    var speed = 400;
6    var href= $(this).attr("href");
7    var target = $(href == "#" || href == "" ? 'html' : href);
8    var position = target.offset().top - adjust;
9    $('body,html').animate({scrollTop:position}, speed, 'swing');
10    return false;
11  });
12});
13
14/* アンカーリンクでヘッダー分ずらす */
15$(window).on('load', function() {
16	// ページのURLを取得
17	const url = $(location).attr('href'),
18	// headerの高さを取得してそれに30px追加した値をheaderHeightに代入
19	headerHeight = $('header').outerHeight() + 30;
20
21	// urlに「#」が含まれていれば
22	if(url.indexOf("#") != -1){
23		// urlを#で分割して配列に格納
24		const anchor = url.split("#"),
25		// 分割した最後の文字列(#◯◯の部分)をtargetに代入
26		target = $('#' + anchor[anchor.length - 1]),
27		// リンク先の位置からheaderHeightの高さを引いた値をpositionに代入
28		position = Math.floor(target.offset().top) - headerHeight;
29		// positionの位置に移動
30		$("html, body").animate({scrollTop:position}, 400);
31	}
32});
33
34/* タブ */
35$(function(){
36	if (window.location.hash === "#link") {
37		$('#tab01').prop('checked', true);
38		$('html,body').animate({
39			scrollTop: $('#qa').offset().top
40		}, 'fast');
41	}
42});
43
44/* キーワード挿入 */
45$(document).ready(function() {
46	
47	//よくあるキーワードクリックでフォームへ
48	$('#keyword button').on('click', function() {
49		$('#search-text').val($(this).val());
50	});
51	
52      $('#search-text').on('input', function () {
53        const input = $(this).val();
54        const invalidChar = input.split('').find(c => c.match(/[!"#$%&'()*+,-./:;<=>?@[\\\]^_`{|}~]/));
55        
56        if (invalidChar) {
57          // 無効な文字があれば通知して削除
58         $('#message').text(`"${invalidChar}" の文字は使えません、入力が制限されています。`);
59          $(this).val(input.replace(/[!"#$%&'()*+,-./:;<=>?@[\\\]^_`{|}~]/g, ''));
60        } else {
61          $('#message').text('');
62        }
63      });
64
65      // サニタイズ関数:HTMLエスケープ
66      function sanitize(value) {
67        return $('<div>').text(value).html();
68      }
69
70      // クエリパラメータを取得してオブジェクト化
71      const queryParams = new URLSearchParams(window.location.search);
72      const search = queryParams.get('search') || '';
73
74      // サニタイズしてフォームに反映
75      if (search) $('#search-text').val(sanitize(search));
76
77      // performSearch関数
78      function performSearch(search) {
79        const sanitizedWord = sanitize(search); // ワードをサニタイズ
80        $('#output').html(`検索結果`);
81
82        let searchResult = [];
83        let searchText = $('#search-text').val();
84        let searchResultList = $('#search-result__list ul');
85        searchResultList.empty();
86        let searchResultScroll = $('#result-scroll');
87        $('.no-result').remove();
88
89        let targetAreaItems = $('.search-target');
90        let resultNumber = 0;
91
92        if (searchText !== '') {
93            targetAreaItems.each(function() {
94                let targetText = $(this).text();
95                let targetTextHtml = $(this).html();
96                if (targetText.indexOf(searchText) !== -1) {
97                    searchResult.push(targetTextHtml);
98                }
99            });
100
101            $.each(searchResult, function(index, result) {
102                searchResultList.append('<li>' + result + '</li>');
103                resultNumber = searchResultList.find('li').length;
104            });
105            $('.faq #target-area').hide();
106        }
107
108        if (resultNumber === 0) {
109            searchResultList.append('<li class="no-result">該当のキーワードを含んだFAQはありません。</li>');
110        }
111
112        searchResultScroll.scrollTop(0);
113		
114        // GA4
115        if (typeof gtag === 'function') {
116            gtag('event', 'search', {
117                'search_term': searchText
118            });
119        }
120		
121    }
122
123      // クエリパラメータに"search"が存在する場合、検索を実行
124      if (search) {
125        performSearch(search);
126      }
127
128	
129    $(document).on('click', '#searchBtn', performSearch);
130	//$(document).on('click', '#searchBtn-faq1', performSearch);
131	//$(document).on('click', '#searchBtn-faq2', performSearch);
132	//$(document).on('click', '#searchBtn-faq3', performSearch);
133
134    $('#search-text').on('keypress', function(e) {
135        if (e.which === 13) {
136            performSearch();
137        }
138    });
139});
140
141/* メール */
142$(document).ready(function() {
143	$('#link-mail').on('click', function(event) {
144	sendGA4Event();
145
146	function sendGA4Event() {
147		if (typeof gtag === 'function') {
148			gtag('event', 'email_click', {
149				'mail_type': 'データ送受信'
150			});
151		}
152	}
153	});
154});
155
156/* ページ先頭 */
157$('.pagetop').on('click', function (e) {
158  e.preventDefault();
159  $('body, html').animate({
160	scrollTop: 0
161  }, 500);
162  return false;
163});
164$('.pagetop').hide();
165$(window).on('scroll resize', function () {
166  // 表示/非表示
167  if ($(this).scrollTop() > $('header').innerHeight()) {
168	$('.pagetop').fadeIn(500);
169
170  } else {
171	$('.pagetop').fadeOut(250);
172
173  }
174});
175
176/* スマホメニュー表示 */
177$(function () {
178	$('.sp_nav').on("click", function () {
179		$('nav').toggleClass('open');
180	});
181});
182
183/* スマホメニュー表示時 class="fixed"追加でCSSで固定 */
184$(function(){
185	var state = false;
186	var pos;
187	$('.sp_nav').click(function(){
188		if (state == false) {
189			pos = $(window).scrollTop();
190			$('body').addClass('fixed').css({'top': -pos});
191			state = true;
192		} else {
193			$('body').removeClass('fixed').css({'top': 0});
194			window.scrollTo(0, pos);
195			state = false;
196		}
197	});
198});
199
200/* レポート一覧 プルダウンフィルター */
201$(document).ready(function () {
202  updateFilteredList();
203
204  $('#yearFilter, #genreFilter').on('change', function () {
205    updateFilteredList();
206  });
207
208  function updateFilteredList() {
209    var selectedYear = $('#yearFilter').val();
210    var selectedGenre = $('#genreFilter').val();
211
212    $('.filtered-item').hide();
213    $('.filtered-item').fadeIn();
214
215    if (selectedYear !== 'all') {
216      $('.filtered-item')
217        .filter(function () {
218          return $(this).find('.year').text() !== selectedYear;
219        })
220        .hide();
221    }
222
223    if (selectedGenre !== 'all') {
224      $('.filtered-item')
225        .filter(function () {
226          return $(this).find('.genre').text() !== selectedGenre;
227        })
228        .hide();
229    }
230      
231    if (selectedGenre == 'all' && selectedYear == 'all') {
232        $('.order').fadeIn();
233    } else {
234        $('.order').hide();
235    }
236
237    $('.filtered-item:visible').fadeIn();
238  }
239});
240
241/* 他言語切り替えボタン */
242$(function () {
243  var scrollBtn = $('#scroll-lang');
244  scrollBtn.hide();
245
246  $(window).on('scroll', function () {
247    if ($(this).scrollTop() > 150) {
248      scrollBtn.fadeIn();
249    } else {
250      scrollBtn.fadeOut();
251    }
252  });
253});
254
255/* アコーディオン */
256$(function(){
257  // .js-accordion_titleをクリックすると
258  //$('.js-accordion_title').click(function(){
259  $(document).on('click', '.js-accordion_title', function() {
260    // クリックした次の要素を展開
261    $(this).next('.js-accordion_inner').slideToggle();
262    // 展開するときjs-accordion_titleクラスにopenクラスを追加してアイコンを回転
263    $(this).toggleClass("open");
264  });
265});
266
267$(function () {
268  // URLのハッシュ部分(id)を取得
269  const urlHash = location.hash;
270  // そのidを持つ要素がなかったら処理を抜ける
271  if (!$(urlHash).length) return;
272
273  // アコーディオンの要素を開く処理
274  $(urlHash)
275    .find('.accordion-data_title')
276    .addClass('open')
277    .next('.js-accordion_inner').slideToggle();
278});
279
280/* SPメニュー */
281window.addEventListener("DOMContentLoaded", () => {
282  // ページ内リンクの取得
283  const anchorLinks = document.querySelectorAll('a[href^="#"]');
284  // NodeList を Array に変換
285  const anchorLinksArr = Array.from(anchorLinks);
286  // ハンバーガーメニューボタンの取得
287  const btn = document.querySelector("#js-buttonHamburger");
288  // オーバーレイの取得
289  const overlay = document.querySelector("#js-overlay");
290  // ページ内リンクのクリックイベントリスナー
291  anchorLinksArr.forEach((link) => {
292    link.addEventListener("click", (e) => {
293      e.preventDefault(); // デフォルトの挙動をキャンセル
294      const targetId = link.hash;
294 // リンク先の要素のIDを取得
295      const targetElement = document.querySelector(targetId); // リンク先の要素を取得
296      const targetoffsetTop =
297        window.pageYOffset + targetElement.getBoundingClientRect().top; // スクロール量を取得
298      // メニューが開いている場合は閉じる
299      if (btn.ariaExpanded == "true") {
300        btn.ariaExpanded = false;
301        overlay.classList.remove("active"); // オーバーレイを非表示にする
302      }
303      // 全てのページ内リンク要素の ariaExpanded を false にする
304      anchorLinksArr.forEach((link) => {
305        link.ariaExpanded = false;
306      });
307      MicroModal.close("modal-1"); // モーダルを閉じる
308      // スムーススクロール
309      window.scrollTo({
310        top: targetoffsetTop,
311        behavior: "smooth", // スムーススクロールを有効にする
312      });
313    });
314  });
315  // ハンバーガーメニューボタンのクリックイベントリスナー
316  btn.addEventListener("click", function () {
317    if (btn.ariaExpanded == "false") {
318      btn.ariaExpanded = true;
319      MicroModal.show("modal-1", {
320        disableScroll: true, // スクロールを無効化
321        awaitOpenAnimation: true, // 開くアニメーションの完了を待つ
322      });
323      overlay.classList.add("active"); // オーバーレイを表示する
324    } else {
325      btn.ariaExpanded = false;
326      MicroModal.close("modal-1", {
327        awaitCloseAnimation: true, // 閉じるアニメーションの完了を待つ
328      });
329      overlay.classList.remove("active"); // オーバーレイを非表示にする
330    }
331  });
332  // オーバーレイのクリックイベントリスナー
333  overlay.addEventListener("click", function () {
334    btn.ariaExpanded = false;
335    MicroModal.close("modal-1", {
336      awaitCloseAnimation: true, // 閉じるアニメーションの完了を待つ
337    });
338    overlay.classList.remove("active"); // オーバーレイを非表示にする
339  });
340  // ESCキーが押された時の処理
341  document.addEventListener("keydown", function (e) {
342    if (e.key === "Escape") {
343      btn.ariaExpanded = false;
344      MicroModal.close("modal-1", {
345        awaitCloseAnimation: true, // 閉じるアニメーションの完了を待つ
346      });
347      overlay.classList.remove("active"); // オーバーレイを非表示にする
348    }
349  });
350});
351
352/* 採択情報一覧 プルダウンフィルター */
353$(document).ready(function () {
354  // 初期化時に実行
355  saitakuFilteredList();
356
357  // フィルターの変更イベント
358  $('#countryFilter, #jigyouFilter, #kouboFilter, #fieldFilter').on('change', function () {
359    saitakuFilteredList().then(checkHiddenItems);
360  });
361
362  // saitakuFilteredListをPromise対応に
363  function saitakuFilteredList() {
364	$('#noitem').hide();
365    return new Promise((resolve) => {
366      var selectedCountry = $('#countryFilter').val();
367      var selectedJigyou = $('#jigyouFilter').val();
368      var selectedKoubo = $('#kouboFilter').val();
369      var selectedField = $('#fieldFilter').val();
370
371      $('.filtered-item').hide();
372      $('.filtered-item').fadeIn();
373
374      /*if (selectedCountry !== 'all') {
375        $('.filtered-item')
376          .filter(function () {
377            // .country要素のテキストを取得
378            const countryText = $(this).find('.country').text();
379
380            // 国名を区切り文字("・")で分割
381            const countries = countryText.split(/・|、|(|)/);
382
383            // selectedCountryがリストに完全一致するかをチェック
384            return !countries.includes(selectedCountry);
385          })
386          .hide();
387      }*/
388      
389      if (selectedCountry !== 'all') {
390      // <option> から国名リストを取得
391      const countryList = $('#countryFilter option')
392        .map(function () {
393          return $(this).val().trim(); // 各オプションの値を取得
394        })
395        .get();
396
397      $('.filtered-item')
398        .filter(function () {
399          const countryText = $(this).find('.country').text().trim();
400
401          // 国名リストから一致する国を抽出(完全一致チェック)
402          const matchedCountries = countryList.filter(country => {
403            // 正規表現で完全一致をチェック
404            const regex = new RegExp(`(^|・|、|(|))${country}($|・|、|(|))`);
405            return regex.test(countryText);
406          });
407
408          // 選択された国がマッチしなければ非表示
409          return !matchedCountries.includes(selectedCountry);
410        })
411        .hide();
412      }
413
414
415      if (selectedJigyou !== 'all') {
416        $('.filtered-item')
417          .filter(function () {
418            return $(this).find('.jigyou').text() !== selectedJigyou;
419          })
420          .hide();
421      }
422      
423      if (selectedKoubo !== 'all') {
424        $('.filtered-item')
425          .filter(function () {
426            return $(this).find('.koubo').text() !== selectedKoubo;
427          })
428          .hide();
429      }
430      
431      if (selectedField !== 'all') {
432      $('.filtered-item')
433        .filter(function () {
434          return !$(this).find('.field').text().includes(selectedField);
435        })
436        .hide();
437      }
438
439      // 可視要素を取得
440      const visibleItems = $('.filtered-item:visible');
441
442      if (visibleItems.length === 0) {
443        // 可視要素がない場合でもresolve
444        resolve();
445      } else {
446        // フェードインが完了したタイミングでresolve
447        visibleItems.fadeIn(() => {
448          resolve();
449        });
450      }
451    });
452  }
453
454  function checkHiddenItems() {
455    // すべてのリストアイテムを取得し、非表示かどうかを確認
456    const allHidden = $('.filtered-item').toArray().every(item => $(item).css('display') === 'none');
457
458    // メッセージの更新
459    if (allHidden) {
460		$('#noitem').text('該当の採択情報はありません。');
461		$('#noitem').fadeIn();
462    } else {
463      $('#noitem').hide();
464    }
465  }
466});
467
468
469/* タブ切り替え */
470$(document).ready(function () {
471    // URLのパラメータを取得
472    const params = new URLSearchParams(window.location.search);
473    const activeTab = params.get('tab') || 'tab-fs'; // デフォルトはtab1
474
475    // タブ切り替え関数
476    function activateTab(tabId) {
477        $('.tab').removeClass('active');
478        $(`.tab[data-tab="${tabId}"]`).addClass('active');
479        $('.tab-content').removeClass('active');
480        $(`#${tabId}`).addClass('active');
481    }
482
483    // 初期表示
484    activateTab(activeTab);
485
486    // data-tab属性を持つ要素のクリックイベント
487    $('[data-tab]').click(function () {
488        const tabId = $(this).data('tab');
489        activateTab(tabId);
490
491        // URLパラメータを更新
492        const newUrl = new URL(window.location);
493        newUrl.searchParams.set('tab', tabId);
494        history.replaceState(null, '', newUrl);
495    });
496});
497
498/* FAQタブ切り替え */
499$(document).ready(function () {
500    // URLのパラメータを取得
501    const faqParams = new URLSearchParams(window.location.search);
502    const activeFaqTab = faqParams.get('faq-tab') || 'faq-tab1'; // デフォルトはfaq-tab01
503
504    // タブ切り替え関数
505    function activateFaqTab(tabId) {
506        $('.faq-tab').removeClass('active');
507        $(`.faq-tab[data-tab-faq="${tabId}"]`).addClass('active');
508        $('.faq-tab-content').removeClass('active');
509        $(`#${tabId}`).addClass('active');
510    }
511
512    // 初期表示
513    activateFaqTab(activeFaqTab);
514
515    // data-tab-faq属性を持つ要素のクリックイベント
516    $('[data-tab-faq]').click(function () {
517        const tabId = $(this).data('tab-faq');
518        activateFaqTab(tabId);
519
520        // URLパラメータを更新
521        const newUrl = new URL(window.location);
522        newUrl.searchParams.set('faq-tab', tabId);
523        history.replaceState(null, '', newUrl);
524    });
525});
526
527/* 事業全体の流れのフェードイン */
528document.addEventListener("DOMContentLoaded", function () {
529
530    const options = {
531      root: null, // ビューポートをルートとして使用
532      rootMargin: "0% 0%", // 交差の有効範囲をpx % で指定
533      threshold: 0.5, // 要素がどの程度見えたら検知するかの割合。50%で検知させる場合は0.5を指定。(最小0.0〜最大1.0)
534    };
535
536    const flowElement = document.getElementById("flow");
537    const objectElement = document.getElementById("flow-image");
538
539    // Intersection Observerの設定
540    const observer = new IntersectionObserver((entries, observer) => {
541        entries.forEach(entry => {
542            if (entry.isIntersecting) {
543                // flowが表示されたらSVGにクラスを付与
544                addFadeInToSVG();
545                observer.unobserve(entry.target); // 1回だけ動作するように監視解除
546            }
547        });
548    }, options);
549
550    // 監視する要素を設定
551    observer.observe(flowElement);
552
553    // SVG内のetc-group要素にfadeInクラスを追加する関数
554    function addFadeInToSVG() {
555        if (objectElement.contentDocument) {
556            // SVGがすでにロードされている場合
557            applyFadeInClass();
558        } else {
559            // SVGがまだロードされていない場合
560            objectElement.addEventListener("load", applyFadeInClass);
561        }
562    }
563
564    // SVG内の要素にクラスを付与する関数
565    function applyFadeInClass() {
566        const svgDoc = objectElement.contentDocument; // SVGの内部DOMにアクセス
567        const targetElement = svgDoc.getElementById("etc-group"); // SVG内の要素を取得
568
569        if (targetElement) {
570            targetElement.classList.add("fadeIn"); // クラスを付与
571        } else {
572            //console.error("ID 'etc-group' の要素が見つかりません。");
573        }
574    }
575});
576
577/* =============================
578   ヒーローセクションバナー
579============================= */
580document.addEventListener('DOMContentLoaded', function() {
581    const tabButtons = document.querySelectorAll('.tab-button');
582
583    tabButtons.forEach(button => {
584        button.addEventListener('click', function() {
585            const targetTab = this.getAttribute('data-tab');
586
587            // すべてのタブボタンから active クラスを削除
588            tabButtons.forEach(btn => btn.classList.remove('active'));
589
590            // クリックされたタブボタンに active クラスを追加
591            this.classList.add('active');
592
593            // すべてのタブコンテンツから active クラスを削除
594            document.querySelectorAll('.banner-tab-content').forEach(content => {
595                content.classList.remove('active');
596            });
597
598            // 対応するタブコンテンツに active クラスを追加
599            document.getElementById(targetTab).classList.add('active');
600        });
601    });
602});

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.