/* Author : hyojeong yang Date : 2025-09-22 Project : 온세종 */ const toggleCommonFunc = ({ obj, className, hasClass, noneClass }) => { $(obj).toggleClass(className); if ($(obj).hasClass(className)) { hasClass(obj); } else { noneClass(); } }; let openPopupsPub = []; let dimZIndexPub = 97; let lastFocusedElement = null; const popupOpenPub = (target) => { lastFocusedElement = document.activeElement; const $pop = $(`[data-popuppub="${target}"]`); if ($pop.hasClass('popup-alert-area')) { $pop.css({ 'display': 'flex' }); setTimeout(() => { $pop.find('button, a[href], input, select, textarea, [tabindex]:not([tabindex="-1"]), [contenteditable]').first().focus(); }, 10); return; } else { openPopupsPub.push(target); dimZIndexPub += 2; $pop.css({ 'display': 'flex', 'z-index': dimZIndexPub + 1 }).addClass('is-active'); $('.dim').css({ 'z-index': dimZIndexPub }).show(); $('body').css({ 'overflow-y': 'hidden' }); setTimeout(() => { $pop.find('button, a[href], input, select, textarea, [tabindex]:not([tabindex="-1"]), [contenteditable]').first().focus(); }, 10); } }; const popupClosePub = (target) => { const $pop = $(`[data-popuppub="${target}"]`); if ($pop.hasClass('popup-alert-area')) { $pop.fadeOut(200, () => { if (lastFocusedElement) { lastFocusedElement.focus(); // 이전 요소로 포커스 복귀 } }); return; } else { openPopupsPub = openPopupsPub.filter(item => item !== target); if (openPopupsPub.length === 0) { $('body').css({ 'overflow-y': 'auto' }); $pop.add('.dim').fadeOut(100).removeClass('is-active'); dimZIndexPub = 97; } else { dimZIndexPub -= 2; $pop.fadeOut(200, () => { $('.dim').css({ 'z-index': dimZIndexPub }); }); } setTimeout(() => { if (lastFocusedElement) { lastFocusedElement.focus(); // 이전 요소로 포커스 복귀 } }, 10); } }; $(document).on('click', '[data-popuppub] .pop-close', function () { const target = $(this).closest($('[class^=popup][data-popuppub]')).data('popuppub'); popupClosePub(target); }); $('.dim').on('click', () => { if (openPopupsPub.length > 0) { const topPopup = openPopupsPub[openPopupsPub.length - 1]; popupClosePub(topPopup); } }); //toast let toastTimer; const toastShow = function (message) { clearTimeout(toastTimer); $(".toast").text(message); $(".toast").removeClass("is-hidden").removeClass("is-hide").addClass("is-show"); toastTimer = setTimeout(function () { toastHide(); }, 2000); } const toastHide = function () { clearTimeout(toastTimer); $(".toast").removeClass("is-show").addClass("is-hide"); toastTimer = setTimeout(function () { $(".toast").addClass("is-hidden"); }, 1000); } /* chart */ // 공통 const defaltBg = '#F0F0F5'; let gradientColorPrimary = ['#26C1D9', '#91E7F5']; let gradientColorSecondary = ['#5FDDCD', '#AEEEE8']; let gradientColorAccent = ['#FFD47C', '#FFC550']; const gradientColorPositive = ['#C2EFC2', '#42BE42']; const gradientColorNegative = ['#FF8F66', '#FF6A33']; const gradientColorYellow = ['#FFD47C', '#FFC550']; const gradientColorGreen = ['#C2EFC2', '#42BE42']; const gradientColorBlue = ['#88B7EC', '#1359A9']; const gradientColorPink = ['#FFC5D7', '#FF8291']; const gradientColorViolet = ['#BDA2E3', '#7A45C6']; // const gradientColorOrange = ['#FF8F66', '#FF6A33']; //const gradientColorRed = ['#F89999', '#F23B3B']; const hexToRGBA = (hex, opacity) => { // HEX 값에서 R, G, B 값을 추출 const r = parseInt(hex.substring(1, 3), 16); const g = parseInt(hex.substring(3, 5), 16); const b = parseInt(hex.substring(5, 7), 16); return `rgba(${r}, ${g}, ${b}, ${opacity})`; }; const createGradient = (ctx, colors, opacity = 1) => { const gradient = ctx.createLinearGradient(0, 0, 0, 200); // HEX 값을 RGBA로 변환 후 투명도 적용 const rgbaColor1 = hexToRGBA(colors[0], opacity); const rgbaColor2 = hexToRGBA(colors[1], opacity); gradient.addColorStop(0, rgbaColor1); gradient.addColorStop(1, rgbaColor2); return gradient; }; const isMobile = window.innerWidth <= 768; const chartStyleLabelFont = { font: { size: isMobile ? 10 : 12, weight: 500, family: "Pretendard" }, } const chartStyleLabel = { backgroundColor: '#fff', color: '#5A585E', borderRadius: 4, borderWidth: 1, font: { size: isMobile ? 10 : 11, weight: 700, family: "Pretendard" }, borderColor: '#dddae3', shadowColor: 'rgba(0, 0, 0, 0.5)', shadowBlur: 15, shadowOffsetX: 4, shadowOffsetY: 4, padding: { left: isMobile ? 4 : 8, right: isMobile ? 4 : 8 } } const chartStyleAvgLine = { type: 'line', borderColor: '#FF8291', borderWidth: 1, borderDash: [5, 5], } const chartDoughnutOption = { // responsive: true, cutout: '70%', animation: false, interaction: { mode: null, // hover 모드 비활성화 intersect: false, // 데이터와의 교차점에서만 활성화되지 않도록 설정 }, plugins: { tooltip: { enabled: false }, legend: { display: false }, } } function createChartDoughnut(elementId, value, gradientColors) { document.getElementById(elementId).classList.add('chart-doughnut'); const ctx = document.getElementById(elementId).getContext('2d'); const backgroundColors = gradientColors.map(colors => { if (Array.isArray(colors) && colors.length === 2) { return createGradient(ctx, colors); } return defaltBg; }); const dataValues = Array.isArray(value) && value.length > 1 ? value : [value, 100 - value]; const dataBackgroundColor = Array.isArray(value) && value.length > 1 ? backgroundColors : [createGradient(ctx, gradientColors), defaltBg]; return new Chart(ctx, { type: 'doughnut', data: { datasets: [ { data: dataValues, backgroundColor: dataBackgroundColor, borderWidth: 0, } ] }, options: { ...chartDoughnutOption, } }); } function createChartDoughnutTxt(elementId, value, gradientColors) { const ctx = document.getElementById(elementId).getContext('2d'); const backgroundColors = gradientColors.map(colors => { if (Array.isArray(colors) && colors.length === 2) { return createGradient(ctx, colors); } return defaltBg; }); const dataValues = Array.isArray(value) && value.length > 1 ? value : [value, 100 - value]; const dataBackgroundColor = Array.isArray(value) && value.length > 1 ? backgroundColors : [createGradient(ctx, gradientColors), defaltBg]; return new Chart(ctx, { type: 'doughnut', data: { datasets: [{ data: dataValues, backgroundColor: dataBackgroundColor, borderWidth: 0 }] }, options: { ...chartDoughnutOption, plugins: { // ...chartDoughnutOption.plugins, datalabels: { // display: true, color: '#000', font: { size: 20, weight: 'bold' }, formatter: function(_, context) { if (context.dataIndex === 0) { return Array.isArray(value) ? value[0] + '%' : value + '%'; } return ''; }, // 중앙에 고정 anchor: 'cetner', align: 'center' } } }, plugins: [ChartDataLabels] }); } function createChartBar(elementId, labels, data, onClick = null, avg = false) { document.getElementById(elementId).classList.add('chart-bar'); const canvas = document.getElementById(elementId); const chartParent = canvas.parentElement; const ctx = canvas.getContext('2d'); const charBarStyle = { datalabels: { display: true, anchor: 'end', align: function (context) { const dataValue = context.dataset.data[context.dataIndex]; var totalMinus = 95; return dataValue === 0 || dataValue < totalMinus ? 'end' : 'center'; }, padding: { left: isMobile ? 4 : 8, right: isMobile ? 4 : 8 }, formatter: function(value) { return value + '%'; }, ...chartStyleLabel }, backgroundColor: function(context) { return context.dataIndex % 2 === 0 ? createGradient(context.chart.ctx, gradientColorPrimary) : createGradient(context.chart.ctx, gradientColorSecondary); }, borderWidth: 0, borderRadius: isMobile ? 16 : 24, maxBarThickness: isMobile ? 16 : 24, custom: function(context) { const label = labels[context.dataIndex]; return label && label.id ? { id: label.id } : {}; } }; const charBarOptions = { plugins: { tooltip: { enabled: false }, legend: { display: false }, annotation: { annotations: { avgLine: { ...chartStyleAvgLine, display: !!avg, yMin: avg || 0, yMax: avg || 0, } } } }, maintainAspectRatio: false, animation: false, scales: { x: { ticks: { ...chartStyleLabelFont }, grid: { display: false }, }, y: { beginAtZero: true, border: { dash: [2, 4] }, ticks: { padding: isMobile ? 0 : 8, stepSize: 25, ...chartStyleLabelFont, callback: function(value) { return value + '%'; } }, max: 100, min: 0, }, }, onClick: onClick ? (event, elements) => { onClick(event, elements, labels, data); } : null, }; new Chart(ctx, { type: 'bar', data: { labels: labels, datasets: [{ data: data, ...charBarStyle }], }, plugins: [ChartDataLabels], options: charBarOptions, }); } function createChartBarWidthauto(elementId, labels, data, onClick = null, avg = false) { document.getElementById(elementId).classList.add('chart-bar-widthauto'); const ctx = document.getElementById(elementId).getContext('2d'); const canvas = document.getElementById(elementId); const chartParent = canvas.parentElement; // chart1 div 요소 const canvasWidth = labels.length * 36; // 바의 개수에 따른 너비 계산 // 캔버스의 너비와 높이 설정 canvas.width = canvasWidth; chartParent.style.minWidth = `${canvasWidth}px`; const charBarStyle = { datalabels: { display: false, }, backgroundColor: function(context) { return context.dataIndex % 2 === 0 ? createGradient(context.chart.ctx, gradientColorPrimary) : createGradient(context.chart.ctx, gradientColorSecondary); }, borderWidth: 0, borderRadius: isMobile ? 16 : 24, maxBarThickness: isMobile ? 16 : 24, custom: function(context) { const label = labels[context.dataIndex]; // labels 배열에서 해당 데이터 참조 return label.id ? { id: label.id } : {}; } }; const charBarOptions = { plugins: { tooltip: { enabled: false }, legend: { display: false }, annotation: { annotations: { avgLine: { ...chartStyleAvgLine, yMin: avg, yMax: avg, } } } }, maintainAspectRatio: false, animation: false, scales: { x: { ticks: { ...chartStyleLabelFont }, grid: { display: false }, }, y: { beginAtZero: true, border: { dash: [2,4] }, ticks: { padding: isMobile ? 0 : 8, stepSize: 25, ...chartStyleLabelFont, callback: function(value) { return value + '%'; } }, max: 100, min: 0, }, }, onClick: onClick ? (event, elements) => { onClick(event, elements, labels, data); } : null, }; new Chart(ctx, { type: 'bar', data: { labels: labels, datasets: [ { data: data, ...charBarStyle, }, ], }, plugins: [ChartDataLabels], options: charBarOptions, }); } function createChartLine(elementId, labels, dataSets, legends, colors, animation) { document.getElementById(elementId).classList.add('chart-line'); const ctx = document.getElementById(elementId).getContext('2d'); // 각 데이터셋에 맞는 그라데이션 생성 const gradients = colors.map(color => createGradient(ctx, color, .1)); const datasets = dataSets.map((data, index) => ({ label: legends[index], data: data, backgroundColor: gradients[index], borderColor: colors[index][1], borderWidth:2, lineTension:0.3, pointRadius:4, pointBackgroundColor:'#fff', pointBorderWidth: 2, fill: false, })); new Chart(ctx, { type: "line", data: { labels, datasets }, options: { plugins: { tooltip: { enabled: false }, legend: { display: false } }, animation: false, //responsive: true, // 반응형 설정 //maintainAspectRatio: false, // 부모 요소 크기에 맞게 차트 크기 조정 scales: { x: { beginAtZero: true, grid: { display: false, }, ticks: { ...chartStyleLabelFont } }, y: { suggestedMin: 0, suggestedMax: 100, border: { dash: [2,4], }, ticks: { padding: isMobile ? 0 : 0, stepSize: 25, ...chartStyleLabelFont, callback: function(value) { return value + '%'; } }, }, }, }, }); } function createChartRadar(elementId, labels, dataSets, legends, colors, animation) { document.getElementById(elementId).classList.add('chart-radar'); const ctx = document.getElementById(elementId).getContext('2d'); const allDataValues = dataSets.flat(); const rawMax = Math.max(...allDataValues); const safeMax = rawMax <= 4 ? 4 : rawMax; const maxValue = Math.ceil(safeMax / 10) * 10 || 4; const stepSize = maxValue / 4; // 각 데이터셋에 맞는 그라데이션 생성 const gradients = colors.map(color => createGradient(ctx, color, .1)); const datasets = dataSets.map((data, index) => ({ label: legends[index], data: data, backgroundColor: gradients[index], borderColor: colors[index][1], borderWidth: 2, lineTension: 0, pointRadius: 4, pointBackgroundColor: '#fff', pointBorderWidth: 2, fill: true, })); new Chart(ctx, { type: "radar", data: { labels, datasets }, options: { plugins: { tooltip: { enabled: false }, legend: { display: false } }, maintainAspectRatio: false, animation: false, // responsive: true, // maintainAspectRatio: false, scales: { r: { max: maxValue, ticks: { display: false, // 눈금 값 숨김 stepSize: stepSize, }, pointLabels: { ...chartStyleLabelFont, padding: isMobile ? 4 : 16, }, } } }, }); } //헤더 체크 const checkIsSticky = () => { const header = document.querySelector('.site-header'); if (!header) return; if (window.scrollY > 10) { header.classList.add('is-sticky'); } else { header.classList.remove('is-sticky'); } } if (jQuery) (function ($) { // accordionFunc $.extend($.fn, { accordionFunc: function () { var init = function (obj) { $(document).on('click', '.btn-accordion-toggle', function (e) { const $targetBtn = $(e.target).closest('.btn-accordion-toggle'); const $currentLi = $targetBtn.closest('li'); const $accordion = $currentLi.closest('.accordion'); const $btns = $accordion.find('li .btn-accordion-toggle'); $currentLi.siblings('li').removeClass('is-active'); toggleCommonFunc({ obj: $currentLi, className: 'is-active', hasClass: function () { $btns.html('열기'); $targetBtn.html('닫기'); }, noneClass: function () { $btns.html('열기'); } }); }); }; init(this); return $(this); }, }); // sectionAccordionFunc $.extend($.fn, { sectionAccordionFunc: function () { var init = function (obj) { $(document).on('click', '.btn-section-accordion-toggle', function () { const $btn = $(this); const $area = $(this).closest('.section-accordion'); toggleCommonFunc({ obj: $area, className: 'is-close', hasClass: function () { $btn.html('열기'); }, noneClass: function () { $btn.html('접기'); } }); }); }; init(this); return $(this); }, }); // stepUnitAccordionFunc $.extend($.fn, { stepUnitAccordionFunc: function () { var init = function (obj) { $(document).on('click', '.btn-step-unit-accordion-toggle', function () { const $btn = $(this); const $area = $(this).closest('.step-unit-accordion'); toggleCommonFunc({ obj: $area, className: 'is-close', hasClass: function () {}, noneClass: function () {} }); }); }; init(this); return $(this); }, }); // tabsNormalFunc $.extend($.fn, { tabsNormalFunc: function () { const init = function (obj) { const showTab = function (tabSelector) { $(tabSelector).addClass('is-active'); const $tabsNav = $(tabSelector).find("[class^='tabs-nav'] a.is-active"); if ($tabsNav.length > 0) { const tabHref = $tabsNav.attr('href'); const $tabsCont = $(tabSelector).find('.tabs-cont' + tabHref); $tabsCont.addClass('is-active'); } }; const showInitialTabs = function () { const $currentTab = $(obj).children("[class^='tabs-nav']").find('a.is-active'); const $currentTabCont = $currentTab.attr('href'); showTab($currentTabCont); $(obj).find('.tabs-normal').not(':first').each(function () { init(this); }); }; const setActiveTab = function (tabLink) { if (!$(tabLink).hasClass("is-active")) { $(tabLink).closest("[class^='tabs-nav']").find('a').removeClass("is-active").removeAttr("title"); $(tabLink).addClass("is-active").attr("title", "선택됨"); } }; const hideTabs = function (tabsContainer) { $(tabsContainer).find('.tabs-cont').removeClass('is-active').removeAttr("title"); }; const handleTabClick = function (e) { const $tabLink = $(this); const $tabsNormal = $tabLink.closest('.tabs-normal'); setActiveTab($tabLink); hideTabs($tabsNormal); const $activeTab = $tabLink.attr('href'); showTab($activeTab); e.preventDefault(); }; $(document).on('click', ".tabs-normal .tabs-nav-lg a, .tabs-normal .tabs-nav a, .tabs-normal .tabs-nav-sm a, .tabs-normal .tabs-nav-xsm a,.tabs-normal .tabs-nav-img a", handleTabClick); showInitialTabs(); }; $(this).each(function () { init(this); }); return this; }, }); // toggleFunc $.extend($.fn, { toggleFunc: function () { var init = function (obj) { var $currentTab = $(obj).find("[data-toggle]").find('a.is-active').attr('href'); $($currentTab).show(); $(document).on('click', '[data-toggle]', function (e) { var val = $(this).data('toggle'); var $el = $('[data-toggleobj="' + val + '"]'); var $btn = $('[data-toggle="' + val + '"]'); toggleCommonFunc({ obj: $btn, className: 'is-active', hasClass: function () { $el.css({'display': 'flex'}); }, noneClass: function () { $el.css({'display': 'none'}); } }); }); }; init(this); return $(this); }, }); // btnToggleFunc $.extend($.fn, { btnToggleFunc: function () { var init = function (obj) { $(document).on('click', '.btn-toggle, .btn.toggle, .btn-text.toggle', function (e) { let $btn = $(this); toggleCommonFunc({ obj: $btn, className: 'is-active', hasClass: function () { if ($btn.attr("data-txt")) $btn.html($btn.data("txt")); if ($btn.attr("data-toast")) toastShow($btn.data("toast")); if ($btn.attr('data-btntoggle')) $('[data-btntoggleobj="' + $btn.data('btntoggle') + '"]').addClass('is-active'); }, noneClass: function () { if ($btn.attr("data-txt-inactive")) $btn.html($btn.data("txt-inactive")); if ($btn.attr("data-toast-inactive")) toastShow($btn.data("toast-inactive")); if ($btn.attr('data-btntoggle')) $('[data-btntoggleobj="' + $btn.data('btntoggle') + '"]').removeClass('is-active'); } }); }); }; init(this); return $(this); }, }); // tipFunc $.extend($.fn, { tipFunc: function () { var init = function (obj) { var txt = $(obj).find("[data-tip]:checked").data('tip'); var $tip = $(obj).find('.tip-txt'); $tip.css({'display': 'flex'}).html(txt); $(document).on('click', '[data-tip]', function (e) { var $area = $(this).closest('.tip-area'); $tip = $area.find('.tip-txt'); $tip.css({'display': 'flex'}).html($(this).data('tip')); }); }; init(this); return $(this); }, }); // tooltipFunc $.extend($.fn, { tooltipFunc: function () { var init = function (obj) { $(document).on('click', '.btn-tooltip', function (e) { var $area = $(this).closest('.tooltip'); $('.tooltip').removeClass('is-active'); toggleCommonFunc({ obj: $area, className: 'is-active' }); }); $(document).click(function (e) { if (!$(e.target).is('.btn-tooltip')) { $('.tooltip').removeClass('is-active'); } }); }; init(this); return $(this); }, }); // etcFunc $.extend($.fn, { etcFunc: function () { var init = function (obj) { $(document).on('click', '.btn-etc-fnc', function (e) { var $area = $(this).closest('.etc-fnc-area'); var $el = $area.find('.etc-fnc'); toggleCommonFunc({ obj: $area, className: 'is-active', hasClass: function () { // TweenMax.fromTo($el, .5, { opacity: 0 }, { opacity: 1 }); $('.etc-fnc-area').not($area).removeClass('is-active'); }, noneClass: function () { // TweenMax.fromTo($el, .5, { opacity: 1 }, { opacity: 0 }); } }); }); $(document).click(function (e) { if (!$(e.target).is('.btn-etc-fnc')) { $('.etc-fnc-area').removeClass('is-active'); } }); }; init(this); return $(this); }, }); // headerUserFunc $.extend($.fn, { headerUserFunc: function () { var init = function (obj) { $(document).on('click', '.site-header .btn-user-fnc-toggle', function (e) { var $btn = $(this); var $area = $btn.closest('.user-area'); toggleCommonFunc({ obj: $area, className: 'is-active', hasClass: function () { $btn.html('열기'); }, noneClass: function () { $btn.html('닫기'); } }); }); $(document).click(function (e) { if (!$(e.target).is('.site-header .btn-user-fnc-toggle')) { $('.site-header .user-area').removeClass('is-active'); } }); }; init(this); return $(this); }, }); // btnUtilFunc $.extend($.fn, { btnUtilFunc: function () { var init = function (obj) { $(document).on('click', '.btn-util-toggle', function (e) { e.stopPropagation(); var $btn = $(this); var $area = $btn.closest('.btn-util-area'); toggleCommonFunc({ obj: $area, className: 'is-active' }); }); $(document).click(function (e) { if (!$(e.target).closest('.btn-util-area').length) { $('.btn-util-area').removeClass('is-active'); } }); }; init(this); return $(this); }, }); // siteMenuFunc $.extend($.fn, { siteMenuFunc: function () { var init = function (obj) { $(document).on("click", ".btn-site-menu-open", function () { $(".site-menu-area").addClass("is-active"); }); $(document).on("click", ".btn-site-menu-close", function () { $(".menu > li > ul > li").removeClass("is-active"); $(".site-menu-area").removeClass("is-active"); }); $(document).on("click", ".site-menu-area", function (e) { if (!$(e.target).closest(".site-menu").length) { $(".btn-site-menu-close").trigger("click"); } }); $(document).on("click", ".site-header .menu > li > ul > li > a", function (e) { if ($(this).next("ul").length) { e.preventDefault(); let $parentLi = $(this).closest('li'); let isActive = $parentLi.hasClass("is-active"); $(".menu > li > ul > li").removeClass("is-active"); if (!isActive) $parentLi.addClass("is-active"); } }); }; init(this); return $(this); }, }); $.extend($.fn, { viewermenuFunc: function () { return this.each(function () { $(document).on('click', '.btn-viewer-menu, .btn-viewer-menu-toggle, .viewer-menu-dim', function () { $('.tabs-normal').tabsNormalFunc(); toggleCommonFunc({ obj: '.viewer', className: 'is-active' }); }); }); }, classViewermenuFunc: function () { return this.each(function () { $(document).on('click', '.btn-class-viewer-menu', function () { $('.tabs-normal').tabsNormalFunc(); toggleCommonFunc({ obj: '.class-viewer', className: 'is-active' }); }); }); }, qGroupFunc: function () { return this.each(function () { $(document).on('click', '.btn-q-group-toggle', function () { const $btn = $(this); const $area = $btn.closest('.q-group-area'); if ($area.hasClass('is-close')) { setTimeout(() => { $area.removeClass('is-close'); $btn.find('span').text('닫기'); }, 290); } else { $area.addClass('is-close'); $btn.find('span').text('열기'); } }); }); }, thumbSwiper: function () { return this.each(function () { new Swiper(this, { preloadImages: false, lazy: { loadPrevNext: true }, slidesPerView: 5, initialSlide: 0, watchSlidesProgress: true, spaceBetween: 15, loop: false, freeMode: true, navigation: { prevEl: '.swiper-button-prev', nextEl: '.swiper-button-next' }, breakpoints: { 0: { slidesPerView: 2.05, spaceBetween: 8 }, 767: { slidesPerView: 3.1, spaceBetween: 20 }, 1279: { slidesPerView: 4, spaceBetween: 20, freeMode: false } } }); }); }, thumbSwiperSm: function () { return this.each(function () { const isThumb3 = $(this).hasClass('thumb3'); new Swiper(this, { preloadImages: false, lazy: { loadPrevNext: true }, slidesPerView: 5, initialSlide: 0, watchSlidesProgress: true, spaceBetween: 8, loop: false, freeMode: true, navigation: { prevEl: '.swiper-button-prev', nextEl: '.swiper-button-next' }, breakpoints: isThumb3 ? { 0: { slidesPerView: 2.05 }, 767: { slidesPerView: 3.1 }, 1279: { slidesPerView: 3, freeMode: false } } : { 0: { slidesPerView: 2.05 }, 767: { slidesPerView: 3.1 }, 1279: { slidesPerView: 4, freeMode: false } } }); }); }, imgSwiper: function () { return this.each(function () { const $area = $(this).find('.img-area'); const $el = $(this).find('.img-swiper'); const $btnPrev = $area.find('.swiper-button-prev'); const $btnNext = $area.find('.swiper-button-next'); const $thumbArea = $(this).find('.img-thumb-area'); const $thumb = $(this).find('.img-thumb-swiper'); const $thumbBtnPrev = $thumbArea.find('.swiper-button-prev'); const $thumbBtnNext = $thumbArea.find('.swiper-button-next'); const imgThumbSwiper = new Swiper($thumb[0], { direction: 'vertical', slidesPerView: 5.4, spaceBetween: 8, navigation: { prevEl: $thumbBtnPrev[0], nextEl: $thumbBtnNext[0] }, watchSlidesProgress: true, }); const imgSwiper = new Swiper($el[0], { spaceBetween: 0, navigation: { prevEl: $btnPrev[0], nextEl: $btnNext[0] }, thumbs: { swiper: imgThumbSwiper, }, }); }); }, mnPopupSwiper: function () { return this.each(function () { const $el = $(this).find('.swiper'); const $btnPrev = $(this).find('.swiper-button-prev')[0]; const $btnNext = $(this).find('.swiper-button-next')[0]; const $btnPlayStop = $(this).find('.swiper-btn-playstop-toggle')[0]; const $btnsPagination = $(this).find('.swiper-total')[0]; let isPaused = false; let slideCount = $el.find('.swiper-slide').length; // 현재 브레이크포인트에서 slidesPerView 값 설정 let getSlidesPerView = function () { var width = window.innerWidth; if (width >= 1023) return 3; if (width >= 767) return 2; return 1; }; let slidesPerView = getSlidesPerView(); let enableAutoplay = slideCount > slidesPerView; //var enableLoop = slideCount > slidesPerView; //var enableCenteredSlides = slideCount < slidesPerView; if (slideCount < slidesPerView) { $el.addClass('is-inactive');}; const swiper = new Swiper($el[0], { preloadImages: true, spaceBetween: 16, //centeredSlides: enableCenteredSlides, autoplay: enableAutoplay ? { delay: 4000, disableOnInteraction: false, } : false, // loop: enableLoop, loopedSlides: 0, speed: 1000, initialSlide: 0, watchSlidesProgress: true, navigation: { prevEl: $btnPrev, nextEl: $btnNext }, breakpoints: { 480: { slidesPerView: 1, }, 767: { slidesPerView: 2, spaceBetween: 16, }, 1023: { slidesPerView: 3, spaceBetween: 40, }, }, pagination: { el: $btnsPagination, type: "custom", renderCustom: function (swiper, current, total) { return ` ${slideCount} `; }, }, }); // 중지 버튼 클릭 이벤트 $($btnPlayStop).on('click', function() { if (isPaused) { // 슬라이드 재생 swiper.autoplay.start(); $(this).removeClass('is-stop').text('중지'); // 버튼 텍스트 변경 isPaused = false; } else { // 슬라이드 정지 swiper.autoplay.stop(); $(this).addClass('is-stop').text('재생'); // 버튼 텍스트 변경 isPaused = true; } }); $(window).on('resize', function () { var newSlidesPerView = getSlidesPerView(); var wasAutoplayEnabled = enableAutoplay; slidesPerView = newSlidesPerView; enableAutoplay = slideCount > slidesPerView; if (slideCount < slidesPerView) { $el.addClass('is-inactive'); } else { $el.removeClass('is-inactive'); } if (enableAutoplay && !wasAutoplayEnabled) { swiper.params.autoplay = { delay: 3000, disableOnInteraction: false }; if (!isPaused) { swiper.autoplay.start(); $($btnPlayStop).removeClass('is-stop').text('중지'); } } else if (!enableAutoplay && wasAutoplayEnabled) { swiper.autoplay.stop(); swiper.params.autoplay = false; $($btnPlayStop).addClass('is-stop').text('재생'); isPaused = true; } }); }); } }); })(jQuery); // $(document).ready(function () { // $('.accordion, .accordion-nav, .accordion-list').accordionFunc(); // $('.tabs-normal').tabsNormalFunc(); // $('[data-toggle]').toggleFunc(); // $('.btn-toggle, .btn.toggle, .btn-text.toggle').btnToggleFunc(); // $('.tip-area').tipFunc(); // $('.tooltip').tooltipFunc(); // $('.etc-fnc-area').etcFunc(); // $('.site-menu-area').siteMenuFunc(); // }); $(document).ready(function () { $('.accordion, .accordion-nav, .accordion-list').accordionFunc(); $('.section-accordion').sectionAccordionFunc(); $('.step-unit-accordion').stepUnitAccordionFunc(); $('.tabs-normal').tabsNormalFunc(); $('[data-toggle]').toggleFunc(); $('.btn-toggle, .btn.toggle, .btn-text.toggle').btnToggleFunc(); $('.tip-area').tipFunc(); $('.tooltip').tooltipFunc(); $('.etc-fnc-area').etcFunc(); //$('.search-box').schboxFunc(); $('.site-header .user-area').headerUserFunc(); $('.btn-util-area').btnUtilFunc(); $('.site-menu-area').siteMenuFunc(); //class $('.viewer .viewer-menu-area').viewermenuFunc(); $('.class-viewer .viewer-menu-area').classViewermenuFunc(); $('.q-group-area').qGroupFunc(); //swiper $('.thumb-swiper').thumbSwiper(); $('.img-swiper-area').imgSwiper(); $('.mn-popup-area').mnPopupSwiper(); checkIsSticky(); window.onscroll = () => { checkIsSticky(); } }); $(document).on('keydown', '.site-header .gnb > ul > li > a, .site-header .gnb > ul > li > button', function (event) { if (event.key === 'Enter') { $(this).closest('li').addClass('is-active'); } }); $(document).on('focusout', '.site-header .gnb > ul > li.is-active > ul > li:last-child a', function (event) { setTimeout(() => { if (!$('.site-header .gnb > ul > li.is-active ul li a').is(':focus')) { $(this).closest('ul').closest('li').removeClass('is-active'); } }, 10); }); $(document).on('focusout', 'input[type=date]', function () { $(this).showPicker(); }); //비밀번호 숨기기 $(document).on('click', '.btn-pw-toggle', function () { const $btn = $(this); const $pwArea = $btn.closest('.input-pw-area'); const $input = $pwArea.find('.pw-input'); if ($input.attr('type') === 'password') { $input.attr('type', 'text'); $btn.text('비밀번호숨기기'); $pwArea.addClass('is-active'); } else { $input.attr('type', 'password'); $btn.text('비밀번호보기'); $pwArea.removeClass('is-active'); } }); // $(document).on('click', '.btn-chasi-toggle', function (e) { // var $area; // $area = $(this).closest('li'); // toggleCommonFunc({ // obj: $area, // className: 'is-active', // }); // }); //item-type 선택 $(document).on('change', '.item-type-checkradio input[type="radio"]', function () { var newType = $(this).attr('id'); $('.item-type-list').removeClass('item-type-feed item-type-thumb item-type-table').addClass(newType); });