IJMuAN02pVKE2uZHXG2JnZAHGfjon49GBXjko1rk

블로소득 팝업 3종 시리즈 코드 | 블로그스팟 전용

📌 8월 27일 13:00 3종 코드 업데이트 : 플로팅 배너 오류 수정
     * 멤버십 구독자 Aproct 님께서 많이 도와주셨습니다 😀 


블로소득 팝업을 시작으로 플로팅 배너까지 코드를 공유해드렸는데요! 

이번에는 접속과 동시에 바로 팝업이 뜨는 인스턴트 팝업을 추가하여 총 3종을 공개합니다.

이 코드 하나만 추가해두면 블로소득 팝업 시리즈 3종을 모두 사용하실수 있습니다.

블로소득 팝업 시리즈 3종

블로소득 팝업 시리즈 3종 작동원리

블로소득이 만든 팝업 시리즈는 거듭 말씀드리지만 누구의 도움없이 AI와 함께 만든 코드입니다.

그래서 코드가 다소 지저분하게 느끼실분도 계시겠지만 나름 시간을 투자해서 만든 코드입니다.

이 팝업 코드는 블로그스팟 테마 HTML 편집에 붙여넣기 하면 작동을 위한 준비는 끝납니다.

이 코드를 넣는다고 해서 모든 페이지에서 팝업이 막 튀어나고 그러진 않습니다 😅

글을 작성하실때 작동시키고 싶은 코드를 새 글쓰기에서 추가해주시면 작동하게 되어있습니다.

1. 블로소득 팝업 3종 코드 복붙하기

아래 코드를 복사해서 아래 메뉴로 이동합니다.테마 > 맞춤설정 🔽 > HTML 편집 메뉴

HTML 편집 메뉴에 들어가면 테마 코드가 빡빡하게 화면을 채우고 있을텐데요!

화면을 가장 아래로 내립니다. 그리고 </body> 앞에 이 코드를 붙여넣기 합니다.

다시한번 말씀드리지만 뒤가 아니라  (앞부분) </body> 에 넣으셔야 합니다.

<style>
  #blogsodk-overlay {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.7);
    z-index: 1000000;
  }
  #blogsodk-popup {
    display: none;
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background-color: white;
    border-radius: 10px;
    z-index: 1000001;
    width: 90%;
    max-width: 600px;
    height: auto;
    max-height: 80vh;
    overflow: hidden;
  }
  #blogsodk-popup-content {
    width: 100%;
    height: calc(100% - 80px);
    overflow-y: auto;
  }
  #blogsodk-popup-content img {
    width: 100%;
    height: auto;
    display: block;
  }
  #blogsodk-popup-buttons {
    display: flex;
    justify-content: space-between;
    padding: 20px;
    background-color: white;
    z-index: 1000002;
  }
  #blogsodk-close-button, #blogsodk-link-button {
    flex: 1;
    padding: 17px 10px;
    margin: 0 10px;
    font-size: 21px;
    font-weight: bold;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    transition: background-color 0.3s, transform 0.1s;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  #blogsodk-close-button {
    background-color: #E0E0E0;
    color: #333;
  }
  #blogsodk-link-button {
    background-color: #6CA6CD;
    color: white;
  }
  #blogsodk-close-button:hover, #blogsodk-link-button:hover {
    opacity: 0.9;
    transform: scale(1.05);
  }
  body.blogsodk-popup-active {
    overflow: hidden;
  }
  .blogsodk-popup-trigger {
    display: none;
  }
  .blogsodk-floating-banner {
    position: fixed;
    top: 20vh;
    right: 0;
    border-radius: 5px 0 0 5px;
    box-shadow: -2px 2px 5px rgba(0,0,0,0.2);
    display: none;
    font-family: Arial, sans-serif;
    z-index: 1000;
    overflow: hidden;
    max-width: 300px;
    transition: all 0.3s ease;
  }
  .blogsodk-floating-content {
  display: flex;
  flex-direction: column;
  text-decoration: none;
  cursor: pointer;
  position: relative;
  line-height: 0;
  font-size: 0;
  }
  .blogsodk-floating-line {
    padding: 10px;
    text-align: center;
    font-size: 14px;
    word-wrap: break-word;
    transition: all 0.3s ease;
    line-height: 1;
  }
  .blogsodk-floating-line1 {
    background-color: #8B0000;
    color: white;
  }
  .blogsodk-floating-content:hover .blogsodk-floating-line1 {
    background-color: white;
    color: #8B0000;
  }
  .blogsodk-floating-line2,
  .blogsodk-floating-line3,
  .blogsodk-floating-line4 {
    background-color: #f0f0f0;
    color: #333;
  }
  .blogsodk-floating-image {
  max-width: 200px;
  width: 100%;
  height: auto;
  object-fit: cover;
  display: block;
  margin: 0;
  padding: 0;
  vertical-align: top;
  }
  .blogsodk-floating-line:has(.blogsodk-floating-image) {
    padding: 0;
    line-height: 0;
    font-size: 0;
  }
  .blogsodk-close-banner {
    position: absolute;
    top: 5px;
    right: 5px;
    cursor: pointer;
    font-size: 16px;
    color: #666;
    background-color: rgba(255, 255, 255, 0.7);
    padding: 2px 6px;
    border-radius: 3px;
    z-index: 1001;
  }
  .blogsodk-floating-banner:hover {
    box-shadow: -4px 4px 10px rgba(0,0,0,0.3);
  }
  @media (max-width: 768px) {
    .blogsodk-floating-banner {
      max-width: 200px;
    }
    .blogsodk-floating-image {
      max-width: 130px;
    }
  .blogsodk-instant-popup-trigger {
    display: none;
  }
  
  }
