PageSourceSearch

https://i-shift.com/wp-content/themes/OriginalTheme/asset/js/move-CMN.js

js i-shift.com collected 2026-10-09 22:40:40 UTC 4,405 bytes, 181 lines download raw bytes

1jQuery(function ($) {
2
3  // =============================== */
4  // tab switch 
5  // =============================== */
6  $('.tab-swich li').on('click', function () {
7    $('.tab-swich li, .panel').removeClass('active');
8    $(this).addClass('active');
9    var index = $('.tab-swich li').index(this);
10    $('.panel').eq(index).addClass('active');
11  });
12
13  // =============================== */
14  // contact-CMN
15  // =============================== */
16  jQuery(function ($) {
17    const $cta = $('.contact-CMN');
18    if (!$cta.length) return;
19
20    const io = new IntersectionObserver(
21      (entries) => {
22        entries.forEach(entry => {
23          if (!entry.isIntersecting) return;
24
25          $(entry.target).addClass('is-slideUp');
26          io.unobserve(entry.target); // 一度だけ
27        });
28      }, {
29        root: null,
30        threshold: 0,
31        rootMargin: '0px 0px 15% 0px' // ← 画面に入った瞬間
32        // もっと早めたいなら例:
33        // rootMargin: '0px 0px 20% 0px'
34      }
35    );
36
37    io.observe($cta[0]);
38  });
39
40
41  // =============================== */
42  // type
43  // =============================== */
44  const $targets = $('.js-type-common');
45  if (!$targets.length) return;
46
47  const ensureBox = ($el) => {
48    if ($el.text().length) return;
49    $el.text('\u200B'); // 0幅スペースで高さ0を回避(開始時に必ず消える)
50  };
51
52  const startTyping = ($el) => {
53    const text = $el.data('text') || '';
54    const speed = Number($el.data('speed')) || 40;
55    const useCaret = $el.is('[data-caret]');
56
57    $el.removeClass('is-typing is-typingEND').text('');
58    if (useCaret) $el.addClass('is-caret');
59
60    $el.addClass('is-typing');
61
62    let i = 0;
63    const tick = () => {
64      $el.text(text.slice(0, i));
65      i++;
66
67      if (i <= text.length) {
68        setTimeout(tick, speed);
69        return;
70      }
71
72      $el.removeClass('is-typing').addClass('is-typingEND');
73    };
74
75    tick();
76  };
77
78  const viewEls = [];
79  $targets.each(function () {
80    const $el = $(this);
81    const start = $el.data('start') || 'load';
82    if (start === 'view') {
83      ensureBox($el);
84      viewEls.push(this);
85    } else {
86      startTyping($el);
87    }
88  });
89
90  if (!viewEls.length) return;
91
92  const pending = new Set();
93  let ticking = false;
94
95  const inViewport = (rect, vh) => rect.bottom >= 0 && rect.top < vh;
96
97  const checkPending = () => {
98    ticking = false;
99    if (!pending.size) return;
100
101    const vh = window.innerHeight || document.documentElement.clientHeight;
102    const done = [];
103
104    pending.forEach(el => {
105      const rect = el.getBoundingClientRect();
106      if (!inViewport(rect, vh)) return;
107
108      const $el = $(el);
109      const offset = Number($el.data('offset'));
110      if (!Number.isFinite(offset)) {
111        done.push(el);
112        startTyping($el);
113        observer.unobserve(el);
114        return;
115      }
116
117      const triggerY = vh * offset;
118      if (rect.top <= triggerY) {
119        done.push(el);
120        startTyping($el);
121        observer.unobserve(el);
122      }
123    });
124
125    done.forEach(el => pending.delete(el));
126  };
127
128  const requestCheck = () => {
129    if (ticking) return;
130    ticking = true;
131    requestAnimationFrame(checkPending);
132  };
133
134  window.addEventListener('scroll', requestCheck, {
135    passive: true
136  });
137  window.addEventListener('resize', requestCheck);
138
139  const observer = new IntersectionObserver((entries) => {
140    entries.forEach(entry => {
141      const el = entry.target;
142
143      if (!entry.isIntersecting) {
144        pending.delete(el);
145        return;
146      }
147
148      const $el = $(el);
149      const offsetRaw = $el.data('offset');
150
151      if (offsetRaw === undefined || offsetRaw === '' || offsetRaw === null) {
152        observer.unobserve(el);
153        startTyping($el);
154        return;
155      }
156
157      pending.add(el);
158      requestCheck();
159    });
160  }, {
161    threshold: 0
162  });
163
164  viewEls.forEach(el => observer.observe(el));
165
166  // 初期表示時にObserverが反応しないケースの保険
167  viewEls.forEach(el => {
168    const $el = $(el);
169    const offsetRaw = $el.data('offset');
170    if (offsetRaw !== undefined && offsetRaw !== '' && offsetRaw !== null) {
171      pending.add(el);
172    } else {
173      const rect = el.getBoundingClientRect();
174      const vh = window.innerHeight || document.documentElement.clientHeight;
175      if (inViewport(rect, vh)) startTyping($el);
176    }
177  });
178  requestCheck();
179
180
181});

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.