269 lines
11 KiB
JavaScript
269 lines
11 KiB
JavaScript
/**
|
|
* Discshar.js
|
|
*
|
|
* 할인 공유 기능을 관리하는 모듈
|
|
* 할인 슬라이더, 공유 링크 생성, 공유 결과 확인 등의 기능 제공
|
|
*/
|
|
|
|
const Discshar = (function() {
|
|
// 모듈 내부 변수 선언
|
|
let $slider; // 슬라이더 컨테이너 (ul 요소)
|
|
let $slides; // 슬라이드 아이템들 (li 요소들)
|
|
let slideWidth; // 각 슬라이드 너비 (마진 포함)
|
|
let currentSlide; // 현재 표시 중인 슬라이드 인덱스
|
|
let totalSlides; // 전체 슬라이드 개수 (복제 슬라이드 포함)
|
|
let slideInterval; // 자동 슬라이드 간격 (밀리초)
|
|
let autoSlideTimeout; // 자동 슬라이드 타이머 ID
|
|
|
|
/**
|
|
* 모듈 초기화 함수
|
|
* 슬라이더 초기화 및 이벤트 바인딩
|
|
*/
|
|
function init() {
|
|
initSlider(); // 슬라이더 요소 초기화
|
|
bindEvents(); // 이벤트 리스너 등록
|
|
}
|
|
|
|
/**
|
|
* 슬라이더 초기화 함수
|
|
* 슬라이더 요소 참조 가져오기, 크기 설정, 무한 루프를 위한 슬라이드 복제
|
|
*/
|
|
function initSlider() {
|
|
// 슬라이더 요소 참조 가져오기
|
|
$slider = $('.discountSlider ul');
|
|
$slides = $('.discountSlider li');
|
|
|
|
// 슬라이드 너비 계산 (요소 너비 + 마진)
|
|
slideWidth = $slides.outerWidth() + parseInt($slides.css('margin-right'));
|
|
|
|
// 초기 슬라이드 인덱스 및 총 개수 설정
|
|
currentSlide = 0;
|
|
totalSlides = $slides.length;
|
|
slideInterval = 3000; // 슬라이드 자동 전환 간격 (밀리초)
|
|
|
|
// 무한 루프 슬라이드를 위한 복제 요소 추가
|
|
// 첫 번째 슬라이드 앞에 마지막 슬라이드 복제본 추가
|
|
$slides.first().before($slides.last().clone());
|
|
// 마지막 슬라이드 뒤에 첫 번째 슬라이드 복제본 추가
|
|
$slides.last().after($slides.first().clone());
|
|
|
|
// 복제된 슬라이드를 포함하여 총 슬라이드 수 업데이트
|
|
totalSlides += 2;
|
|
|
|
// 모든 슬라이드를 포함할 수 있도록 컨테이너 너비 설정
|
|
$slider.width(totalSlides * slideWidth);
|
|
|
|
// 초기 위치를 첫 번째 실제 슬라이드로 설정 (복제 슬라이드 건너뛰기)
|
|
$slider.css('margin-left', -slideWidth);
|
|
|
|
// 자동 슬라이드 시작
|
|
startAutoSlide();
|
|
}
|
|
|
|
/**
|
|
* 이벤트 리스너 등록 함수
|
|
* 슬라이더 조작을 위한 다양한 이벤트 핸들러 연결
|
|
*/
|
|
function bindEvents() {
|
|
// 슬라이더에 마우스 이벤트 및 터치 이벤트 바인딩
|
|
$slider.on('mouseenter', stopAutoSlide) // 마우스 진입 시 자동 슬라이드 정지
|
|
.on('mouseleave', startAutoSlide) // 마우스 이탈 시 자동 슬라이드 재시작
|
|
.on('mousedown touchstart', startDrag) // 드래그 시작
|
|
.on('mousemove touchmove', drag) // 드래그 중
|
|
.on('mouseup touchend', endDrag); // 드래그 종료
|
|
|
|
// 문서 전체에 마우스업/터치엔드 이벤트 리스너 추가 (드래그 도중 슬라이더 밖으로 나갔을 때 대비)
|
|
$(document).on('mouseup touchend', endDrag);
|
|
|
|
// 이미지 기본 드래그 방지 (브라우저의 기본 동작 차단)
|
|
$('.discountSlider img').on('dragstart', function(event) { event.preventDefault(); });
|
|
}
|
|
|
|
/**
|
|
* 자동 슬라이드 시작 함수
|
|
* 일정 간격으로 다음 슬라이드로 자동 이동
|
|
*/
|
|
function startAutoSlide() {
|
|
autoSlideTimeout = setInterval(nextSlide, slideInterval);
|
|
}
|
|
|
|
/**
|
|
* 자동 슬라이드 정지 함수
|
|
* 자동 슬라이드 타이머 중지
|
|
*/
|
|
function stopAutoSlide() {
|
|
clearInterval(autoSlideTimeout);
|
|
}
|
|
|
|
/**
|
|
* 다음 슬라이드로 이동 함수
|
|
* 현재 슬라이드 인덱스 증가 후 슬라이드 이동
|
|
*/
|
|
function nextSlide() {
|
|
currentSlide++;
|
|
moveSlide();
|
|
}
|
|
|
|
/**
|
|
* 슬라이드 이동 함수
|
|
* 현재 슬라이드 인덱스에 맞게 슬라이더 위치 애니메이션
|
|
* 무한 루프 슬라이딩을 위한 위치 보정 처리 포함
|
|
*/
|
|
function moveSlide() {
|
|
// 애니메이션으로 슬라이더 위치 이동
|
|
$slider.animate({'margin-left': -currentSlide * slideWidth}, 500, function() {
|
|
// 애니메이션 완료 후 위치 보정 (무한 루프 구현)
|
|
if (currentSlide >= totalSlides - 1) {
|
|
// 마지막 슬라이드(복제본)에 도달하면 첫 번째 실제 슬라이드로 위치 즉시 이동
|
|
currentSlide = 1;
|
|
$slider.css('margin-left', -slideWidth);
|
|
} else if (currentSlide <= 0) {
|
|
// 첫 번째 슬라이드(복제본)에 도달하면 마지막 실제 슬라이드로 위치 즉시 이동
|
|
currentSlide = totalSlides - 2;
|
|
$slider.css('margin-left', -currentSlide * slideWidth);
|
|
}
|
|
});
|
|
}
|
|
|
|
// 드래그 관련 상태 변수
|
|
let isDragging = false; // 드래그 중인지 여부
|
|
let startPos = 0; // 드래그 시작 위치 (X좌표)
|
|
let currentPos = 0; // 현재 슬라이더 위치
|
|
|
|
/**
|
|
* 드래그 시작 처리 함수
|
|
* 드래그 시작 위치와 현재 슬라이더 위치 기록
|
|
* @param {Event} e - 마우스 또는 터치 이벤트
|
|
*/
|
|
function startDrag(e) {
|
|
isDragging = true;
|
|
// 마우스 또는 터치 이벤트의 X좌표 가져오기
|
|
startPos = e.pageX || e.originalEvent.touches[0].pageX;
|
|
// 현재 슬라이더 위치 기록
|
|
currentPos = $slider.css('margin-left');
|
|
// 자동 슬라이드 정지
|
|
stopAutoSlide();
|
|
}
|
|
|
|
/**
|
|
* 드래그 중 처리 함수
|
|
* 마우스/터치 위치에 따라 슬라이더 위치 실시간 업데이트
|
|
* @param {Event} e - 마우스 또는 터치 이벤트
|
|
*/
|
|
function drag(e) {
|
|
if (!isDragging) return; // 드래그 중이 아니면 무시
|
|
|
|
// 현재 마우스/터치 위치 가져오기
|
|
let currentMousePos = e.pageX || e.originalEvent.touches[0].pageX;
|
|
// 시작 위치와의 차이 계산
|
|
let diff = currentMousePos - startPos;
|
|
// 슬라이더 위치 실시간 업데이트
|
|
$slider.css('margin-left', parseInt(currentPos) + diff);
|
|
}
|
|
|
|
/**
|
|
* 드래그 종료 처리 함수
|
|
* 드래그 방향과 거리에 따라 슬라이드 이동 또는 원위치
|
|
* @param {Event} e - 마우스 또는 터치 이벤트
|
|
*/
|
|
function endDrag(e) {
|
|
if (!isDragging) return; // 드래그 중이 아니면 무시
|
|
|
|
isDragging = false;
|
|
// 마우스/터치 종료 위치 가져오기
|
|
let endPos = e.pageX || e.originalEvent.changedTouches[0].pageX;
|
|
// 시작 위치와의 차이 계산
|
|
let diff = endPos - startPos;
|
|
|
|
// 슬라이드 전환을 위한 최소 드래그 거리(50px) 이상이면 슬라이드 전환
|
|
if (Math.abs(diff) > 50) {
|
|
// 오른쪽으로 드래그: 이전 슬라이드, 왼쪽으로 드래그: 다음 슬라이드
|
|
currentSlide += (diff > 0) ? -1 : 1;
|
|
moveSlide();
|
|
} else {
|
|
// 최소 거리 미만이면 원래 위치로 되돌리기
|
|
$slider.animate({'margin-left': currentPos}, 200);
|
|
}
|
|
|
|
// 자동 슬라이드 재시작
|
|
startAutoSlide();
|
|
}
|
|
|
|
/**
|
|
* 공유 링크 생성 함수
|
|
* 할인 공유를 위한 고유 링크 생성 및 모달에 표시
|
|
* @param {number} bnfInnb - 혜택 고유 번호
|
|
*/
|
|
function copyLink(bnfInnb) {
|
|
$.ajax({
|
|
url: '/sopmal/bnft/copyDiscsharLink', // 공유 링크 생성 API
|
|
method: 'POST',
|
|
contentType: 'application/json',
|
|
data: JSON.stringify({ bnfInnb: bnfInnb }), // 혜택 고유 번호 전달
|
|
success: function(response) {
|
|
if (response.success && response.links && response.links.length > 0) {
|
|
// 성공 시 첫 번째 링크 정보 사용
|
|
const link = response.links[0];
|
|
// 생성된 고유 URL을 입력 필드에 설정
|
|
$('#linkToCopy').val(link.uniqueUrl);
|
|
// 링크 만료일 표시 형식 변환
|
|
const validDate = new Date(link.validDt);
|
|
const formattedDate = validDate.toISOString().split('T')[0];
|
|
$('#linkExpiryDate').text(formattedDate);
|
|
// 링크 복사 모달 표시
|
|
MicroModal.show('modal-1');
|
|
} else {
|
|
// 링크 정보 없음 알림
|
|
alert('유효한 링크 정보가 없습니다.');
|
|
}
|
|
},
|
|
error: function(xhr, status, error) {
|
|
// 통신 오류 처리
|
|
console.error('서버 통신 오류:', error);
|
|
alert('서버 통신 중 오류가 발생했습니다.');
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 공유 결과 확인 함수
|
|
* 사용자의 할인 공유 결과에 따라 적절한 모달 표시
|
|
*/
|
|
function showShareResult() {
|
|
$.ajax({
|
|
url: '/sopmal/bnft/checkDiscsharResult', // 공유 결과 확인 API
|
|
method: 'POST',
|
|
contentType: 'application/json',
|
|
data: JSON.stringify({}),
|
|
success: function(response) {
|
|
// 공유 링크로 구매한 사람이 있는지 여부에 따라 다른 모달 표시
|
|
if (response.hasPurchase) {
|
|
// 구매자가 있는 경우 (성공)
|
|
MicroModal.show('modal-3');
|
|
} else {
|
|
// 구매자가 없는 경우 (아직 공유 중)
|
|
MicroModal.show('modal-2');
|
|
}
|
|
},
|
|
error: function() {
|
|
// 통신 오류 처리
|
|
alert('공유 결과를 확인하는데 실패했습니다.');
|
|
}
|
|
});
|
|
}
|
|
|
|
// 모듈의 공개 인터페이스
|
|
return {
|
|
init: init, // 모듈 초기화
|
|
copyLink: copyLink, // 공유 링크 생성
|
|
showShareResult: showShareResult // 공유 결과 확인
|
|
};
|
|
})();
|
|
|
|
/**
|
|
* 문서 로드 완료 시 실행
|
|
* Discshar 모듈 초기화
|
|
*/
|
|
$(document).ready(function() {
|
|
Discshar.init();
|
|
}); |