</style>
<div class='blogsodk-floating-banner'>
  <a class='blogsodk-floating-content' href='#' id='blogsodk-floating-content'>
  </a>
  <span class='blogsodk-close-banner' onclick='event.stopPropagation(); this.parentElement.style.display=&quot;none&quot;;'>&#10006;</span>
</div>
<script>
  //<![CDATA[
function showPopup(content, linkUrl) {
    document.getElementById('blogsodk-popup-content').innerHTML = content;
    document.getElementById('blogsodk-overlay').style.display = 'block';
    document.getElementById('blogsodk-popup').style.display = 'block';
    document.body.classList.add('blogsodk-popup-active');
    document.getElementById('blogsodk-link-button').onclick = function() {
      window.location.href = linkUrl;
    };
  }
  function hidePopup() {
    document.getElementById('blogsodk-overlay').style.display = 'none';
    document.getElementById('blogsodk-popup').style.display = 'none';
    document.body.classList.remove('blogsodk-popup-active');
  }
  function loadPopupContent(url, linkUrl) {
    fetch(url)
      .then(response => response.text())
      .then(html => {
        const parser = new DOMParser();
        const doc = parser.parseFromString(html, 'text/html');
        const content = doc.querySelector('.post-body').innerHTML;
        const tempDiv = document.createElement('div');
        tempDiv.innerHTML = content;
        const images = tempDiv.querySelectorAll('img');
        images.forEach(img => {
          const wrapper = document.createElement('a');
          wrapper.href = linkUrl;
          img.parentNode.insertBefore(wrapper, img);
          wrapper.appendChild(img);
        });
        showPopup(tempDiv.innerHTML, linkUrl);
      })
      .catch(error => console.error('팝업 내용을 불러오는데 실패했습니다:', error));
  }
  function canShowPopup() {
    const lastShownTime = localStorage.getItem('blogsodk-popupLastShown-' + location.pathname);
    if (!lastShownTime) return true;
    const oneHour = 60 * 60 * 1000;
    return (Date.now() - parseInt(lastShownTime)) > oneHour;
  }
  function initPopup() {
    var popupTrigger = document.querySelector('.blogsodk-popup-trigger');
    if (popupTrigger) {
      var popupUrl = popupTrigger.getAttribute('data-popup-url');
      var linkUrl = popupTrigger.getAttribute('data-link-url');
      if (popupUrl && linkUrl) {
        window.addEventListener('scroll', function() {
          var scrollPosition = window.scrollY;
          var totalHeight = document.documentElement.scrollHeight - window.innerHeight;
          if (scrollPosition > totalHeight * 3/5 && canShowPopup()) {
            loadPopupContent(popupUrl, linkUrl);
            localStorage.setItem('blogsodk-popupLastShown-' + location.pathname, Date.now().toString());
          }
        });
      }
    }
  }
  function blogsodk_loadBannerContent(url, linkUrl) {
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() {
      if (xhr.readyState == 4 && xhr.status == 200) {
        var parser = new DOMParser();
        var doc = parser.parseFromString(xhr.responseText, 'text/html');
        var postBody = doc.querySelector('.post-body').innerHTML;
        var bannerElement = document.querySelector('.blogsodk-floating-banner');
        bannerElement.querySelector('.blogsodk-floating-content').href = linkUrl;
        bannerElement.querySelector('.blogsodk-floating-content').innerHTML = postBody;
        bannerElement.style.display = 'block';
      }
    };
    xhr.open('GET', url, true);
    xhr.send();
  }
 function initPopup() {
    var popupTrigger = document.querySelector('.blogsodk-popup-trigger');
    var instantPopupTrigger = document.querySelector('.blogsodk-instant-popup-trigger');
    if (popupTrigger) {
      var popupUrl = popupTrigger.getAttribute('data-popup-url');
      var linkUrl = popupTrigger.getAttribute('data-link-url');
      if (popupUrl && linkUrl) {
        window.addEventListener('scroll', function() {
          var scrollPosition = window.scrollY;
          var totalHeight = document.documentElement.scrollHeight - window.innerHeight;
          if (scrollPosition > totalHeight * 3/5 && canShowPopup()) {
            loadPopupContent(popupUrl, linkUrl);
            localStorage.setItem('blogsodk-popupLastShown-' + location.pathname, Date.now().toString());
          }
        });
      }
    }
    if (instantPopupTrigger) {
      var instantPopupUrl = instantPopupTrigger.getAttribute('data-popup-url');
      var instantLinkUrl = instantPopupTrigger.getAttribute('data-link-url');
      if (instantPopupUrl && instantLinkUrl) {
        window.addEventListener('scroll', function() {
          var scrollPosition = window.scrollY;
          var totalHeight = document.documentElement.scrollHeight - window.innerHeight;
          if (scrollPosition > totalHeight * 0.001 && canShowPopup()) { 
            loadPopupContent(instantPopupUrl, instantLinkUrl);
            localStorage.setItem('blogsodk-popupLastShown-' + location.pathname, Date.now().toString());
          }
        });
      }
    }
  }
  function blogsodk_initFloatingBanner() {
    var triggerElement = document.querySelector('.blogsodk-floating-trigger');
    if (triggerElement) {
      var floatingUrl = triggerElement.getAttribute('data-floating-url');
      var linkUrl = triggerElement.getAttribute('data-link-url');
      if (floatingUrl && linkUrl) {
        blogsodk_loadBannerContent(floatingUrl, linkUrl);
      }
    }
  }
  document.addEventListener('DOMContentLoaded', function() {
    initPopup();
    blogsodk_initFloatingBanner();
  });

  function blogsodk_loadBannerContent(url, linkUrl) {
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() {
      if (xhr.readyState == 4 && xhr.status == 200) {
        var parser = new DOMParser();
        var doc = parser.parseFromString(xhr.responseText, 'text/html');
        var postBody = doc.querySelector('.post-body').innerHTML;
        var bannerElement = document.querySelector('.blogsodk-floating-banner');
        var contentElement = bannerElement.querySelector('.blogsodk-floating-content');    
        contentElement.href = linkUrl;
        contentElement.innerHTML = postBody;
        var images = contentElement.querySelectorAll('img');
        images.forEach(function(img) {
          var wrapper = document.createElement('a');
          wrapper.href = linkUrl;
          img.parentNode.insertBefore(wrapper, img);
          wrapper.appendChild(img);
        });
        
        bannerElement.style.display = 'block';
      }
    };
    xhr.open('GET', url, true);
    xhr.send();
  }

  function blogsodk_initFloatingBanner() {
    var triggerElement = document.querySelector('.blogsodk-floating-trigger');
    if (triggerElement) {
      var floatingUrl = triggerElement.getAttribute('data-floating-url');
      var linkUrl = triggerElement.getAttribute('data-link-url');
      if (floatingUrl && linkUrl) {
        blogsodk_loadBannerContent(floatingUrl, linkUrl);
      }
    }
  }

  document.addEventListener('DOMContentLoaded', function() {
    initPopup();
    blogsodk_initFloatingBanner();
  });
  //]]>
