summaryrefslogtreecommitdiff
path: root/layouts/partials/components/like-button.html
diff options
context:
space:
mode:
authorEltrac <hi@guhub.cn>2025-06-19 14:03:07 +0800
committerEltrac <hi@guhub.cn>2025-06-19 14:03:07 +0800
commitd0555f5a6747297dbb591caaad57b130ecb2bce9 (patch)
tree1d696c42ab2a9e640d2a56b359d2cd112e7c7fac /layouts/partials/components/like-button.html
parenta1bf685c4fb83e05bba3b1e89dd42ea59309cef2 (diff)
feat(like-button): 将点赞按钮的样式和逻辑提取到独立文件
提取CSS和JavaScript到单独文件以提高可维护性 使用Hugo资源管道进行最小化处理 保留原有功能并优化代码结构 Former-commit-id: e276f3a456980c64a80eb5cc29567703f4268fb7
Diffstat (limited to 'layouts/partials/components/like-button.html')
-rw-r--r--layouts/partials/components/like-button.html260
1 files changed, 10 insertions, 250 deletions
diff --git a/layouts/partials/components/like-button.html b/layouts/partials/components/like-button.html
index aa665453..b377bf78 100644
--- a/layouts/partials/components/like-button.html
+++ b/layouts/partials/components/like-button.html
@@ -9,255 +9,15 @@
</div>
</div>
-<script>
-(function() {
- const pageId = "{{ .File.UniqueID | urlize }}";
- const countEl = document.getElementById("like-count-" + pageId);
- const btnEl = document.getElementById("like-btn-" + pageId);
- const containerEl = document.getElementById("like-container-" + pageId);
-
- let isNearComments = false;
-
- function checkScrollPosition() {
- const commentsSection = document.querySelector('.post-comments');
- if (!commentsSection) return;
-
- const rect = commentsSection.getBoundingClientRect();
- const windowHeight = window.innerHeight;
-
- // 当评论区进入视窗下半部分时触发
- const shouldHighlight = rect.top < windowHeight * 0.8;
-
- if (shouldHighlight !== isNearComments) {
- isNearComments = shouldHighlight;
- // 如果已经点赞,不添加 near-comments 类(避免晃动)
- if (containerEl.classList.contains('liked')) {
- return;
- }
-
- if (isNearComments) {
- containerEl.classList.add('near-comments');
- } else {
- containerEl.classList.remove('near-comments');
- }
- }
- }
-
- function updateTooltip() {
- if (containerEl.classList.contains('liked')) {
- btnEl.setAttribute('title', btnEl.getAttribute('data-liked-title'));
- } else {
- btnEl.setAttribute('title', '为这篇文章献上心脏');
- }
- }
-
- function fetchLikes() {
- fetch("https://like.guhub.cn/like/" + pageId)
- .then(resp => resp.json())
- .then(data => {
- countEl.innerText = data.likes ?? 0;
- if (localStorage.getItem("liked_" + pageId)) {
- btnEl.disabled = true;
- containerEl.classList.add("liked");
- // 移除可能存在的 near-comments 类
- containerEl.classList.remove('near-comments');
- updateTooltip();
- }
- })
- .catch(() => {
- countEl.innerText = "❌";
- });
- }
-
- window.sendLike = function(pageId) {
- if (localStorage.getItem("liked_" + pageId)) return;
+<!-- 内嵌CSS样式 -->
+{{ with resources.Get "css/like-button.css" | minify }}
+<style>{{ .Content | safeCSS }}</style>
+{{ end }}
- if (window.location.hostname !== 'localhost') {
- umami.track('👍 Hit Like Button');
- }
-
- // 添加点击效果
- btnEl.classList.add("clicked");
- setTimeout(() => {
- btnEl.classList.remove("clicked");
- }, 300);
-
- fetch("https://like.guhub.cn/like/" + pageId, { method: "POST" })
- .then(resp => resp.json())
- .then(data => {
- localStorage.setItem("liked_" + pageId, "1");
- countEl.innerText = data.likes ?? 1;
- btnEl.disabled = true;
- containerEl.classList.add("liked");
- // 移除 near-comments 类,停止晃动
- containerEl.classList.remove('near-comments');
- updateTooltip();
- })
- .catch(() => {
- alert("点赞失败,请稍后再试");
- });
- };
-
- // 监听滚动事件
- window.addEventListener('scroll', checkScrollPosition);
- window.addEventListener('resize', checkScrollPosition);
-
- // 初始化
- fetchLikes();
- checkScrollPosition();
-})();
+<!-- 设置页面ID并内嵌JavaScript -->
+<script>
+ window.likeButtonPageId = "{{ .File.UniqueID | urlize }}";
</script>
-
-<style>
-.floating-like-container {
- position: fixed;
- bottom: 30px;
- right: 30px;
- z-index: 1000;
- opacity: 0.3;
- transition: all 0.3s ease;
-}
-
-.floating-like-container:hover {
- opacity: 1;
-}
-
-.floating-like-container.near-comments {
- opacity: 0.6;
- animation: gentle-shake 2s ease-in-out infinite;
-}
-
-.floating-like-container.near-comments:hover {
- opacity: 1;
- animation: none;
-}
-
-/* 已点赞状态:保持最高不透明度,不再晃动 */
-.floating-like-container.liked {
- opacity: 1 !important;
-}
-
-.floating-like-container.liked.near-comments {
- animation: none !important;
-}
-
-.floating-like-button {
- display: flex;
- flex-direction: column;
- align-items: center;
- cursor: pointer;
- background: none;
- border: none;
- padding: 8px;
- transition: all 0.3s ease;
- position: relative;
-}
-
-.floating-like-button:hover {
- transform: scale(1.1);
-}
-
-/* 已点赞状态下禁用hover放大效果 */
-.liked .floating-like-button:hover {
- transform: none;
-}
-
-.floating-like-button.clicked {
- transform: scale(0.9);
-}
-
-.floating-like-button:disabled {
- cursor: not-allowed;
-}
-
-#like-button-icon {
- width: 32px;
- height: 32px;
- transition: all 0.3s ease;
- filter: drop-shadow(0 2px 4px rgba(0,0,0,0.2));
-}
-
-.liked #like-button-icon {
- filter: brightness(0) saturate(100%) invert(8%) sepia(100%) saturate(7500%) hue-rotate(0deg) brightness(70%) contrast(150%) drop-shadow(0 2px 4px rgba(0,0,0,0.2));
- animation: heartbeat 1.5s ease-in-out infinite;
-}
-
-.like-count-display {
- margin-top: 4px;
- font-size: 12px;
- font-weight: bold;
- color: var(--secondary-text-color);
- text-align: center;
- min-width: 20px;
- background: rgba(255, 255, 255, 0.9);
- border-radius: 10px;
- padding: 2px 6px;
- box-shadow: 0 1px 3px rgba(0,0,0,0.1);
-}
-
-.liked .like-count-display {
- color: #8B0000;
-}
-
-/* 悬浮提示样式 */
-.floating-like-button::before {
- content: attr(title);
- position: absolute;
- bottom: 100%;
- right: 0;
- background: rgba(0, 0, 0, 0.8);
- color: white;
- padding: 6px 10px;
- border-radius: 4px;
- font-size: 12px;
- white-space: nowrap;
- opacity: 0;
- visibility: hidden;
- transform: translateY(5px);
- transition: all 0.3s ease;
- pointer-events: none;
- margin-bottom: 8px;
-}
-
-.floating-like-button:hover::before {
- opacity: 1;
- visibility: visible;
- transform: translateY(0);
-}
-
-/* 动画定义 */
-@keyframes gentle-shake {
- 0%, 100% { transform: translateX(0); }
- 25% { transform: translateX(-2px); }
- 75% { transform: translateX(2px); }
-}
-
-@keyframes heartbeat {
- 0%, 100% { transform: scale(1); }
- 25% { transform: scale(1.1); }
- 50% { transform: scale(1.2); }
- 75% { transform: scale(1.1); }
-}
-
-/* 移动端适配 */
-@media screen and (max-width: 768px) {
- .floating-like-container {
- bottom: 20px;
- right: 20px;
- }
-
- #like-button-icon {
- width: 28px;
- height: 28px;
- }
-
- .floating-like-button::before {
- right: -10px;
- transform: translateX(50%) translateY(5px);
- }
-
- .floating-like-button:hover::before {
- transform: translateX(50%) translateY(0);
- }
-}
-</style>
+{{ with resources.Get "js/like-button.js" | minify }}
+<script>{{ .Content | safeJS }}</script>
+{{ end }}