저는 쇼핑몰에 채널톡을 사용하고 있습니다.
워낙 많은 쇼핑몰들에서 사용하는 서비스라서 굳이 설명할 필요는 없을 것 같습니다.
아임웹에서도 채널톡을 공식 지원해서 아주 손쉽게 적용을 하였습니다.
채널톡 버튼 위치는 우측 하단에 배치하였습니다.
모바일은 우측 하단을 기준으로 28px 위에 위치하도록 설정하였습니다.
깔끔하게 잘 배치가 되어서 만족하고 있는데..
아임웹은 모바일 상품 상세페이지의 경우, 구매하기 버튼이 하단에 위치합니다. 따라서, 모바일 상품 상세페이지에서 구매하기 버튼과 채널톡 버튼이 겹치는 상황이 발생합니다.
뭐 겹치면 모바일 상세페이지에서만 버튼을 좀 올리면 되겠다. 생각했습니다.
근데 문제가 채널톡 버튼은
ShadowRoot 안에 있는 버튼이고, 심지어 페이지가 로딩된 후 약간 시간을 두고 나타납니다. 쉽게 설명해서 일반적인 방법으로는 위치를 조정하기가 아주아주 어려운 형태입니다.
에이, 그래도 채널톡인데~!!
개발자들이 많다고 소문난 서비스인데, 도움받으면 되겠지~
쉽게 생각하고, 채널톡에 문의를 남겼고 다음과 같은 답변을 받았습니다.
솔직히 전혀 예상하지 못했습니다.
1. 그냥 이대로 사용하거나
2. 아예 모든 페이지에서 채널톡 버튼을 다 올려버리는 것 입니다.
근데, 저는 그렇게 하고 싶지 않단 말이죠.
어떻게든 제가 원하는 형태로 사용해고 싶었습니다.
그래서, 대충 모바일 상세페이지 채널톡 버튼 올리기 시나리오를 짜봤습니다.
1. 먼저 쇼핑몰에 있는 채널톡 버튼의 id 또는 class 값 확인
2. ShadowRoot 가 로드될때까지 감지하기
3. ShadowRoot 가 로드되면, 채널톡 버튼을 선택하기
4. 버튼을 올리고, 스크립트는 종료하기
자, 그럼 적용해볼까요?
먼저 채널톡 버튼의 id 또는 class 값을 찾아보니 다음과 같습니다.
대충 .knmmOd 로 지정하면 될 것 같습니다. 다행히도, PC 와 모바일의 클래스값이 다르더군요.
다음으로 ShadowRoot 가 로드될때까지 감지하기 인가요?
setInterval 을 사용하기로 했습니다. 간격은 뭐 0.3초 정도면 충분할 것 같네요. (하지만, 버튼이 나타나고 올라가는게 보여서 최종 0.1초로 변경했습니다.)
그 다음에는 ShadowRoot 로드되면, 채널톡 버튼을 선택하기 인가요?
여기에서는 IntersectionObserver 를 사용했습니다. 적용해보니 잘 작동해서 다른건 고민하지 않았습니다. 참고로, IntersectionObserver 는 화면이 보일때만 감지하는 브라우저 API 입니다.
마지막으로, 채널톡 버튼을 올리고 스크립트를 종료하면 되겠네요.
채널톡에서 위치를 28px 로 설정해서, 모바일 상세페이지에서는 78px 로 설정했습니다. 그리고 마지막으로 observer.disconnect(); 를 넣어서 한번 실행하고 중지하도록 처리했습니다.
그렇게 만들어진 최종 스크립트는 다음과 같습니다.
<script>
function waitForShadowElementAndObserve() {
const hostSelector = '#ch-plugin-entry > div';
const targetClass = '.knmmOd';
const interval = setInterval(() => {
const host = document.querySelector(hostSelector);
if (!host || !host.shadowRoot) return;
const target = host.shadowRoot.querySelector(targetClass);
if (target) {
clearInterval(interval);
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
console.log("모바일 상세페이지 채널톡 버튼을 올려!!");
target.style.cssText = 'bottom: 78px';
observer.disconnect();
}
});
});
observer.observe(target);
}
}, 100);
}
window.addEventListener("DOMContentLoaded", waitForShadowElementAndObserve);
</script>
상품 상세페이지에서 코드 위젯을 추가하고, 적용해주었습니다.
이제 잘 작동하나 테스트를 해봐야겠죠?
오예~! 아주 잘 작동합니다.
사실 간단히 적었지만, 사실 시행착오를 엄청나게 많이 했습니다. OTL
(ShadowRoot 잊지 않겠다...)
혹 제 경험과 똑같이 모바일 상품페이지에서만 채널톡 버튼의 위치를 수정하고 싶다면, 위에 코드는 맘대로 가져다 쓰시고, 채널톡 class 값이 동일한지 확인하고, 올리는 수치만 수정하세요~
E-mail : raremore@kakao.com