</script>
<div id='blogsodk-overlay'>
  <div id='blogsodk-popup'>
    <div id='blogsodk-popup-content'/>
    <div id='blogsodk-popup-buttons'>
      <button id='blogsodk-close-button' onclick='hidePopup()'>닫기</button>
      <button id='blogsodk-link-button'>바로가기</button>
    </div>
  </div>
</div>


2. 팝업, 플로팅 내용 입력하기

우리가 글을 작성할 때는 글 메뉴를 사용하고, 팝업에 대한 내용은 페이지를 사용합니다.

글과 페이지의 차이는 얼마나 최신성을 유지하느냐에 따라 다르다고 보시면 되는데요!

통상 팝업 내용은 한번 발행하고나면 거의 변경을 하지않는 반면 글은 다르죠..

그래서 검색엔진에서도 글을 먼저 긁어가고, 페이지는 조금 늦거나 안 긁어가기도 합니다.

이러한 점을 고려해서 잘 쓰지않는 페이지를 활용하여 팝업 기능을 만들었습니다.

팝업이미지는 이미지 제외한 나머지 공백은 삭제!

팝업 이미지 주의사항

페이지에 이미지를 업로드하고 난 후에 이미지 크기를 [아주크게]로 만들어주는게 좋습니다.

작게하면 작은 상태에서 팝업이 활성화 될때 확대를 시키기 때문에 그림이 깨집니다.

