PageSourceSearch

https://oumasan-gem.com/wp-content/themes/cocoon-master/javascript.js?ver=7.1.2&fver=20260827071124

js oumasan-gem.com collected 2026-10-04 04:45:12 UTC 15,683 bytes, 448 lines download raw bytes

1/**
2 * Cocoon WordPress Theme
3 * @author: yhira
4 * @link: https://wp-cocoon.com/
5 * @license: http://www.gnu.org/licenses/gpl-2.0.html GPL v2 or later
6 */
7/////////////////////////////////
8// JavaScriptコード
9/////////////////////////////////
10
11( function ( $ ) {
12  /////////////////////////////////
13  //TOPへ戻るボタン
14  /////////////////////////////////
15  let prevScrollTop = -1;
16  const $window = $( window );
17  $window.scroll( () => {
18    //最上部から現在位置までの距離を取得して、変数[scrollTop]に格納
19    const scrollTop = $window.scrollTop();
20    const threashold = 600;
21    const s1 = prevScrollTop > threashold;
22    const s2 = scrollTop > threashold;
23
24    // スレッショルドを跨いだ時のみ処理をする
25    if ( s1 ^ s2 ) {
26      if ( s2 ) {
27        // トップへ戻るボタンが見えている時
28        $( '.body' ).addClass( 'go-to-top-visible' );
29
30        // //[.go-to-to]をゆっくりフェードインする
31        // $('.go-to-top').fadeIn('slow');
32      } else {
33        //トップへ戻る間だけ追加したクラスを除去
34        $( '.go-to-top-common' ).removeClass( 'go-to-top-up' );
35        // トップへ戻るボタンが見えていない時
36        $( '.body' ).removeClass( 'go-to-top-visible' );
37
38        // //それ以外だったらフェードアウトする
39        // $('.go-to-top').fadeOut('slow');
40      }
41    }
42
43    prevScrollTop = scrollTop;
44  } );
45
46  //ボタン(.go-to-top-common)のクリックイベント
47  $( '.go-to-top-common' ).click( function () {
48    //トップへ戻る間だけクラスを追加
49    $( this ).addClass( 'go-to-top-up' );
50    //ページトップへ移動する
51    $( 'body,html' ).animate(
52      {
53        scrollTop: 1,
54      },
55      800
56    );
57  } );
58  //ボタン(.go-to-toc-common)のクリックイベント
59  $( '.go-to-toc-common' ).click( () => {
60    //目次へ移動する
61    $( 'body,html' ).animate(
62      {
63        scrollTop: $( '.entry-content .toc' ).offset().top,
64      },
65      800
66    );
67  } );
68
69  //検索ボタンクリックでフォーカスを入力エリアに移す
70  $( '#search-menu-input' ).change( ( e ) => {
71    const searchEdit = $( '#search-menu-content .search-edit' ).first();
72    if ( e.target.checked ) {
73      searchEdit.focus();
74    } else {
75      searchEdit.blur();
76    }
77  } );
78
79  //下にスクロールで管理パネルを隠す
80  //上にスクロールで管理パネルを表示
81  const adminMenu = $( '#admin-panel' );
82  const adminHeight = adminMenu.outerHeight();
83  let adminStartPos = 0;
84  $( window ).scroll( function () {
85    const adminCurrentPos = $( this ).scrollTop();
86    if ( adminCurrentPos > adminStartPos ) {
87      if ( adminCurrentPos >= 200 ) {
88        adminMenu.css( 'bottom', '-' + adminHeight + 'px' );
89      }
90    } else {
91      adminMenu.css( 'bottom', 0 );
92    }
93    adminStartPos = adminCurrentPos;
94  } );
95
96  //モバイルボタンが固定じゃない場合
97  if ( cocoon_localize_script_options.is_fixed_mobile_buttons_enable != 1 ) {
98    //ヘッダーモバイルメニュー
99    const headerMenu = $( '.mobile-header-menu-buttons' );
100    let headerStartPos = 0;
101    $( window ).scroll( function () {
102      const headerCurrentPos = $( this ).scrollTop();
103      // メニュー名の折り返しで高さが変わるため、隠す直前に都度高さを取得する。
104      // box-shadowはouterHeightに含まれないため、影の残り対策として余裕を加える。
105      const headerHight = headerMenu.outerHeight() + 5;
106      // 画面幅が600px以下の場合は、--wp-admin--admin-bar--heightを考慮しない(WordPressアドミンバーが固定とならないため、ヘッダーメニューの位置を0にする)
107      if ( window.innerWidth <= 600 ) {
108        if ( headerCurrentPos > headerStartPos ) {
109          if ( headerCurrentPos >= 100 ) {
110            headerMenu.css( 'top', '-' + headerHight + 'px' );
111          }
112        } else {
113          headerMenu.css( 'top', 0 );
114        }
115      } else {
116        // CSS変数--wp-admin--admin-bar--heightの値を取得
117        const adminBarHeight =
118          getComputedStyle( document.documentElement )
119            .getPropertyValue( '--wp-admin--admin-bar--height' )
120            .trim() || '0px';
121        if ( headerCurrentPos > headerStartPos ) {
122          if ( headerCurrentPos >= 100 ) {
123            // 管理バーの高さを考慮してtopを設定
124            headerMenu.css(
125              'top',
126              'calc(' + adminBarHeight + ' - ' + headerHight + 'px)'
127            );
128          }
129        } else {
130          // 管理バーの高さを考慮してtopを設定
131          headerMenu.css( 'top', 'calc(' + adminBarHeight + ')' );
132        }
133      }
134      headerStartPos = headerCurrentPos;
135    } );
136
137    //フッターモバイルメニュー
138    const footerMenu = $( '.mobile-footer-menu-buttons' );
139    let footerStartPos = 0;
140    $( window ).scroll( function () {
141      const footerCurrentPos = $( this ).scrollTop();
142      // メニュー名の折り返しで高さが変わるため、隠す直前に都度高さを取得する。
143      // box-shadowはouterHeightに含まれないため、影の残り対策として余裕を加える。
144      const footerHeight = footerMenu.outerHeight() + 5;
145
146      if ( footerCurrentPos > footerStartPos ) {
147        if ( footerCurrentPos >= 100 ) {
148          footerMenu.css(
149            'bottom',
150            'calc( -1 * (env(safe-area-inset-bottom) + ' +
151              footerHeight +
152              'px) )'
153          );
154        }
155      } else if ( footerCurrentPos - footerStartPos < -8 ) {
156        footerMenu.css( 'bottom', 0 );
157      }
158
159      footerStartPos = footerCurrentPos;
160    } );
161
162    const headerButtons = $( '.mobile-header-menu-buttons' );
163    const footerButtons = $( '.mobile-footer-menu-buttons' );
164    headerButtons.click( () => {
165      headerButtons.css( 'z-index', '3' );
166      footerButtons.css( 'z-index', '2' );
167    } );
168
169    footerButtons.click( () => {
170      headerButtons.css( 'z-index', '2' );
171      footerButtons.css( 'z-index', '3' );
172    } );
173  }
174
175  //コメントボタンがクリックされたとき
176  const clickEventType = window.ontouchstart !== null ? 'click' : 'touchend';
177  $( document ).on(
178    clickEventType,
179    '#comment-reply-btn, .comment-reply-link',
180    () => {
181      $( '#comment-reply-btn' ).slideUp();
182      const respond = document.getElementById( 'respond' );
183      const styles = {
184        inset: 'auto',
185        position: 'static',
186        visibility: 'visible',
187      };
188      Object.entries( styles ).forEach( ( [ key, value ] ) => {
189        respond.style[ key ] = value;
190      } );
191      $( '#respond' ).slideDown();
192    }
193  );
194
195  //Google検索ボタン
196  $( '.sbtn' ).click( function () {
197    const w = $( this ).prev( '.sform' ).text();
198    if ( w ) {
199      window.open(
200        'https://www.google.co.jp/search?q=' + encodeURIComponent( w ),
201        '_blank'
202      );
203    }
204  } );
205
206  //スライドインサイドバーのアーカイブセレクトボックス選択処理
207  $( '.sidebar-menu-content .widget_archive select' ).change( function () {
208    document.location.href = this.options[ this.selectedIndex ].value;
209  } );
210
211  //スライドインサイドバーのカテゴリーセレクトボックス選択処理
212  $( '.sidebar-menu-content .widget_categories select' ).change( function () {
213    if ( this.options[ this.selectedIndex ].value > 0 ) {
214      this.parentNode.submit();
215    }
216  } );
217
218  function drawerCloser( selecter, checkbox ) {
219    $( selecter ).click( () => {
220      $( checkbox ).prop( 'checked', false );
221      // const href = $(this).attr('href');
222      // if (href.match(/#/)) {
223      //   $(checkbox).prop('checked', false);
224      // }
225    } );
226  }
227
228  //モバイルメニューをクリックしたら閉じる
229  drawerCloser( '.menu-drawer .menu-item a', '#navi-menu-input' );
230
231  //モバイルサイドバーをクリックしたら閉じる
232  drawerCloser( '#slide-in-sidebar a', '#sidebar-menu-input' );
233
234  //モバイルヘッダーメニューのロゴ処理
235  $( '.mobile-menu-buttons' ).each( function () {
236    if ( $( this ).has( '.logo-menu-button' ).length ) {
237      $( this ).addClass( 'has-logo-button' );
238    }
239  } );
240
241  $( window ).on( 'load', () => {
242    $( '#carousel' ).addClass( 'loaded' );
243  } );
244
245  //FAQボックスのアコーディオン化用
246  $( '.is-style-accordion > .faq > .faq-answer' ).hide();
247  $( '.is-style-accordion > .faq > .faq-question' ).click( function () {
248    $( this ).next( '.is-style-accordion .faq-answer' ).slideToggle();
249    $( this ).toggleClass( 'active' );
250  } );
251
252  //モバイルサイドバー表示時にサイドバーを移動する・モバイルサイドバーを閉じる時に元の位置に戻す
253  $( document ).on( 'change', '#sidebar-menu-input', function () {
254    if ( $( this ).prop( 'checked' ) ) {
255      $( '#sidebar' ).appendTo( '#sidebar-menu-content' );
256      $( '#sidebar' ).attr( 'id', 'slide-in-sidebar' );
257      $( '#sidebar' ).addClass( 'slide-in-sidebar' );
258      //モバイルサイドバーのリンクをクリックしたら閉じる
259      drawerCloser( '#slide-in-sidebar a', '#sidebar-menu-input' );
260    } else {
261      $( '#sidebar' ).removeClass( 'slide-in-sidebar' );
262      $( '#slide-in-sidebar' ).attr( 'id', 'sidebar' );
263      $( '#sidebar' ).insertAfter( '#main' );
264    }
265  } );
266
267  //リサイズした時はサイドバーを元に戻す
268  let vw = window.innerWidth;
269  $( window ).resize( () => {
270    if ( vw != window.innerWidth ) {
271      $( '#sidebar-menu-input' ).prop( 'checked', false ).change();
272    }
273    vw = window.innerWidth;
274  } );
275} )( jQuery );
276
277/*
278* Cocoon WordPress Theme incorporates code from "Youtube SpeedLoad" WordPress Plugin, Copyright 2017 Alexufo[http://habrahabr.ru/users/alexufo/]
279"Youtube SpeedLoad" WordPress Plugin is distributed under the terms of the GNU GPL v2
280*/
281( function () {
282  const f = document.querySelectorAll( '.video-click' );
283  for ( let i = 0; i < f.length; ++i ) {
284    f[ i ].onclick = function () {
285      const iframe = this.getAttribute( 'data-iframe' );
286      this.parentElement.innerHTML = '<div class="video">' + iframe + '</div>';
287    };
288  }
289} )();
290
291// ヘッダーの位置オフセットを更新
292( function () {
293  function updateHeaderOffset() {
294    const header = document.getElementById( 'header-container' );
295
296    let offset = 0;
297
298    if ( header && header.classList.contains( 'fixed-header' ) ) {
299      offset = header.offsetHeight;
300    }
301
302    // .mobile-header-menu-buttonsのtop・高さを取得して処理
303    const mobileHeaderMenuButtons = document.querySelector(
304      '.mobile-header-menu-buttons'
305    );
306    if ( mobileHeaderMenuButtons ) {
307      const computedStyle = window.getComputedStyle( mobileHeaderMenuButtons );
308      const topValue = parseFloat( computedStyle.top );
309      // ボタンの実寸高さ(ラベル折り返し時も実寸)
310      const height = mobileHeaderMenuButtons.offsetHeight;
311
312      if ( topValue >= 0 ) {
313        // topが0以上(表示中)の場合は、sticky用オフセットに高さを反映
314        offset += height;
315      }
316      // 本文余白用には高さのみを常時設定する。
317      // スクロールで隠れている最中(topが負)でも高さは変わらないため、
318      // 位置(top)に依存せず余白が安定する。
319      document.documentElement.style.setProperty(
320        '--cocoon--mobile-header-menu-buttons--height',
321        height + 'px'
322      );
323    }
324
325    document.documentElement.style.setProperty(
326      '--cocoon--header-container--position-offset',
327      offset + 'px'
328    );
329  }
330
331  function initHeaderOffset() {
332    updateHeaderOffset();
333
334    // モバイルヘッダーボタンのサイズ変化(遅延表示・ラベルの折り返し)を監視する。
335    // スクロールに依存しないため、初期表示時に高さが0pxになる問題を解消できる。
336    const target = document.querySelector( '.mobile-header-menu-buttons' );
337    if ( target && 'ResizeObserver' in window ) {
338      new ResizeObserver( updateHeaderOffset ).observe( target );
339    }
340  }
341
342  if ( document.readyState !== 'loading' ) {
343    initHeaderOffset();
344  } else {
345    document.addEventListener( 'DOMContentLoaded', initHeaderOffset );
346  }
347
348  // ブラウザサイズ変更時に更新(リサイズ処理が完了してから実行するため、少し遅延させる)
349  let resizeTimer;
350  window.addEventListener( 'resize', () => {
351    clearTimeout( resizeTimer );
352    resizeTimer = setTimeout( () => {
353      updateHeaderOffset();
354    }, 100 );
355  } );
356
357  // スクロール時にも更新(固定ヘッダーの表示切り替えに追従するため)
358  window.addEventListener( 'scroll', updateHeaderOffset );
359} )();
360
361// スキップリンクの移動先へのフォーカス付与
362( function () {
363  /**
364   * スキップリンクの移動先要素にフォーカスを移す。
365   *
366   * <main>などの本来フォーカスできない要素にtabindex="-1"を常時付けておくと、
367   * Blink・WebKit系ではその内部をクリック・範囲選択しただけで祖先要素へ
368   * フォーカスが移り、Tabキーの移動起点がコンテナ先頭に戻ってしまう。
369   * そのため、スキップリンクが押されたときだけ一時的に付与して、
370   * フォーカスが外れた時点で取り除く。
371   *
372   * @param {HTMLElement} target 移動先の要素
373   */
374  function focusSkipLinkTarget( target ) {
375    //既存のtabindexがある場合は元の指定を尊重
376    const isTemporary = ! target.hasAttribute( 'tabindex' );
377
378    if ( isTemporary ) {
379      target.setAttribute( 'tabindex', '-1' );
380    }
381
382    target.focus();
383
384    if ( ! isTemporary ) {
385      return;
386    }
387
388    //非表示要素などでフォーカスできなかった場合は、blurが発生せず属性が残り続けるため即時除去
389    if ( document.activeElement !== target ) {
390      target.removeAttribute( 'tabindex' );
391      return;
392    }
393
394    target.addEventListener( 'blur', function removeTemporaryTabindex() {
395      target.removeAttribute( 'tabindex' );
396      target.removeEventListener( 'blur', removeTemporaryTabindex );
397    } );
398  }
399
400  /**
401   * ハッシュから移動先要素のIDを取り出す。
402   *
403   * 日本語などのIDはパーセントエンコードされるためデコードするが、
404   * 不正なエンコードでもクリック処理全体が例外で止まらないようにする。
405   *
406   * @param  {string} hash 先頭に#を含むハッシュ
407   * @return {string} 移動先要素のID
408   */
409  function getSkipLinkTargetId( hash ) {
410    const id = hash.slice( 1 );
411
412    try {
413      return decodeURIComponent( id );
414    } catch ( e ) {
415      return id;
416    }
417  }
418
419  //スキップリンクは描画直後に押される可能性があるため、documentへの委譲で受け取る
420  document.addEventListener( 'click', ( event ) => {
421    //別タブ・別ウィンドウで開く操作のときは、現在のページのフォーカスと表示位置を動かさない
422    if (
423      event.button !== 0 ||
424      event.metaKey ||
425      event.ctrlKey ||
426      event.shiftKey ||
427      event.altKey
428    ) {
429      return;
430    }
431
432    const element = event.target;
433    if ( ! element || typeof element.closest !== 'function' ) {
434      return;
435    }
436
437    const link = element.closest( '.skip-link' );
438    if ( ! link || ! link.hash ) {
439      return;
440    }
441
442    const target = document.getElementById( getSkipLinkTargetId( link.hash ) );
443    if ( target ) {
444      focusSkipLinkTarget( target );
445    }
446  } );
447} )();
448

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.