PageSourceSearch

https://changellenge.com/local/templates/new/components/bitrix/new…/.default/script.js?17888064267908

js changellenge.com collected 2026-10-02 06:45:14 UTC 7,908 bytes, 304 lines download raw bytes

1$(document).ready(function () {
2  $('body').on('click', '.js-scroll', function () {
3    var scroll_el = $(this).attr('href')
4    if ($(scroll_el).length !== 0) {
5      $('html, body').animate({ scrollTop: $(scroll_el).offset().top }, 500)
6    }
7    return false // выключаем стандартное действие
8  })
9
10})
11
12document.addEventListener('DOMContentLoaded', () => {
13
14  document.querySelectorAll('.back-event__button').forEach((button) => {
15    button.addEventListener('click', (e) => {
16      e.preventDefault()
17
18      const referrer = document.referrer
19      if (referrer) {
20        try {
21          const refUrl = new URL(referrer)
22          const isSameOrigin = refUrl.origin === window.location.origin
23          const isCurrentPage = refUrl.pathname + refUrl.search === window.location.pathname + window.location.search
24
25          if (isSameOrigin && !isCurrentPage) {
26            history.back()
27            return
28          }
29        } catch (err) {
30          // fallback below
31        }
32      }
33
34      window.location.href = button.getAttribute('href') || '/event/'
35    })
36  })
37
38  /* Programs popup */
39  document.querySelectorAll('.program').forEach((eventProgram) => {
40	  const eventProgramPopup = eventProgram.nextElementSibling;
41	  if (!eventProgramPopup?.classList.contains('program-popup')) {
42		  return;
43	  }
44
45	  eventProgram.addEventListener('click', () => {
46		  eventProgramPopup.classList.toggle('is-visible')
47	  });
48	  eventProgramPopup.addEventListener('click', (e) => {
49		  if (e.target.classList.contains('program-popup__close')) {
50			  eventProgramPopup.classList.remove('is-visible')
51		  }
52	  });
53
54	  const popupButton = eventProgramPopup.querySelector('.btn-main_red');
55	  const ctaButton = document.querySelector('.ai-jenya-cta__buttons .btn-second');
56
57	  if (popupButton && ctaButton) {
58		  popupButton.addEventListener('click', () => {
59			  ctaButton.click()
60		  })
61	  }
62  })
63
64  const copyTextToClipboard = async (text) => {
65    if (navigator.clipboard?.writeText && window.isSecureContext) {
66      await navigator.clipboard.writeText(text)
67      return
68    }
69
70    const textarea = document.createElement('textarea')
71    textarea.value = text
72    textarea.style.position = 'fixed'
73    textarea.style.left = '-9999px'
74    document.body.appendChild(textarea)
75    textarea.select()
76    document.execCommand('copy')
77    document.body.removeChild(textarea)
78  }
79
80  document.querySelectorAll('[data-event-share]').forEach((button) => {
81    let hideTooltipTimer = null
82
83    button.addEventListener('click', async (e) => {
84      e.preventDefault()
85      const url = button.getAttribute('data-event-share')
86      if (!url) {
87        return
88      }
89
90      try {
91        await copyTextToClipboard(url)
92        const tooltip = button.querySelector('.back-event__share-tooltip')
93        if (!tooltip) {
94          return
95        }
96
97        if (hideTooltipTimer !== null) {
98          clearTimeout(hideTooltipTimer)
99        }
100
101        tooltip.classList.add('is-visible')
102        hideTooltipTimer = window.setTimeout(() => {
103          tooltip.classList.remove('is-visible')
104          hideTooltipTimer = null
105        }, 2000)
106      } catch (err) {
107        console.error('Ошибка при копировании ссылки:', err)
108      }
109    })
110  })
111
112  initAiJenyaStickyCta()
113
114  document.querySelectorAll('[data-registration]').forEach(element => {
115    element.addEventListener('click', (e) => {
116      if (document.querySelector('.project-reg')) {
117        return
118      }
119      e.preventDefault()
120      const formUid = element.getAttribute('data-registration')
121      const $form = document.querySelector('event-registration-form')
122      $form.showForm(formUid)
123    })
124  })
125
126  document.querySelectorAll('[class*="js-registration-internship-"]')?.forEach(element => {
127    element.addEventListener('click', e => {
128      if (document.querySelector('.project-reg')) {
129        return
130      }
131      let formUid = ''
132
133      for (let className of Array.from(element.classList)) {
134        if (className.startsWith('js-registration-internship-')) {
135          formUid = className.replace('js-registration-internship-', '')
136          break
137        }
138      }
139
140      if (formUid) {
141        const $form = document.querySelector('event-registration-form')
142        $form.showForm(formUid)
143      }
144    })
145  })
146
147  const qaEvents = document.querySelectorAll('.qa-event')
148
149  qaEvents.forEach(element => {
150	  const question = element.querySelector('.question')
151	  if (question) {
152		  question.addEventListener('click', () => {
153			  element.classList.toggle('active')
154		  })
155	  }
156  })
157})
158
159const MOBILE_BREAKPOINT = 768
160const STICKY_HYSTERESIS = 16
161const STICKY_TRANSITION_MS = 350
162
163function initAiJenyaStickyCta() {
164  const cta = document.querySelector('[data-ai-jenya-cta]')
165  if (!cta) {
166    return
167  }
168
169  const placeholder = document.createElement('div')
170  placeholder.className = 'ai-jenya-cta-placeholder'
171  cta.before(placeholder)
172
173  let isPinned = false
174  let isUnpinning = false
175  let baseHeight = 0
176  let rafId = null
177  let unpinTimerId = null
178
179  const clearUnpinTimer = () => {
180    if (unpinTimerId !== null) {
181      clearTimeout(unpinTimerId)
182      unpinTimerId = null
183    }
184  }
185
186  const measureBaseHeight = () => {
187    if (!isPinned && !isUnpinning) {
188      baseHeight = cta.offsetHeight
189    }
190
191    return baseHeight
192  }
193
194  const finishUnpin = () => {
195    if (!isUnpinning) {
196      return
197    }
198
199    clearUnpinTimer()
200    cta.removeEventListener('transitionend', onTransitionEnd)
201    isUnpinning = false
202    isPinned = false
203    cta.classList.remove('ai-jenya-cta--fixed', 'ai-jenya-cta--shown')
204    placeholder.style.height = '0'
205    measureBaseHeight()
206  }
207
208  const resetDesktop = () => {
209    clearUnpinTimer()
210    cta.removeEventListener('transitionend', onTransitionEnd)
211    isUnpinning = false
212    isPinned = false
213    cta.classList.remove('ai-jenya-cta--fixed', 'ai-jenya-cta--shown')
214    placeholder.style.height = '0'
215    measureBaseHeight()
216  }
217
218  const onTransitionEnd = (event) => {
219    if (!isUnpinning || event.target !== cta || event.propertyName !== 'transform') {
220      return
221    }
222
223    finishUnpin()
224  }
225
226  const pin = () => {
227    if (isPinned || isUnpinning) {
228      return
229    }
230
231    baseHeight = cta.offsetHeight
232    placeholder.style.height = `${baseHeight}px`
233    cta.classList.add('ai-jenya-cta--fixed')
234    isPinned = true
235
236    requestAnimationFrame(() => {
237      if (isPinned && !isUnpinning) {
238        cta.classList.add('ai-jenya-cta--shown')
239      }
240    })
241  }
242
243  const unpin = () => {
244    if (!isPinned || isUnpinning) {
245      return
246    }
247
248    isUnpinning = true
249    const hadShown = cta.classList.contains('ai-jenya-cta--shown')
250    cta.classList.remove('ai-jenya-cta--shown')
251
252    if (hadShown) {
253      cta.addEventListener('transitionend', onTransitionEnd)
254      unpinTimerId = window.setTimeout(finishUnpin, STICKY_TRANSITION_MS)
255      return
256    }
257
258    requestAnimationFrame(() => {
259      requestAnimationFrame(finishUnpin)
260    })
261  }
262
263  const update = () => {
264    if (window.innerWidth > MOBILE_BREAKPOINT) {
265      resetDesktop()
266      return
267    }
268
269    if (isUnpinning) {
270      return
271    }
272
273    const height = measureBaseHeight()
274    if (!height) {
275      return
276    }
277
278    const placeholderTop = placeholder.getBoundingClientRect().top
279    const placeholderBottom = placeholderTop + height
280    const isAboveViewport = placeholderBottom <= -STICKY_HYSTERESIS
281    const isBackInView = placeholderBottom > STICKY_HYSTERESIS
282
283    if (!isPinned && isAboveViewport) {
284      pin()
285    } else if (isPinned && isBackInView) {
286      unpin()
287    }
288  }
289
290  const scheduleUpdate = () => {
291    if (rafId !== null) {
292      return
293    }
294
295    rafId = requestAnimationFrame(() => {
296      rafId = null
297      update()
298    })
299  }
300
301  window.addEventListener('scroll', scheduleUpdate, { passive: true })
302  window.addEventListener('resize', scheduleUpdate)
303  scheduleUpdate()
304}

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.