플로팅 이미지 주의사항

플로팅의 경우 이미지만 적용되도록 수정하였습니다.

글자를 아무리 작성해도 페이지에 들어가있는 이미지만 플로팅 배너 형식으로 나옵니다.


3. 본문 새 글에 적용하기

테마 HTML 수정했고, 페이지에 팝업/플로팅 내용도 작성했다면 이제 마지막은 글에 적용하는겁니다.

모든 글에 팝업, 플로팅이 작동되지 않도록 만들었기 때문에 새 글에 특별한 코드를 넣어야 합니다.

코드를 넣으실때는 HTML 보기에서 넣으세요! 

이 코드는 팝업, 플로팅, 인스턴트에 따라 다릅니다. 사용하고자 하는 코드를 골라서 넣으시면 됩니다.

아래 코드는 본문 <마지막 줄>에 넣어주세요!!

(1) 인스턴트 팝업 : 페이지 접속과 동시에 팝업 활성화

<div 
  class="blogsodk-instant-popup-trigger"
  data-popup-url="페이지 주소"
data-link-url="https://링크 주소" style="display: none;"></div>

(2) 플로팅 배너 : 오른쪽 스크롤바에 활성화

<div 
  class="blogsodk-floating-trigger" 
  data-floating-url="페이지 주소"
  data-link-url="https://링크 주소"
  style="display: none;">

(3) 블로소득 팝업 : 본문 60% 지점에서 팝업 활성화

<div
  class="blogsodk-popup-trigger"
  data-popup-url="페이지 주소"
  data-link-url="https://링크 주소"
  style="display:none;"
></div>


대부분 필요한 기능들을 다 넣은것 같은데 앞으로 더 업그레이드가 있을지 모르겠습니다만..

정상 작동하지 않는 경우가 생긴다면 수시로 수정하도록 하겠습니다.