// 전역 변수 var errmsg = ""; var errfld = null; // 필드 검사 function check_field(fld, msg) { if ((fld.value = trim(fld.value)) == "") error_field(fld, msg); else clear_field(fld); return; } // 필드 오류 표시 function error_field(fld, msg) { if (msg != "") errmsg += msg + "\n"; if (!errfld) errfld = fld; fld.style.background = "#BDDEF7"; } // 필드를 깨끗하게 function clear_field(fld) { fld.style.background = "#FFFFFF"; } function trim(s) { var t = ""; var from_pos = (to_pos = 0); for (i = 0; i < s.length; i++) { if (s.charAt(i) == " ") continue; else { from_pos = i; break; } } for (i = s.length; i >= 0; i--) { if (s.charAt(i - 1) == " ") continue; else { to_pos = i; break; } } t = s.substring(from_pos, to_pos); // alert(from_pos + ',' + to_pos + ',' + t+'.'); return t; } // 자바스크립트로 PHP의 number_format 흉내를 냄 // 숫자에 , 를 출력 function number_format(data) { var tmp = ""; var number = ""; var cutlen = 3; var comma = ","; var i; data = data + ""; var sign = data.match(/^[\+\-]/); if (sign) { data = data.replace(/^[\+\-]/, ""); } len = data.length; mod = len % cutlen; k = cutlen - mod; for (i = 0; i < data.length; i++) { number = number + data.charAt(i); if (i < data.length - 1) { k++; if (k % cutlen == 0) { number = number + comma; k = 0; } } } if (sign != null) number = sign + number; return number; } // 새 창 function popup_window(url, winname, opt) { window.open(url, winname, opt); } // 폼메일 창 function popup_formmail(url) { opt = "scrollbars=yes,width=417,height=385,top=10,left=20"; popup_window(url, "wformmail", opt); } // , 를 없앤다. function no_comma(data) { var tmp = ""; var comma = ","; var i; for (i = 0; i < data.length; i++) { if (data.charAt(i) != comma) tmp += data.charAt(i); } return tmp; } // 삭제 검사 확인 function del(href) { if ( confirm( "한번 삭제한 자료는 복구할 방법이 없습니다.\n\n정말 삭제하시겠습니까?" ) ) { document.location.href = href; } } // 쿠키 입력 function set_cookie(name, value, expirehours, domain) { var today = new Date(); today.setTime(today.getTime() + 60 * 60 * 1000 * expirehours); document.cookie = name + "=" + escape(value) + "; path=/; expires=" + today.toGMTString() + ";"; if (domain) { document.cookie += "domain=" + domain + ";"; } } // 쿠키 얻음 function get_cookie(name) { var match = document.cookie.match(new RegExp("(^| )" + name + "=([^;]+)")); if (match) return unescape(match[2]); return ""; } // 쿠키 지움 function delete_cookie(name) { var today = new Date(); today.setTime(today.getTime() - 1); var value = get_cookie(name); if (value != "") document.cookie = name + "=" + value + "; path=/; expires=" + today.toGMTString(); } var last_id = null; function menu(id) { if (id != last_id) { if (last_id != null) document.getElementById(last_id).style.display = "none"; document.getElementById(id).style.display = "block"; last_id = id; } else { document.getElementById(id).style.display = "none"; last_id = null; } } function textarea_decrease(id, row) { if (document.getElementById(id).rows - row > 0) document.getElementById(id).rows -= row; } function textarea_original(id, row) { document.getElementById(id).rows = row; } function textarea_increase(id, row) { document.getElementById(id).rows += row; } // 글숫자 검사 function check_byte(content, target) { var i = 0; var cnt = 0; var ch = ""; var cont = document.getElementById(content).value; for (i = 0; i < cont.length; i++) { ch = cont.charAt(i); if (escape(ch).length > 4) { cnt += 2; } else { cnt += 1; } } // 숫자를 출력 document.getElementById(target).innerHTML = cnt; return cnt; } // 브라우저에서 오브젝트의 왼쪽 좌표 function get_left_pos(obj) { var parentObj = null; var clientObj = obj; //var left = obj.offsetLeft + document.body.clientLeft; var left = obj.offsetLeft; while ((parentObj = clientObj.offsetParent) != null) { left = left + parentObj.offsetLeft; clientObj = parentObj; } return left; } // 브라우저에서 오브젝트의 상단 좌표 function get_top_pos(obj) { var parentObj = null; var clientObj = obj; //var top = obj.offsetTop + document.body.clientTop; var top = obj.offsetTop; while ((parentObj = clientObj.offsetParent) != null) { top = top + parentObj.offsetTop; clientObj = parentObj; } return top; } function flash_movie(src, ids, width, height, wmode) { var wh = ""; if (parseInt(width) && parseInt(height)) wh = " width='" + width + "' height='" + height + "' "; return ( "" ); } function obj_movie(src, ids, width, height, autostart) { var wh = ""; if (parseInt(width) && parseInt(height)) wh = " width='" + width + "' height='" + height + "' "; if (!autostart) autostart = false; return ( "" ); } function doc_write(cont) { document.write(cont); } var win_password_lost = function (href) { window.open( href, "win_password_lost", "left=50, top=50, width=617, height=330, scrollbars=1" ); }; $(document).ready(function () { $("#login_password_lost, #ol_password_lost").click(function () { win_password_lost(this.href); return false; }); }); /** * 포인트 창 **/ var win_point = function (href) { var new_win = window.open( href, "win_point", "left=100,top=100,width=600, height=600, scrollbars=1" ); new_win.focus(); }; /** * 쪽지 창 **/ var win_memo = function (href) { var new_win = window.open( href, "win_memo", "left=100,top=100,width=620,height=500,scrollbars=1" ); new_win.focus(); }; /** * 쪽지 창 **/ var check_goto_new = function (href, event) { if (!(typeof g5_is_mobile != "undefined" && g5_is_mobile)) { if ( window.opener && window.opener.document && window.opener.document.getElementById ) { event.preventDefault ? event.preventDefault() : (event.returnValue = false); window.open(href); //window.opener.document.location.href = href; } } }; /** * 메일 창 **/ var win_email = function (href) { var new_win = window.open( href, "win_email", "left=100,top=100,width=600,height=580,scrollbars=1" ); new_win.focus(); }; /** * 자기소개 창 **/ var win_profile = function (href) { var new_win = window.open( href, "win_profile", "left=100,top=100,width=620,height=510,scrollbars=1" ); new_win.focus(); }; /** * 스크랩 창 **/ var win_scrap = function (href) { var new_win = window.open( href, "win_scrap", "left=100,top=100,width=600,height=600,scrollbars=1" ); new_win.focus(); }; /** * 홈페이지 창 **/ var win_homepage = function (href) { var new_win = window.open(href, "win_homepage", ""); new_win.focus(); }; /** * 우편번호 창 **/ var win_zip = function ( frm_name, frm_zip, frm_addr1, frm_addr2, frm_addr3, frm_jibeon ) { if (typeof daum === "undefined") { alert("KAKAO 우편번호 서비스 postcode.v2.js 파일이 로드되지 않았습니다."); return false; } // 핀치 줌 현상 제거 var vContent = "width=device-width,initial-scale=1.0,minimum-scale=0,maximum-scale=10"; $("#meta_viewport").attr("content", vContent + ",user-scalable=no"); var zip_case = 1; //0이면 레이어, 1이면 페이지에 끼워 넣기, 2이면 새창 var complete_fn = function (data) { // 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분. // 각 주소의 노출 규칙에 따라 주소를 조합한다. // 내려오는 변수가 값이 없는 경우엔 공백('')값을 가지므로, 이를 참고하여 분기 한다. var fullAddr = ""; // 최종 주소 변수 var extraAddr = ""; // 조합형 주소 변수 // 사용자가 선택한 주소 타입에 따라 해당 주소 값을 가져온다. if (data.userSelectedType === "R") { // 사용자가 도로명 주소를 선택했을 경우 fullAddr = data.roadAddress; } else { // 사용자가 지번 주소를 선택했을 경우(J) fullAddr = data.jibunAddress; } // 사용자가 선택한 주소가 도로명 타입일때 조합한다. if (data.userSelectedType === "R") { //법정동명이 있을 경우 추가한다. if (data.bname !== "") { extraAddr += data.bname; } // 건물명이 있을 경우 추가한다. if (data.buildingName !== "") { extraAddr += extraAddr !== "" ? ", " + data.buildingName : data.buildingName; } // 조합형주소의 유무에 따라 양쪽에 괄호를 추가하여 최종 주소를 만든다. extraAddr = extraAddr !== "" ? " (" + extraAddr + ")" : ""; } // 우편번호와 주소 정보를 해당 필드에 넣고, 커서를 상세주소 필드로 이동한다. var of = document[frm_name]; of[frm_zip].value = data.zonecode; of[frm_addr1].value = fullAddr; of[frm_addr3].value = extraAddr; if (of[frm_jibeon] !== undefined) { of[frm_jibeon].value = data.userSelectedType; } setTimeout(function () { $("#meta_viewport").attr("content", vContent); of[frm_addr2].focus(); }, 100); }; switch (zip_case) { case 1: //iframe을 이용하여 페이지에 끼워 넣기 var daum_pape_id = "daum_juso_page" + frm_zip, element_wrap = document.getElementById(daum_pape_id), currentScroll = Math.max( document.body.scrollTop, document.documentElement.scrollTop ); if (element_wrap == null) { element_wrap = document.createElement("div"); element_wrap.setAttribute("id", daum_pape_id); element_wrap.style.cssText = "display:none;border:1px solid;left:0;width:100%;height:300px;margin:5px 0;position:relative;-webkit-overflow-scrolling:touch;"; element_wrap.innerHTML = '접기 버튼'; jQuery('form[name="' + frm_name + '"]') .find('input[name="' + frm_addr1 + '"]') .before(element_wrap); jQuery("#" + daum_pape_id) .off("click", ".close_daum_juso") .on("click", ".close_daum_juso", function (e) { e.preventDefault(); $("#meta_viewport").attr("content", vContent); jQuery(this).parent().hide(); }); } new daum.Postcode({ oncomplete: function (data) { complete_fn(data); // iframe을 넣은 element를 안보이게 한다. element_wrap.style.display = "none"; // 우편번호 찾기 화면이 보이기 이전으로 scroll 위치를 되돌린다. document.body.scrollTop = currentScroll; }, // 우편번호 찾기 화면 크기가 조정되었을때 실행할 코드를 작성하는 부분. // iframe을 넣은 element의 높이값을 조정한다. onresize: function (size) { element_wrap.style.height = size.height + "px"; }, maxSuggestItems: g5_is_mobile ? 6 : 10, width: "100%", height: "100%", }).embed(element_wrap); // iframe을 넣은 element를 보이게 한다. element_wrap.style.display = "block"; break; case 2: //새창으로 띄우기 new daum.Postcode({ oncomplete: function (data) { complete_fn(data); }, }).open(); break; default: //iframe을 이용하여 레이어 띄우기 var rayer_id = "daum_juso_rayer" + frm_zip, element_layer = document.getElementById(rayer_id); if (element_layer == null) { element_layer = document.createElement("div"); element_layer.setAttribute("id", rayer_id); element_layer.style.cssText = "display:none;border:5px solid;position:fixed;width:300px;height:460px;left:50%;margin-left:-155px;top:50%;margin-top:-235px;overflow:hidden;-webkit-overflow-scrolling:touch;z-index:10000"; element_layer.innerHTML = '닫기 버튼'; document.body.appendChild(element_layer); jQuery("#" + rayer_id) .off("click", ".close_daum_juso") .on("click", ".close_daum_juso", function (e) { e.preventDefault(); $("#meta_viewport").attr("content", vContent); jQuery(this).parent().hide(); }); } new daum.Postcode({ oncomplete: function (data) { complete_fn(data); // iframe을 넣은 element를 안보이게 한다. element_layer.style.display = "none"; }, maxSuggestItems: g5_is_mobile ? 6 : 10, width: "100%", height: "100%", }).embed(element_layer); // iframe을 넣은 element를 보이게 한다. element_layer.style.display = "block"; } }; /** * 새로운 비밀번호 분실 창 : 101123 **/ win_password_lost = function (href) { var new_win = window.open( href, "win_password_lost", "width=617, height=330, scrollbars=1" ); new_win.focus(); }; /** * 설문조사 결과 **/ var win_poll = function (href) { var new_win = window.open( href, "win_poll", "width=616, height=500, scrollbars=1" ); new_win.focus(); }; /** * 쿠폰 **/ var win_coupon = function (href) { var new_win = window.open( href, "win_coupon", "left=100,top=100,width=700, height=600, scrollbars=1" ); new_win.focus(); }; /** * 스크린리더 미사용자를 위한 스크립트 - 지운아빠 2013-04-22 * alt 값만 갖는 그래픽 링크에 마우스오버 시 title 값 부여, 마우스아웃 시 title 값 제거 **/ $(function () { $("a img") .mouseover(function () { $a_img_title = $(this).attr("alt"); $(this).attr("title", $a_img_title); }) .mouseout(function () { $(this).attr("title", ""); }); }); /** * 텍스트 리사이즈 **/ function font_resize(id, rmv_class, add_class, othis) { var $el = $("#" + id); if ( (typeof rmv_class !== "undefined" && rmv_class) || (typeof add_class !== "undefined" && add_class) ) { $el.removeClass(rmv_class).addClass(add_class); set_cookie("ck_font_resize_rmv_class", rmv_class, 1, g5_cookie_domain); set_cookie("ck_font_resize_add_class", add_class, 1, g5_cookie_domain); } if (typeof othis !== "undefined") { $(othis).addClass("select").siblings().removeClass("select"); } } /** * 댓글 수정 토큰 **/ function set_comment_token(f) { if (typeof f.token === "undefined") $(f).prepend(''); $.ajax({ url: g5_bbs_url + "/ajax.comment_token.php", type: "GET", dataType: "json", async: false, cache: false, success: function (data, textStatus) { f.token.value = data.token; }, }); } $(function () { $(".win_point").click(function () { win_point(this.href); return false; }); $(".win_memo").click(function () { win_memo(this.href); return false; }); $(".win_email").click(function () { win_email(this.href); return false; }); $(".win_scrap").click(function () { win_scrap(this.href); return false; }); $(".win_profile").click(function () { win_profile(this.href); return false; }); $(".win_homepage").click(function () { win_homepage(this.href); return false; }); $(".win_password_lost").click(function () { win_password_lost(this.href); return false; }); /* $(".win_poll").click(function() { win_poll(this.href); return false; }); */ $(".win_coupon").click(function () { win_coupon(this.href); return false; }); // 사이드뷰 var sv_hide = false; $(".sv_member, .sv_guest").click(function () { $(".sv").removeClass("sv_on"); $(this).closest(".sv_wrap").find(".sv").addClass("sv_on"); }); $(".sv, .sv_wrap").hover( function () { sv_hide = false; }, function () { sv_hide = true; } ); $(".sv_member, .sv_guest").focusin(function () { sv_hide = false; $(".sv").removeClass("sv_on"); $(this).closest(".sv_wrap").find(".sv").addClass("sv_on"); }); $(".sv a").focusin(function () { sv_hide = false; }); $(".sv a").focusout(function () { sv_hide = true; }); // 셀렉트 ul var sel_hide = false; $(".sel_btn").click(function () { $(".sel_ul").removeClass("sel_on"); $(this).siblings(".sel_ul").addClass("sel_on"); }); $(".sel_wrap").hover( function () { sel_hide = false; }, function () { sel_hide = true; } ); $(".sel_a").focusin(function () { sel_hide = false; }); $(".sel_a").focusout(function () { sel_hide = true; }); $(document).click(function () { if (sv_hide) { // 사이드뷰 해제 $(".sv").removeClass("sv_on"); } if (sel_hide) { // 셀렉트 ul 해제 $(".sel_ul").removeClass("sel_on"); } }); $(document).focusin(function () { if (sv_hide) { // 사이드뷰 해제 $(".sv").removeClass("sv_on"); } if (sel_hide) { // 셀렉트 ul 해제 $(".sel_ul").removeClass("sel_on"); } }); $(document).on("keyup change", "textarea#wr_content[maxlength]", function () { var str = $(this).val(); var mx = parseInt($(this).attr("maxlength")); if (str.length > mx) { $(this).val(str.substr(0, mx)); return false; } }); }); function get_write_token(bo_table) { var token = ""; $.ajax({ type: "POST", url: g5_bbs_url + "/write_token.php", data: { bo_table: bo_table }, cache: false, async: false, dataType: "json", success: function (data) { if (data.error) { alert(data.error); if (data.url) document.location.href = data.url; return false; } token = data.token; }, }); return token; } $(function () { $(document).on( "click", "form[name=fwrite] input:submit, form[name=fwrite] button:submit, form[name=fwrite] input:image", function () { var f = this.form; if (typeof f.bo_table == "undefined") { return; } var bo_table = f.bo_table.value; var token = get_write_token(bo_table); if (!token) { alert("토큰 정보가 올바르지 않습니다."); return false; } var $f = $(f); if (typeof f.token === "undefined") $f.prepend(''); $f.find("input[name=token]").val(token); return true; } ); }); //디자인팀 작업 내용 추가 // include.js window.addEventListener("load", function () { var allElements = document.getElementsByTagName("*"); Array.prototype.forEach.call(allElements, function (el) { var includePath = el.dataset.includePath; if (includePath) { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function () { if (this.readyState == 4 && this.status == 200) { el.outerHTML = this.responseText; } }; xhttp.open("GET", includePath, true); xhttp.send(); } }); }); $(function () { document.querySelector("head title").textContent = "EG-BIM"; }); // ★★ lenis 멈추기 ★★ function handlePopupScroll(e) { $("body").css("overflow", "hidden"); $("body").on("wheel", function (e) { e.stopPropagation(); }); $("body").on("touchmove", function (e) { e.stopPropagation(); }); lenis.stop(); } // 각 팝업창 불러오기 function agreement() { $(".popup_wrap").hide(); $(".btn_close").show(); $("#pop_agreement").show(0, function () { //팝업창 열때 체크박스 모두 해제 $("#fregister input[type=checkbox]").prop("checked", false); $("#reg_mb_id").val(""); handlePopupScroll(); console.log("body stop 완료"); // $.getScript("../js/popup.js", function () {}); }); } //250813 송대일 추가 agreement() 수정 // function agreement() { // $(".popup_wrap").hide(); // $(".btn_close").show(); // $("#pop_agreement").show(0, function () { // // 팝업 열 때 체크박스 모두 해제 // $("#fregister input[type=checkbox]").prop("checked", false); // $("#reg_mb_id").val(""); // // ★ 동의 버튼 강제 활성화 (혹시 다른 스크립트가 disabled 걸었을 경우 대비) // $('#btn_agree, #fregister button[type=submit]').prop('disabled', false) // .css('pointer-events', 'auto'); // handlePopupScroll(); // console.log("body stop 완료"); // // ★ 이 줄이 문제 가능성이 큽니다. 매번 popup.js를 다시 실행시키지 마세요. // // $.getScript("../js/popup.js", function () {}); // }); // } function join() { $(".popup_wrap").hide(); $("#pop_join").show(0, function () { //회원가입 입력창 비밀번호 자동 입력 제거 $("#reg_mb_password").val(""); handlePopupScroll(); console.log("body stop 완료"); // $.getScript("../js/popup.js", function () {}); }); } function login() { if (typeof window.openOidcLogin === "function") { window.openOidcLogin(); return; } $(".popup_wrap").hide(); //새로고침 없이 다시 팝업창 열었을때 자동 입력된 id, pw 제거 $("#login_id").val(""); $("#login_pw").val(""); $("#pop_login").show(0, function () { handlePopupScroll(); console.log("body stop 완료"); // $.getScript("../js/popup.js", function () {}); }); } function mypage01() { const raw = (window.IDP_SERVICE_URL || "").trim(); if (raw) { const url = raw.replace(/\/+$/, "") + "/profile"; window.open(url, "idp_profile", "noopener,noreferrer"); return; } $(".popup_wrap").hide(); $(".btn_close").show(); $("#pop_mypage01").show(0, function () { handlePopupScroll(); console.log("body stop 완료"); // $.getScript("../js/popup.js", function () {}); }); } function mypage02() { $(".popup_wrap").hide(); $("#pop_mypage02").show(0, function () { handlePopupScroll(); console.log("body stop 완료"); // $.getScript("../js/popup.js", function () {}); }); } function mypage03() { $(".popup_wrap").hide(); $("#pop_mypage03").show(0, function () { handlePopupScroll(); // 팝업이 완전히 열릴 때마다 사용자 정보 재조회 if (typeof loadDescopeUser === "function") { loadDescopeUser(); } console.log("body stop 완료"); // $.getScript("../js/popup.js", function () {}); }); } function search() { $(".popup_wrap").hide(); $("#pop_search").show(0, function () { handlePopupScroll(); //비밀번호 재설정 입력창 아이디 자동입력 제거 $("#txt_name").val(""); //비밀번호 재설정 입력창 비밀번호 자동입력 제거 $("#pw_reset1").val(""); //비밀번호 재설정 버튼 클릭시 아이디 입력창 띄움 $("#pop_search .popup_contents_wrap").hide(); $("#pop_search .popup_contents_wrap").eq(0).show(); console.log("body stop 완료"); // $.getScript("../js/popup.js", function () {}); }); } function sitemap() { const $popup = $(".popup_sitemap"); if ($popup.css("display") === "none") { $("#sitemap").show(0, function () { $(".menu_ham").addClass("btn_map_close"); handlePopupScroll(); console.log("body stop 완료"); // $.getScript("../js/popup.js", function () {}); }); } else { $(".popup_sitemap").hide(); $(".menu_ham").removeClass("btn_map_close"); $("body").css("overflow", ""); // 기본 스크롤 상태로 복귀 lenis.start(); } } function privacy(type) { $(".popup_wrap").hide(); $("#pop_privacy").show(0, function () { handlePopupScroll(); console.log("body stop 완료"); $.getScript("../js/popup.js", function () { if (type === "privacy") { $("#pop_privacy li.tab_privacy").addClass("on"); $("#pop_privacy li.tab_agreement").removeClass("on"); $(".content.pri").addClass("show").removeClass("hide"); $(".content.agr").removeClass("show").addClass("hide"); } else if (type === "agreement") { $("#pop_privacy li.tab_agreement").addClass("on"); $("#pop_privacy li.tab_privacy").removeClass("on"); $(".content.agr").addClass("show").removeClass("hide"); $(".content.pri").removeClass("show").addClass("hide"); } }); }); } // FOOTER - top버튼 위치 조정하기 // document.addEventListener("DOMContentLoaded", (event) => { // const topButton = document.querySelector(".btn_top"); // function adjustButtonPosition() { // const scrollY = window.scrollY; // 현재 스크롤 위치 // const windowHeight = window.innerHeight; // 윈도우 높이 // const documentHeight = document.documentElement.scrollHeight; // 문서 전체 높이 // const bottomSpace = 220; // 탑 버튼이 아래에서 떨어져 있어야 하는 거리 // // const buttonHeight = topButton.offsetHeight; // 탑 버튼의 높이 // // 문서의 맨 아래로부터 300px 떨어지기 위한 계산 // if (scrollY + windowHeight >= documentHeight - bottomSpace) { // topButton.style.bottom = `${ // bottomSpace + (scrollY + windowHeight - documentHeight) // }px`; // } else { // topButton.style.bottom = "60px"; // 원래의 위치 // } // } // window.addEventListener("scroll", adjustButtonPosition); // window.addEventListener("load", adjustButtonPosition); // const showNav = gsap // .from(".js__header", { // yPercent: -200, // paused: true, // duration: 0.2, // }) // .progress(1); // ScrollTrigger.create({ // start: "top top", // end: 99999, // onUpdate: (self) => { // self.direction === -1 ? showNav.play() : showNav.reverse(); // }, // }); // // 새로운 코드 추가 - topButton의 표시/숨기기 로직 // function toggleTopButtonClass() { // if (window.scrollY === 0) { // topButton.classList.remove("topbtn_on"); // topButton.classList.add("topbtn_off"); // 스크롤이 맨 위일 때 topbtn_off 추가 // } else { // topButton.classList.remove("topbtn_off"); // topButton.classList.add("topbtn_on"); // 스크롤이 내려가면 topbtn_on으로 변경 // } // } // window.addEventListener("scroll", toggleTopButtonClass); // window.addEventListener("load", toggleTopButtonClass); // 페이지 로드 시 초기 상태 설정 // }); //250812 송대일 수정 document.addEventListener("DOMContentLoaded", () => { const topButton = document.querySelector(".btn_top"); // rAF 스로틀링 let scheduled = false; const schedule = (fn) => { if (scheduled) return; scheduled = true; requestAnimationFrame(() => { fn(); scheduled = false; }); }; function adjustButtonPosition() { if (!topButton) return; // ← 가드 const scrollY = window.scrollY; const windowHeight = window.innerHeight; const documentHeight = document.documentElement.scrollHeight; const bottomSpace = 120; if (scrollY + windowHeight >= documentHeight - bottomSpace) { topButton.style.bottom = `${ bottomSpace + (scrollY + windowHeight - documentHeight) }px`; } else { topButton.style.bottom = "60px"; } } function toggleTopButtonClass() { if (!topButton) return; // ← 가드 if (window.scrollY === 0) { topButton.classList.remove("topbtn_on"); topButton.classList.add("topbtn_off"); } else { topButton.classList.remove("topbtn_off"); topButton.classList.add("topbtn_on"); } } // .btn_top 이 있을 때만 바인딩 if (topButton) { const onScroll = () => schedule(() => { adjustButtonPosition(); toggleTopButtonClass(); }); window.addEventListener("scroll", onScroll, { passive: true }); window.addEventListener("load", () => { adjustButtonPosition(); toggleTopButtonClass(); }); } // ── 헤더 애니메이션 (GSAP/ScrollTrigger가 있을 때만) if (window.gsap) { try { if (window.ScrollTrigger && gsap.registerPlugin) { gsap.registerPlugin(ScrollTrigger); } const showNav = gsap .from(".js__header", { yPercent: -200, paused: true, duration: 0.2, }) .progress(1); if (window.ScrollTrigger) { ScrollTrigger.create({ start: "top top", end: 99999, onUpdate: (self) => { self.direction === -1 ? showNav.play() : showNav.reverse(); }, }); } } catch (e) { console.error(e); } } }); // FOOTER - 패밀리사이트 열고닫기 $(function () { $(".menu_my").mouseover(function () { $(".menu_my_list").show(); }); $(".menu_my").mouseout(function () { $(".menu_my_list").hide(); }); //footer family site toggle $(".family_btn").click(function (event) { event.stopPropagation(); // family_btn 클릭 시 이벤트 전파를 막음 $(".family_list").toggleClass("family_on"); $(".family_btn").toggleClass("family_on"); }); // 화면 아무 곳이나 클릭했을 때 family_list를 제외한 영역 클릭 시 리스트 닫기 $(document).click(function (event) { if ( !$(event.target).closest(".family_list").length && !$(event.target).closest(".family_btn").length ) { // family_list와 family_btn 외의 영역을 클릭한 경우 $(".family_list").removeClass("family_on"); $(".family_btn").removeClass("family_on"); } }); }); // 마우스 스크롤 마크 표시하기 // 사용 클래스 : js__mouse_mark , js__mouse_area // + TODO 진슬 추가_ addEventListener error debugging window.onload = function () { document.addEventListener("DOMContentLoaded", () => { const mouseMark = document.querySelector(".js__mouse_mark"); const mouseArea = document.querySelector(".js__mouse_area"); const mouseNot = document.querySelector(".js__mouse_not"); mouseArea.addEventListener("mousemove", (e) => { mouseMark.style.left = `${e.clientX}px`; mouseMark.style.top = `${e.clientY}px`; mouseMark.style.display = "flex"; }); mouseArea.addEventListener( "mouseleave", () => (mouseMark.style.display = "none") ); mouseNot.addEventListener( "mouseover", () => (mouseMark.style.opacity = "0") ); mouseNot.addEventListener( "mouseleave", () => (mouseMark.style.opacity = "1") ); }); document.addEventListener("DOMContentLoaded", () => { const mouseMark02 = document.querySelector(".js__mouse_mark02"); const mouseArea02 = document.querySelector(".js__mouse_area02"); const mouseNot02 = document.querySelector(".js__mouse_not02"); mouseArea02.addEventListener("mousemove", (e) => { mouseMark02.style.left = `${e.clientX}px`; mouseMark02.style.top = `${e.clientY}px`; mouseMark02.style.display = "flex"; }); mouseArea02.addEventListener( "mouseleave", () => (mouseMark02.style.display = "none") ); mouseNot02.addEventListener( "mouseover", () => (mouseMark02.style.opacity = "0") ); mouseNot02.addEventListener( "mouseleave", () => (mouseMark02.style.opacity = "1") ); }); }; // 이메일 줄바꿈 document.addEventListener("DOMContentLoaded", () => { const emailSpan = document.getElementById("span_email"); function addBreakToEmail() { if (!emailSpan) return; // 요소의 width를 가져옴 const emailWidth = emailSpan.offsetWidth; // width가 400px 이상일 때 if (emailWidth >= 250) { let emailText = emailSpan.textContent; // 현재 이메일 텍스트 const emailParts = emailText.split("@"); // @를 기준으로 분리 if (emailParts.length === 2) { // 유효한 이메일 형식인지 확인 emailSpan.innerHTML = `${emailParts[0]}
@${emailParts[1]}`; // @ 앞에
태그 추가 } } } // 페이지가 로드된 후 실행 window.addEventListener("load", addBreakToEmail); }); //refresh Token 설정 250827 async function refreshSession() { try { const res = await fetch("/egbim/bbs/descope_refresh_session.php", { method: "POST", credentials: "include", }); const json = await res.json(); if (json.status === "ok") { sessionStorage.setItem("sessionJwt", json.sessionJwt); console.log("세션 갱신 완료"); } else { console.warn("세션 갱신 실패", json); } } catch (e) { console.error("갱신 에러", e); } } // ✅ 주기적 호출 (예: 5분마다) setInterval(refreshSession, 5 * 60 * 1000); // sessionJwt 가져오기 function getSessionJwt() { return sessionStorage.getItem("sessionJwt"); } // API 호출 헬퍼 async function apiFetch(url, options = {}) { // 기본 헤더 options.headers = { ...(options.headers || {}), Authorization: "Bearer " + getSessionJwt(), "Content-Type": "application/json", }; options.credentials = "include"; // 서버 세션 쿠키 포함 let res = await fetch(url, options); // ✅ 토큰 만료시 자동 갱신 if (res.status === 401 || res.status === 403) { console.warn("토큰 만료 → refresh_session.php 호출"); const refreshRes = await fetch("/egbim/bbs/refresh_session.php", { method: "POST", credentials: "include", }); if (refreshRes.ok) { const json = await refreshRes.json(); if (json.sessionJwt) { sessionStorage.setItem("sessionJwt", json.sessionJwt); // Authorization 헤더 갱신 후 재시도 options.headers["Authorization"] = "Bearer " + json.sessionJwt; res = await fetch(url, options); } else { alert("세션 갱신 실패 → 다시 로그인 필요"); window.location.href = "/egbim/index.php?popup=login"; } } else { alert("세션이 만료되었습니다. 다시 로그인해주세요."); window.location.href = "/egbim/index.php?popup=login"; } } return res; } // === 탭 닫을 때 서버 세션 종료 === // window.addEventListener("beforeunload", function () { // try { // // sendBeacon은 비동기지만 브라우저 종료 시점에도 안전하게 전송됨 // navigator.sendBeacon("/egbim/skin/member/basic/descope_logout.php"); // } catch (e) { // console.error("beforeunload logout error:", e); // } // });