미리보기 사진 위치나 크기 조정이 필요하다 생각해서 만듬 필요한 사람 쓰셈
+25/07/28 19:53분 수정 게시글 클릭시 미리보기 이미지 남아있는 문제 해결
// ==UserScript==
// @name 코네 미리보기 조정
// @namespace http://tampermonkey.net/
// @version 1.1
// @description kone.gg 미리보기 복제 방식으로 위치와 크기 자유 조정 + 게시글 밖 잘림 방지 + 원본 숨김 처리 포함 + SPA 대응
// @author cloud67p
// @match https://kone.gg/*
// @grant none
// @run-at document-idle
// ==/UserScript==
(function () {
'use strict';
let activePreview = null;
let hiddenOriginal = null;
let currentUrl = window.location.href;
// 미리보기 정리 함수
function cleanupPreview() {
if (activePreview) {
activePreview.remove();
activePreview = null;
}
if (hiddenOriginal) {
hiddenOriginal.style.display = '';
hiddenOriginal = null;
}
}
// URL 변경 감지 (SPA 대응)
function detectUrlChange() {
const newUrl = window.location.href;
if (newUrl !== currentUrl) {
currentUrl = newUrl;
cleanupPreview();
}
}
// URL 변경 감지를 위한 이벤트 리스너들
window.addEventListener('popstate', cleanupPreview);
// pushState, replaceState 감지 (SPA 라우팅)
const originalPushState = history.pushState;
const originalReplaceState = history.replaceState;
history.pushState = function() {
originalPushState.apply(history, arguments);
cleanupPreview();
};
history.replaceState = function() {
originalReplaceState.apply(history, arguments);
cleanupPreview();
};
// 주기적으로 URL 변경 체크 (추가 안전장치)
setInterval(detectUrlChange, 100);
// 클릭 이벤트 감지 (게시글 링크 클릭 등)
document.addEventListener('click', (e) => {
// 링크나 버튼 클릭 시 미리보기 정리
if (e.target.closest('a') || e.target.closest('button') || e.target.closest('[role="button"]')) {
cleanupPreview();
}
}, true);
// 키보드 이벤트 감지 (ESC 키 등)
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
cleanupPreview();
}
});
// 기존 마우스오버 이벤트
document.addEventListener('mouseover', (e) => {
const postWrapper = e.target.closest('.group\\/post-wrapper');
if (!postWrapper) return;
const preview = postWrapper.querySelector('.group-hover\\/post-wrapper\\:block');
if (!preview) return;
// 기존 미리보기 정리
cleanupPreview();
// 원본 숨김
preview.style.display = 'none';
hiddenOriginal = preview;
// 복제본 생성
const clone = preview.cloneNode(true);
const rect = postWrapper.getBoundingClientRect();
clone.style.position = 'fixed';
clone.style.left = '40rem';
clone.style.top = `${rect.top - 200}px`;
clone.style.zIndex = '9999';
clone.style.pointerEvents = 'none';
clone.style.display = 'block';
const img = clone.querySelector('img');
if (img) {
img.className = '';
img.style.width = 'auto';
img.style.height = 'auto';
img.style.maxWidth = '720px';
img.style.maxHeight = '720px';
img.style.objectFit = 'contain';
img.style.display = 'block';
}
document.body.appendChild(clone);
activePreview = clone;
});
// 기존 마우스아웃 이벤트
document.addEventListener('mouseout', (e) => {
const postWrapper = e.target.closest('.group\\/post-wrapper');
const related = e.relatedTarget?.closest?.('.group\\/post-wrapper');
if (postWrapper && related !== postWrapper) {
cleanupPreview();
}
});
// 페이지 언로드 시 정리
window.addEventListener('beforeunload', cleanupPreview);
// 페이지 숨김 시 정리 (탭 전환 등)
document.addEventListener('visibilitychange', () => {
if (document.hidden) {
cleanupPreview();
}
});
})();