1/* 2 * File : js/jt-strap.js 3 * Author : STUDIO-JT (KMS, NICO, JUN, SUMI) 4 * Guideline : JTstyle.2.1 5 * 6 * SUMMARY: 7 * 1) JT Functions INIT 8 * 2) ON LOAD 9 * 3) ON RESIZE 10 * 4) JT Functions 11 * 5) Helpers 12 */ 13 14 15 16(function($){ 17 18 /* **************************************** * 19 * Global 20 * **************************************** */ 21 let isAjaxLoading = false; 22 23 /* **************************************** * 24 * JT Functions INIT 25 * **************************************** */ 26 // INPUT 27 JT.ui.add( selectric_init, true ); 28 JT.ui.add( custom_input_file, true ); 29 // JT.ui.add( custom_input_email, true ); 30 31 // LAZYLOAD 32 JT.ui.add( lazyload_init, true ); 33 34 // LOADMORE 35 JT.ui.add( loadmore, true ); 36 37 // MODULES 38 JT.ui.add( jt_modules_search, true ); 39 40 // TABS COMPONENT 41 JT.ui.add( jt_tabs, true ); 42 43 // SHARE 44 JT.ui.add( share_popup_init, true ); 45 JT.ui.add( share_clipboard, true ); 46 47 // VIDEO 48 JT.ui.add( vimeo_play, true ); 49 JT.ui.add( youtube_play, true ); 50 JT.ui.add( autoplay_inview, true ); 51 JT.ui.add( html_video_play, true ); 52 53 // SINGLE 54 JT.ui.add( blocks_spacer, true ); 55 JT.ui.add( blocks_list_counter, true ); 56 57 JT.ui.add( jt_list_fullclick, true); 58 59 JT.ui.add( jt_modules_ajax, true ); 60 61 62 63 /* **************************************** * 64 * ON LOAD 65 * **************************************** */ 66 window.addEventListener('load', function(){ 67 68 // add 69 70 }); 71 72 73 74 /* **************************************** * 75 * ON RESIZE 76 * **************************************** */ 77 // INITIALIZE RESIZE 78 function handleResize(){ 79 80 // setTimeout to fix IOS animation on rotate issue 81 setTimeout(function(){ 82 83 JT.ui.call( 'blocks_spacer' ); 84 85 }, 100); 86 87 } 88 89 // Init resize on reisize 90 if( JT.browser('mobile') ) { 91 window.addEventListener('orientationchange', handleResize); 92 } else { 93 window.addEventListener('resize', handleResize); 94 } 95 96 97 98 /* **************************************** * 99 * JT Functions 100 * **************************************** */ 101 /** 102 * select 커ì¤í ì¤íì¼ì ì¤ì í©ëë¤. 103 * 104 * @version 1.0.0 105 * @author STUDIO-JT (KMS) 106 * @see {@link http://selectric.js.org/|selectric API} 107 * @requires jquery.selectric.js 108 * @requires jt-strap.css 109 * @requires rwd-strap.css 110 * 111 * @example 112 * <div class="jt-selectric__wrap"> 113 * <select class="jt-selectric"> 114 * <option value="op1">OP1</option> 115 * <option value="op2">OP2</option> 116 * <option value="op3">OP3</option> 117 * </select> 118 * </div> 119 */ 120 function selectric_init() { 121 122 if( !JT.browser('mobile') ) { 123 124 document.querySelectorAll('.jt-selectric').forEach((select) => { 125 126 $(select).selectric({ 127 disableOnMobile: true, 128 arrowButtonMarkup: '<b class="button"><i class="jt-icon"><svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M8.1,11.4L2.3,5.7l1.4-1.4l4.4,4.3l4.2-4.3l1.4,1.4L8.1,11.4z" fill="black"/></svg></i></b>', 129 optionsItemBuilder: function(itemData) { 130 return '<span>' + itemData.text + '</span>'; 131 }, 132 onInit: function(){ 133 document.querySelectorAll('input.selectric-input').forEach( item => item.setAttribute('readonly', true) ); 134 } 135 }); 136 137 }); 138 139 } 140 141 } 142 143 144 145 /** 146 * Fileíì Inputì 커ì¤í 기ë¥ì ì¤ì í©ëë¤. 147 * 148 * @version 1.0.0 149 * @author STUDIO-JT (KMS) 150 * @requires jt-customfile.js 151 * @requires jt-strap.css 152 * @requires rwd-strap.css 153 * 154 * @example 155 * <input type="file" multiple /> 156 */ 157 function custom_input_file(){ 158 159 document.querySelectorAll('input[type="file"]').forEach((input) => { 160 161 new JtCustomFile(input); 162 163 }); 164 165 } 166 167 168 169 /** 170 * Emailíì Inputì ìëìì± ê¸°ë¥ì ì¤ì í©ëë¤. 171 * 172 * @version 1.0.0 173 * @author STUDIO-JT (KMS) 174 * @requires jt-autocomplete.js 175 * @requires jt-strap.css 176 * @requires rwd-strap.css 177 * 178 * @example 179 * <input id="email" type="email" placeholder="ì´ë©ì¼ì ì ë ¥íì¸ì." /> 180 */ 181 /* 182 function custom_input_email(){ 183 184 document.querySelectorAll('input[type="email"]').forEach((input) => { 185 186 new JtAutocomplete(input); 187 188 }); 189 190 } 191 */ 192 193 194 195 /** 196 * Image Lazyload 197 * 198 * @version 1.0.0 199 * @author STUDIO-JT (KMS) 200 * @requires jt-unveil.js
201 * @description masonry UIì ê²½ì° jt-lazyload 컨í ì´ëì jt-lazyload--masonry class를 ì¶ê°ë¡ ë¶ì¬ì ì¬ì©íë ê²ì ê¶ì¥í©ëë¤. 202 * 203 * @example 204 * <figure class="jt-lazyload"> 205 * <span class="jt-lazyload__color-preview"></span> 206 * <img width="120" height="120" data-unveil="some_img_url.jpg" src="blank.gif" alt="" /> 207 * <noscript><img src="some_img_url.jpg" alt="" /></noscript> 208 * </figure> 209 */ 210 function lazyload_init(){ 211 212 // lazyload 213 $('[data-unveil]').unveil(300, function() { 214 const _this = this; 215 216 _this.addEventListener('load', function(){ 217 if( _this.closest('.jt-lazyload') != null ) { 218 _this.closest('.jt-lazyload').classList.add('jt-lazyload--loaded'); 219 } else { 220 _this.classList.add('jt-lazyload--loaded'); 221 } 222 }); 223 }); 224 225 } 226 227 228 229 /** 230 * Ajax loadmore function 231 * 232 * @version 1.0.0 233 * @author STUDIO-JT (NICO) 234 */ 235 function loadmore(){ 236 237 if( !!!document.getElementById('jt-loadmore') ) return; 238 239 let isLoading = false; 240 241 document.querySelector('#jt-loadmore a').addEventListener('click', function(e){ 242 243 e.preventDefault(); 244 245 if( isLoading ) return; 246 isLoading = true; 247 248 const _this = this; 249 const loadmoreBtn = _this.parentNode; 250 const listSelector = _this.getAttribute('data-loadmore-list'); 251 const list = document.querySelector(listSelector); 252 const url = _this.getAttribute('href'); 253 254 loadmoreBtn.classList.add('jt-loadmore--loading'); 255 256 fetch(url).then(( response ) => { 257 return response.text(); 258 }) 259 .then(( html ) => { 260 261 // DOM parser 262 const parser = new DOMParser(); 263 const response = parser.parseFromString(html, 'text/html'); 264 265 // Get data 266 let nextUrl = ( !!response.getElementById('jt-loadmore') ) ? response.querySelector('#jt-loadmore a').getAttribute('href') : undefined; 267 let moreItems = null; 268 269 if( response.getElementsByClassName('jt-isotope-list').length > 0 ) { // Masonry 270 271 // isotope 272 moreItems = response.querySelectorAll('.jt-isotope-list__item'); 273 274 // lazyload check 275 moreItems.forEach((item) => { 276 if( !!item.querySelector('.jt-lazyload--masonry') ){ 277 const figure = item.querySelector('.jt-lazyload--masonry'); 278 const img = figure.querySelector('img'); 279 const imgWidth = img.getAttribute('width'); 280 const imgHeight = img.getAttribute('height'); 281 const paddingTop = (imgHeight/imgWidth)*100; 282 283 figure.style.paddingTop = paddingTop+'%'; 284 figure.classList.add('jt-lazyload--loaded'); 285 img.setAttribute('src', img.getAttribute('data-unveil')); 286 } 287 }); 288 289 JT.globals.isotope.insert(moreItems); 290 imagesLoaded( document.querySelector('.jt-isotope-list'), function() { 291 JT.globals.isotope.layout(); 292 }); 293 294 } else if( response.getElementsByClassName('jt-accordion').length > 0 ) { // Accordion 295 296 moreItems = response.querySelectorAll('.jt-accordion__item'); 297 298 gsap.set( moreItems, { autoAlpha: 0, scale: 0.9 } ); 299 moreItems.forEach( (item) => { list.appendChild( item ) }); 300 gsap.to( moreItems, { autoAlpha: 1, scale: 1, duration: .3, stagger: .1 } ); 301 302 } else { 303 304 // Nothing 305 306 } 307 308 // Update URL 309 /* 310 if ('history' in window && 'pushState' in history) { 311 window.history.pushState(null, null, url); 312 } 313 */ 314 315 // Refresh scrolltrigger offset 316 if( typeof ScrollTrigger != 'undefined' ) { 317 ScrollTrigger.refresh(); 318 } 319 320 // Remove loading class after some delay to avoid 321 setTimeout(function(){ 322 loadmoreBtn.classList.remove('jt-loadmore--loading'); 323 },300); 324 325 if(nextUrl !== undefined){ 326 // Update url 327 _this.setAttribute('href', nextUrl); 328 329 // Update flag 330 isLoading = false;
331 } else { 332 _this.remove(); 333 return; 334 } 335 336 }) 337 .catch(( error ) => { 338 console.error(error); 339 }); 340 341 }); 342 343 } 344 345 346 347 /** 348 * JT Modules ê²ì 기ë¥ì§ì 349 * 350 * @version 1.0.0 351 * @author STUDIO-JT (KMS) 352 */ 353 function jt_modules_search(){ 354 355 if( !document.getElementsByClassName('jt-search').length ) return; 356 357 const wrap = document.querySelector('.jt-search__bundle'); 358 const input = document.querySelector('.jt-search__input'); 359 const clearBtn = document.querySelector('.jt-search__reset'); 360 361 if( input.value.length > 0 ) wrap.classList.add('jt-search--active'); 362 363 // Input 364 input.addEventListener('keydown', function(){ 365 wrap.classList.add('jt-search--active'); 366 }); 367 input.addEventListener('keyup', function(){ 368 if( input.value == '' ){ 369 wrap.classList.remove('jt-search--active'); 370 } else { 371 wrap.classList.add('jt-search--active'); 372 } 373 }); 374 input.addEventListener('focusout', function(){ 375 if( input.value == '' ){ 376 wrap.classList.remove('jt-search--active'); 377 } else { 378 wrap.classList.add('jt-search--active'); 379 } 380 }); 381 382 // Clear input 383 $('.jt-search__reset').on('click', function(e){ 384 385 e.preventDefault(); 386 e.stopPropagation(); 387 388 const $input = $('.jt-search__input'); 389 const $tmp = $( '<input />', { type: 'text' } ); 390 391 $input.val(''); 392 $input.closest( 'div' ).append( $tmp.wrap( '<div style="display:none;"></div>' ) ); 393 $tmp.focus(); 394 $input.focus(); 395 $tmp.remove(); 396 397 wrap.classList.remove('jt-search--active'); 398 399 }); 400 401 } 402 403 404 405 /** 406 * JT basic tabs component 407 * 408 * @version 1.0.1 409 * @author STUDIO-JT (NICO) 410 */ 411 function jt_tabs(){ 412 413 document.querySelectorAll('.jt-tabs').forEach((element) => { 414 415 const _this = element; 416 const menu = _this.querySelector('.jt-tabs__menu'); 417 const menuList = menu.querySelectorAll(':scope > li'); 418 const panel = _this.querySelector('.jt-tabs__panels'); 419 const itemList = panel.querySelectorAll(':scope > div'); 420 const isHash = ( _this.classList.contains('jt-tabs--hash') ) ? true : false; 421 422 // Hide tabs if not already hidden 423 itemList.forEach( ( item ) => item.style.display = 'none' ); 424 425 // Init display the right tab 426 // TODO : DRY this stuff 427 if( isHash && location.hash != '#' ) { 428 if ( location.hash.length > 0 ) { 429 const currentHash = location.hash.replace(/#/,''); 430 const currentItem = document.getElementById(currentHash); 431 const currentHashIndex = [].indexOf.call(itemList, currentItem) + 1; 432 433 panel.querySelector(':scope > div:nth-child('+currentHashIndex+')').style.display = 'block'; 434 menu.querySelector(':scope > li:first-child').classList.remove('jt-tabs--active'); 435 menu.querySelector(':scope > li:nth-child('+currentHashIndex+')').classList.add('jt-tabs--active'); 436 } else{ 437 panel.querySelector(':scope > div:first-child').style.display = 'block'; 438 menu.querySelector(':scope > li:first-child').classList.add('jt-tabs--active'); 439 } 440 } else { 441 panel.querySelector(':scope > div:first-child').style.display = 'block'; 442 menu.querySelector(':scope > li:first-child').classList.add('jt-tabs--active'); 443 } 444 445 // Add click event 446 menuList.forEach((element) => { 447 const _that = element; 448 449 _that.addEventListener('click', function(e){ 450 e.preventDefault(); 451 e.stopPropagation(); 452 453 const link = _that.querySelector('a'); 454 const hash = link.getAttribute('href'); 455 const index = [].indexOf.call(menuList, _that) + 1; 456 457 menuList.forEach( ( item ) => item.classList.remove('jt-tabs--active') ); 458 menu.querySelector(':scope > li:nth-child('+index+')').classList.add('jt-tabs--active'); 459 460 itemList.forEach( ( item ) => item.style.display = 'none' ); 461 panel.querySelector(':scope > div:nth-child('+index+')').style.display = 'block'; 462 463 // add hash 464 if (isHash && 'history' in window && 'pushState' in history) { 465 history.pushState(null, null, hash) 466 } 467 }); 468 }); 469 470 // Listner hash change 471 // TODO DRY THIS CODE !!! 472 if (isHash && "onhashchange" in window) { 473 window.onhashchange = function locationHashChanged() { 474 const _currentHash = location.hash.replace(/#/,''); 475 const _currentItem = document.getElementById(_currentHash); 476 const _currentHashIndex = [].indexOf.call(itemList, _currentItem) + 1; 477 478 itemList.forEach( ( item ) => item.style.display = 'none' ); 479 panel.querySelector(':scope > div:nth-child('+_currentHashIndex+')').style.display = 'block'; 480 menuList.forEach( ( item ) => item.classList.remove('jt-tabs--active') ); 481 menu.querySelector(':scope > li:nth-child('+_currentHashIndex+')').classList.add('jt-tabs--active'); 482 } 483 } 484 485 }); 486 487 } 488 489 490 491 /** 492 * SNS ê³µì íì ì°½ì ìì±í©ëë¤. 493 * 494 * @version 1.0.0 495 * @author STUDIO-JT (JUN) 496 */
497 function share_popup_init(){ 498 499 let winPop = ''; 500 501 // SNS POPUP 502 document.querySelectorAll('.jt-share__item').forEach((element) => { 503 element.addEventListener('click', function(e){ 504 505 // return kakao share 506 if( element.classList.contains('jt-share--kakaotalk') || element.classList.contains('jt-share--url') ) return false; 507 508 e.preventDefault(); 509 510 // OPTIONS 511 const options = { 512 href : element.getAttribute('href'), // 주ì 513 title : 'socialShare', // íì´í 514 width : '600', // { number } ì´ë¦¬ë ì°½ì ê°ë¡ í¬ê¸° 515 height : '600', // { number } ì´ë¦¬ë ì°½ì ì¸ë¡ í¬ê¸° 516 top : '0', // { number } ì´ë¦¬ë ì°½ì ì¢í ì쪽 517 left : '0', // { number } ì´ë¦¬ë ì°½ì ì¢í ì¼ìª½ 518 status : 'no', // { yes | no | 1 | 0 } ìí íìë° ë³´ì´ê±°ë ì¨ê¸°ê¸° 519 fullscreen : 'no', // { yes | no | 1 | 0 } ì ì²´ ì°½ (기본ê°ì no) 520 channelmode : 'no', // { yes | no | 1 | 0 } ì±ë모ë F11 í¤ ê¸°ë¥ì´ë ê°ì 521 location : 'no', // { yes | no | 1 | 0 } 주ìì°½ (기본ê°ì yes) 522 menubar : 'no', // { yes | no | 1 | 0 } ë©ë´ë° (기본ê°ì yes) 523 toolbar : 'no', // { yes | no | 1 | 0 } í´ë° (기본ê°ì yes) 524 resizable : 'yes', // { yes | no | 1 | 0 } ì°½ (기본ê°ì yes) 525 scrollbars : 'yes' // { yes | no | 1 | 0 } ì°½ ì¤í¬ë¡¤ë° (기본ê°ì yes) 526 }; 527 528 // ALIGN CENTER 529 const alignCenter = { 530 top : Math.round((window.innerHeight / 2) - (options.height / 2)), 531 left : Math.round((window.innerWidth / 2) - (options.width / 2)) 532 }; 533 534 // WINDOW OPEN 535 if( !winPop || (winPop && winPop.closed) ) { 536 winPop = window.open(''+ options.href +'',''+ options.title +'','width='+ options.width +',height='+ options.height +',top='+ alignCenter.top +',left='+ alignCenter.left +',status='+ options.status +',fullscreen='+ options.fullscreen +', channelmode='+ options.channelmode+', location='+ options.location+', menubar='+ options.menubar +', toolbar='+ options.toolbar +', resizable='+ options.resizable +', scrollbars='+ options.scrollbars +''); 537 } else { 538 winPop.location.href = options.href; 539 winPop.focus(); 540 } 541 542 }); 543 }); 544 545 } 546 547 548 549 /** 550 * URL í´ë¦½ë³´ë 551 * 552 * @version 1.0.0 553 * @author STUDIO-JT (KMS) 554 */ 555 function share_clipboard(){ 556 557 if( navigator.clipboard && document.getElementsByClassName('jt-share--url').length > 0 ){ 558 559 document.querySelectorAll('.jt-share--url').forEach((item) => { 560 item.addEventListener('click', function(e){ 561 e.preventDefault(); 562 563 const _this = this; 564 565 if ( 'share' in navigator && JT.browser('mobile') ) { 566 const title = document.querySelector('meta[property="og:title"]').getAttribute('content'); 567 const url = document.querySelector('link[rel="canonical"]').getAttribute('href'); 568 569 navigator.share({ 570 title: title, 571 url: url, 572 }); 573 574 return false; 575 } else { 576 navigator.clipboard.writeText(_this.getAttribute('href')).then(function(){ 577 if ( !!!document.querySelector('.jt-share__tooltip') ) { 578 let tooltip = document.createElement('div'); 579 tooltip.setAttribute('class', 'jt-share__tooltip'); 580 tooltip.innerHTML = `<p class="jt-typo--09">${_this.getAttribute('data-tooltip')}</p>`; 581 582 _this.closest('.jt-share').appendChild(tooltip); 583 } 584 585 gsap.fromTo('.jt-share__tooltip', { autoAlpha: 0 }, { autoAlpha: 1, duration: .2, onComplete: function () { gsap.fromTo('.jt-share__tooltip', { autoAlpha: 1 }, { autoAlpha: 0, duration: .2, delay: 3, onComplete: function () { document.querySelector('.jt-share__tooltip').remove(); } }); } }); 586 }); 587 } 588 }); 589 }); 590 591 592 } 593 594 } 595 596 597 598 /** 599 * Vimeo custom play 600 * 601 * @version 1.0.0 602 * @author STUDIO-JT (KMS, NICO) 603 * @see {@link https://developer.vimeo.com/|API} 604 * @requires https://player.vimeo.com/api/player.js 605 */ 606 function vimeo_play(){ 607
608 if( !document.getElementsByClassName('jt-embed-video--vimeo').length ) return; 609 610 // play if click on the poster 611 document.querySelectorAll('.jt-embed-video--vimeo .jt-embed-video__poster').forEach((element) => { 612 const poster = element; 613 const parent = poster.closest('.jt-embed-video__inner'); 614 const iframe = parent.querySelector('iframe'); 615 616 poster.addEventListener('click', function(e){ 617 e.preventDefault(); 618 619 JT.globals.jt_vimeo_ready(function(){ 620 const video = new Vimeo.Player(iframe); 621 gsap.set(iframe, { autoAlpha: 1 }); 622 gsap.to(poster, { autoAlpha: 0, duration: .6, onStart: function () { video.play(); } }); 623 }); 624 }); 625 }); 626 627 } 628 629 630 631 /** 632 * Youtube custom play 633 * 634 * @version 1.0.0 635 * @author STUDIO-JT (NICO) 636 * @see {@link https://developers.google.com/youtube/iframe_api_reference} 637 */ 638 function youtube_play(){ 639 640 if( !document.getElementsByClassName('jt-embed-video--youtube').length ) return; 641 642 const tag = document.createElement('script'); 643 tag.src = 'https://www.youtube.com/iframe_api'; 644 645 const firstScriptTag = document.getElementsByTagName('script')[0]; 646 firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); 647 648 // if youtube api ready do your stuff 649 window.onYouTubeIframeAPIReady = function() { 650 651 // play if click on the poster 652 document.querySelectorAll('.jt-embed-video--youtube .jt-embed-video__poster').forEach((element) => { 653 654 const poster = element; 655 const parent = poster.closest('.jt-embed-video__inner'); 656 const iframe = parent.querySelector('iframe'); 657 const iframeId = iframe.getAttribute('id'); 658 659 new YT.Player(iframeId,{ 660 events: { 661 'onReady': function(event){ 662 poster.addEventListener('click', function(e){ 663 e.preventDefault(); 664 665 event.target.playVideo(); 666 gsap.to(poster, { autoAlpha: 0, duration: .6, onComplete: function () { poster.remove(); } }); 667 }); 668 } 669 } 670 }); 671 672 }); 673 674 } 675 676 } 677 678 679 680 /** 681 * Video lazyload + inview autoplay 682 * 683 * @version 1.0.0 684 * @author STUDIO-JT (KMS) 685 * @requires gsap.min.js 686 * @requires ScrollTrigger.min.js 687 * @see {@link https://greensock.com/docs/|GreenSock Docs} 688 */ 689 function autoplay_inview(){ 690 691 const $target = $('.jt-autoplay-inview'); 692 693 $target.each(function(){ 694 695 const $this = $(this); 696 697 if( $this.hasClass('jt-autoplay-inview--component') ) return; // ì»´í¬ëí¸ íì ì ì¸ 698 699 ScrollTrigger.create({ 700 trigger: $this, 701 start: 'top 200%', 702 once: true, 703 onEnter: function(){ 704 705 const $video = $this.find('.jt-background-video__vod'), 706 $poster = $this.find('.jt-background-video__poster'); 707 708 if( !$video.find('video').length ) { 709 $video.append('<video playsinline loop muted preload><source src="'+ $video.attr('data-video') +'" type="video/mp4"></video>'); 710 } 711 712 const vid = $video.find('video')[0]; 713 714 if(vid){ 715 716 if( $('html').hasClass('chrome') || $('html').hasClass('safari') ){ 717 718 const promise = vid.play(); 719 720 if( promise !== undefined ) { 721 promise.then(function() { 722 if(vid.readyState !== 4){ 723 vid.addEventListener('canplaythrough', jt_video_canplay, false); 724 vid.addEventListener('load', jt_video_canplay, false); 725 if( !$this.hasClass('jt-autoplay-inview--play') ){ vid.pause(); } 726 } else { 727 gsap.to($poster, { duration: .2, autoAlpha: 0, onComplete: function () { $poster.hide(); } }); 728 $this.addClass('jt-autoplay--loaded'); 729 } 730 }).catch(function(error) { 731 console.warn( error ); 732 }); 733 } 734 735 } else { 736 737 vid.play(); 738 739 if(vid.readyState !== 4){ 740 vid.addEventListener('canplaythrough', jt_video_canplay, false); 741 vid.addEventListener('load', jt_video_canplay, false); 742 if( !$this.hasClass('jt-autoplay-inview--play') ){ vid.pause(); } 743 } else { 744 gsap.to($poster, { duration: .2, autoAlpha: 0, onComplete: function () { $poster.hide(); } }); 745 $this.addClass('jt-autoplay--loaded'); 746 } 747 748 } 749 750 function jt_video_canplay(){ 751 vid.removeEventListener('canplaythrough', jt_video_canplay, false); 752 vid.removeEventListener('load', jt_video_canplay, false); 753 754 gsap.to($poster, { duration: .2, autoAlpha: 0, onComplete: function () { $poster.hide(); } }); 755 756 vid.play(); 757 758 $this.addClass('jt-autoplay--loaded'); 759 } 760 761 // autoplay trigger 762 ScrollTrigger.create({ 763 trigger: $this, 764 once: false, 765 onEnter: function(){ 766 if( vid.paused && $this.hasClass('jt-autoplay--loaded') ) { 767 $this.removeClass('jt-autoplay-inview--paused').addClass('jt-autoplay-inview--play'); 768 vid.play(); 769 } 770 }, 771 onEnterBack: function(){ 772 if( vid.paused && $this.hasClass('jt-autoplay--loaded') ) { 773 $this.removeClass('jt-autoplay-inview--paused').addClass('jt-autoplay-inview--play'); 774 vid.play(); 775 } 776 }, 777 onLeave: function(){ 778 if( !vid.paused && $this.hasClass('jt-autoplay--loaded') ) { 779 $this.removeClass('jt-autoplay-inview--play').addClass('jt-autoplay-inview--paused'); 780 vid.pause(); 781 } 782 }, 783 onLeaveBack: function(){ 784 if( !vid.paused && $this.hasClass('jt-autoplay--loaded') ) { 785 $this.removeClass('jt-autoplay-inview--play').addClass('jt-autoplay-inview--paused'); 786 vid.pause(); 787 } 788 } 789 }); 790 } 791 792 } 793 }); 794 795 }); 796 797 } 798 799 800 801 function html_video_play(){ 802 803 if( !document.getElementsByClassName('jt-html-video').length ) return; 804 805 document.querySelectorAll('.jt-html-video').forEach((target) => { 806 807 const poster = target.getElementsByClassName('jt-html-video__poster')[0]; 808 const video = target.getElementsByTagName('video')[0]; 809 let initialPlay = true; 810 811 if(video){ 812 813 poster.addEventListener('click', function(e){ 814 e.preventDefault(); 815 816 video.load(); 817 video.oncanplaythrough = function(){ 818 819 if( !initialPlay ) return; 820 initialPlay = false;
821 822 video.play(); 823 824 if( poster != null ) { gsap.to(poster, { duration: .6, autoAlpha: 0, onComplete: function () { poster.style.display == "none"; } }); } 825 } 826 }); 827 } 828 829 }) 830 831 } 832 833 834 835 /** 836 * Gutenberg editor spacer block converter 837 * 838 * @version 1.0.0 839 * @author STUDIO-JT (KMS) 840 */ 841 function blocks_spacer(){ 842 843 document.querySelectorAll('.wp-block-spacer').forEach((space) => { 844 845 if( space.getAttribute('data-space') == null ) { 846 space.setAttribute('data-space', space.style.height); 847 } 848 849 const heightOrigin = space.getAttribute('data-space'); 850 let heightConvert = heightOrigin.replace('px',''); 851 852 if( JT.isScreen(860) ){ 853 heightConvert = heightConvert/2; 854 } 855 856 space.style.height = heightConvert+'rem'; 857 858 }); 859 860 } 861 862 863 864 /** 865 * Gutenberg editor list block option support 866 * 867 * @version 1.0.0 868 * @author STUDIO-JT (KMS) 869 */ 870 function blocks_list_counter(){ 871 872 document.querySelectorAll('.jt-blocks ol[reversed]').forEach((list) => { 873 list.style.counterReset = 'item ' + (list.children.length + 1); 874 }); 875 876 } 877 878 879 880 /** 881 * 리ì¤í¸ fullclick actionì ì¶ê°í©ëë¤ 882 * 883 * @version 1.0.0 884 * @author STUDIO-JT (KMS) 885 */ 886 function jt_list_fullclick() { 887 888 document.querySelectorAll('.js-action--full-click').forEach((item) => { 889 890 if ( item.classList.contains('feature-recommend__list-item') && JT.browser('mobile') ){ 891 892 item.classList.remove('js-action--full-click'); 893 return; 894 895 } 896 897 item.addEventListener('click', (e) => { 898 899 var url = item.querySelectorAll('a')[0].getAttribute('href'); 900 901 if(url != undefined){ 902 window.location.href = url; 903 } 904 }); 905 }); 906 907 } 908 909 910 911 /* **************************************** * 912 * Helpers 913 * **************************************** */ 914 /** 915 * Vimeo script on demand 916 * 917 * @version 1.0.0 918 * @author STUDIO-JT (KMS) 919 */ 920 JT.globals.jt_vimeo_ready = function( callback ){ 921 922 if( typeof callback != 'function' ) return; 923 924 if( typeof Vimeo == 'undefined' ){ 925 926 const prior = document.getElementsByTagName('script')[0]; 927 928 let script = document.createElement('script'); 929 script.async = 1; 930 931 script.onload = script.onreadystatechange = function( _, isAbort ) { 932 if( isAbort || !script.readyState || /loaded|complete/.test(script.readyState) ) { 933 script.onload = script.onreadystatechange = null; 934 script = undefined; 935 936 if( !isAbort ) return callback(); 937 } 938 }; 939 940 script.src = 'https://player.vimeo.com/api/player.js'; 941 prior.parentNode.insertBefore(script, prior); 942 943 } else { 944 945 return callback(); 946 947 } 948 949 } 950 951 function jt_modules_ajax(){ 952 953 if( $('body').hasClass('tag') ) { return; } 954 955 // Init 956 if( !!$('.jt-category-nav-wrap').length && JT.isScreen(540) ) { 957 958 // Scroll 959 category_scroll( $('.jt-category-nav-wrap').find('.jt-category--active') ); 960 961 } 962 963 $(document).on('click', '.jt-category-nav > ul > li > a', function(e){ 964 965 e.preventDefault(); 966 967 const $this = $(this); 968 const url = $this.attr('href'); 969 const resource = url.indexOf('resource'); 970 if( isAjaxLoading || $this.closest('li').hasClass('jt-category--active') ) return; 971 972 // Scroll 973 category_scroll( $this.closest('li') ); 974 975 jt_ajax_call( 'category', url , resource ); 976 977 // resource menu update 978 $('.menu-item a, small-menu a').each(function(){ 979 const target = $(this).prop('search'); 980 981 if ($this.prop('search') == target){ 982 983 $(this).parent('li').siblings().removeClass('current-menu-item'); 984 $(this).parent('li').addClass('current-menu-item'); 985 } 986 987 }) 988 989 }); 990 991 // List 992 $(document).on('click', '.jt-list-ajax a', function(e){ 993 e.preventDefault(); 994 995 const $this = $(this); 996 const url = $this.attr('href'); 997 if( isAjaxLoading ) return; 998 999 jt_ajax_call( 'list', url, null ); 1000 1001 }); 1002 1003 // Pagination 1004 $(document).on('click', '.jt-pagination a', function(e){ 1005 1006 e.preventDefault(); 1007 1008 const $this = $(this); 1009 const url = $this.attr('href'); 1010 1011 if( isAjaxLoading ) return; 1012 1013 jt_ajax_call( 'paging', url, null ); 1014 1015 }); 1016 1017 // Search 1018 $(document).on('submit', '.jt-search', function(e){ 1019 1020 e.preventDefault(); 1021 1022 const $this = $(this); 1023 1024 const formData = new FormData(this); 1025 // if (formData.has("search") && formData.get("search").length > 100) { 1026 if ($this.find("[name='search']").val().length > 100) { 1027 alert("ê²ì ê°ë¥í ê¸ì ìê° ì´ê³¼ëììµëë¤.(100ì)"); 1028 return false;
1029 } 1030 1031 const data = $this.serialize(); 1032 const url = $this.attr('action') + '?' + data; 1033 1034 if( isAjaxLoading ) return; 1035 1036 jt_ajax_call( 'search', url, data ); 1037 1038 $this.find('#jt-search__input').blur(); 1039 1040 }); 1041 1042 // Popstate 1043 $(window).on('popstate', function(){ 1044 1045 var url = new URL( window.location.href ); 1046 params = url.searchParams; 1047 1048 jt_ajax_call('popstate', url.href, null, function(){ 1049 1050 category_scroll( $('.jt-category--active') ); 1051 1052 if( params.get('search') ){ 1053 $('.jt-search__bundle').addClass('jt-search--active'); 1054 $('#jt-search__input').val( params.get('search') ); 1055 } else { 1056 $('.jt-search__bundle').removeClass('jt-search--active'); 1057 $('#jt-search__input').val( '' ); 1058 } 1059 }); 1060 1061 }); 1062 1063 // Scroll 1064 function category_scroll( $li ){ 1065 1066 if( JT.isScreen(540) ) { 1067 const containerWidth = $('.jt-list-filter').width(); 1068 let itemWidth = 0; 1069 1070 $('.jt-list-filter li').each(function( idx ){ 1071 const $that = $(this); 1072 itemWidth += $that.width() + parseInt($that.css('margin-left')); 1073 1074 if( idx == $li.index() ) { 1075 let left = itemWidth - (containerWidth/2); 1076 if( left < 0 ) { left = 0; } 1077 1078 $('.jt-category-nav-wrap').stop().animate({ scrollLeft: left }, 400); 1079 1080 return false; 1081 } 1082 }); 1083 } 1084 1085 } 1086 1087 } 1088 1089 function jt_ajax_call( type, url, data, callback ) { 1090 1091 // Update flag 1092 isAjaxLoading = true; 1093 1094 // Target 1095 const selector = '.jt-list-container'; 1096 const $container = $(selector); 1097 1098 if ( data ) { 1099 gsap.to($container.find('> *:not(.jt-list-filter):not(.article__highlight)'), { opacity: 0, duration: .2 }); 1100 } else { 1101 gsap.to($container.find('> *:not(.jt-list-filter)'), { opacity: 0, duration: .2 }); 1102 } 1103 1104 $.get( url, data, function ( response ) { 1105 1106 var $response = $(response).find(selector); 1107 1108 // lazy image check 1109 $response.find('.jt-lazyload').each(function(){ 1110 var $this = $(this); 1111 var $img = $this.find('img'); 1112 $this.addClass('jt-lazyload--loaded'); 1113 $img.attr('src', $img.attr('data-unveil')); 1114 }); 1115 1116 $container.find('> *:not(.jt-list-filter)').remove(); 1117 $container.append($response.find('> *:not(.jt-list-filter)')); 1118 1119 if( type != 'paging' ) { 1120 $container.find('.jt-category-nav').replaceWith( $response.find('.jt-category-nav') ); 1121 } 1122 1123 if( type == 'list' ) { 1124 // 목ë¡ì¼ë¡ê°ê¸° í´ë¦ì ê²ìë°ì´í° reset 1125 $container.find('.jt-search__input').val(''); 1126 $container.find('.jt-search__bundle').removeClass('jt-search--active'); 1127 } 1128 1129 // Update url 1130 if( type != 'popstate' ){ 1131 gsap.to($container.find('> *:not(.jt-list-filter)'), { 1132 opacity: 1, 1133 duration: .3, 1134 onStart: function() { 1135 gsap.to(window, { duration: .3, scrollTo: $container.offset().top - ($('#header').outerHeight()*1.3) }); 1136 JT.ui.call( 'selectric_init' ); 1137 } 1138 }); 1139 1140 if ('history' in window && 'pushState' in history) { 1141 window.history.pushState(null, null, url); 1142 } 1143 } 1144 1145 // swiper reinit (highlight) 1146 JT.ui.call('article_highlight_slider'); 1147 1148 // prevent button with comingsoon alert 1149 JT.ui.call('btn_comingsoon'); 1150 1151 // callback 1152 if( typeof callback == 'function' ){ 1153 callback.call(); 1154 } 1155 1156 // Update flag 1157 isAjaxLoading = false;
1158 1159 } ); 1160 1161 } 1162 1163 1164 1165 // ê·¸ë£¨ë¹ ë§ì¶¤ Validation 1166 JT.globals.validation = function( element, wrapSelector, validSelector ){ 1167 1168 const field = element; 1169 const container = ( typeof wrapSelector == 'undefined' ) ? field.closest('.jt-form__data') : field.closest(wrapSelector); 1170 const validTip = ( typeof wrapSelector == 'undefined' ) ? container.querySelector('.jt-form__valid') : container.querySelector(validSelector); 1171 const dataset = field.dataset; 1172 let isValid = true; 1173 1174 // Pattern 모ì 1175 const langPattern = /^(?!^\s)(?!.*\s$)[a-zA-Zê°-í£\s]+$/; // íê¸+ì문 (ì/ë¤ ì¤íì´ì¤ ë¶ê°) 1176 const numSpecialPattern = /^[0-9!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]+$/; // ì«ì + ê¸°í¸ 1177 const consonantPattern = /[ã±-ã ]/; // ìì 1178 const vowelPattern = /[ã -ã £]/; // 모ì 1179 const phonePattern = /^0?[0-9]{1,2}-?[0-9]{3,4}-?[0-9]{4}$/; // ì íë²í¸ 1180 const emailPattern = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/; // ì´ë©ì¼ 1181 1182 if( !field.validity.valid ) { // Default 1183 1184 if( field.validity.valueMissing ) { 1185 1186 if( 'msgRequired' in dataset ) { 1187 validTip.textContent = dataset.msgRequired; 1188 } else { 1189 validTip.textContent = 'íìí목ì ì ë ¥í´ ì£¼ì¸ì.'; 1190 } 1191 1192 } else if( field.validity.tooLong ) { 1193 1194 validTip.textContent = 'ìµë íì© ê¸¸ì´ë³´ë¤ ê¹ëë¤.'; 1195 1196 } else if( field.validity.tooShort ) { 1197 1198 validTip.textContent = 'ìµì íì© ê¸¸ì´ë³´ë¤ ì§§ìµëë¤.'; 1199 1200 } 1201 1202 // Flag 1203 container.classList.add('jt-form__data--error'); 1204 isValid = false; 1205 1206 } else { // Custom Patterns 1207 1208 const fieldId = field.getAttribute('id'); 1209 const fieldVal = field.value; 1210 let isPattern = true; 1211 1212 if( field.hasAttribute('required') && !fieldVal.replace(/\s/g, '').length ) { // 공백ì ì¸ ë¹ì¹¸ 1213 1214 validTip.textContent = 'íìí목ì ì ë ¥í´ ì£¼ì¸ì.'; 1215 isPattern = false; 1216 1217 } else { // ë¹ì¹¸ìë ë 1218 1219 if( fieldId == 'name' ) { // ì±í¨ 1220 1221 if( consonantPattern.test( fieldVal ) || vowelPattern.test( fieldVal ) ) { 1222 validTip.textContent = 'ì íí íìì ì±í¨ì 기ì¬í´ 주ì¸ì.'; 1223 isPattern = false; 1224 } else if( !langPattern.test( fieldVal ) ) { 1225 validTip.textContent = 'íê¸, ìë¬¸ë§ ì ë ¥ì´ ê°ë¥í©ëë¤.'; 1226 isPattern = false; 1227 } 1228 1229 } else if( fieldId == 'company' || fieldId == 'part' || fieldId == 'position' ) { // íì¬ëª , ë¶ìëª , ì§ê¸ 1230 1231 if( consonantPattern.test( fieldVal ) || vowelPattern.test( fieldVal ) || numSpecialPattern.test( fieldVal ) ) { 1232 // Error type 1233 let msgType = ''; 1234 1235 switch ( fieldId ) { 1236 case 'part': 1237 msgType = 'ë¶ìëª '; 1238 break; 1239 case 'position': 1240 msgType = 'ì§ê¸'; 1241 break; 1242 default: 1243 msgType = 'íì¬ëª '; 1244 break; 1245 } 1246 1247 validTip.textContent = `ì íí íìì ${msgType}ì 기ì¬í´ 주ì¸ì.`; 1248 isPattern = false; 1249 } 1250 1251 } else if( fieldId == 'phone' ) { // ì íë²í¸ 1252 1253 if( !phonePattern.test( fieldVal ) ) { 1254 validTip.textContent = 'ì íí íìì ì°ë½ì²ë¥¼ 기ì¬í´ 주ì¸ì.'; 1255 isPattern = false;
1256 } 1257 1258 } else if( fieldId == 'email' ) { // ì´ë©ì¼ 1259 1260 if( !emailPattern.test( fieldVal ) ) { 1261 validTip.textContent = 'ì íí íìì ì´ë©ì¼ì 기ì¬í´ 주ì¸ì.'; 1262 isPattern = false; 1263 } 1264 1265 } else if( fieldId == 'site' || fieldId == 'function' ) { // ëì ìì ì¬ì´í¸ 1266 1267 if( fieldVal.length == 1 || numSpecialPattern.test( fieldVal ) ) { 1268 // Error type 1269 const msgType = ( fieldId == 'site' ) ? 'ì¬ì´í¸ URL' : '기ë¥'; 1270 1271 validTip.textContent = `ì íí ${msgType}ì 기ì¬í´ 주ì¸ì.`; 1272 isPattern = false; 1273 } 1274 1275 } 1276 1277 } 1278 1279 // Flag 1280 if( !isPattern ) { // Error 1281 container.classList.add('jt-form__data--error'); 1282 isValid = false; 1283 } else { // Success 1284 validTip.textContent = ''; 1285 container.classList.remove('jt-form__data--error'); 1286 } 1287 1288 } 1289 1290 return isValid; 1291 1292 } 1293 1294 1295 1296})(jQuery);
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.