实用功能更新
This commit is contained in:
232
frontend/60sapi/实用功能/链接OG信息/css/background.css
Normal file
232
frontend/60sapi/实用功能/链接OG信息/css/background.css
Normal file
@@ -0,0 +1,232 @@
|
||||
/* 高维度背景特效样式 - 神秘高级风格 */
|
||||
|
||||
/* 背景容器 */
|
||||
.background-container {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 1;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
background: radial-gradient(ellipse at center,
|
||||
rgba(15, 0, 30, 0.95) 0%,
|
||||
rgba(5, 0, 15, 0.98) 50%,
|
||||
rgba(0, 0, 0, 1) 100%);
|
||||
}
|
||||
|
||||
/* 几何网格层 */
|
||||
.geometric-grid {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image:
|
||||
linear-gradient(rgba(138, 43, 226, 0.1) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(138, 43, 226, 0.1) 1px, transparent 1px),
|
||||
linear-gradient(rgba(75, 0, 130, 0.05) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(75, 0, 130, 0.05) 1px, transparent 1px);
|
||||
background-size: 100px 100px, 100px 100px, 20px 20px, 20px 20px;
|
||||
animation: gridPulse 8s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes gridPulse {
|
||||
0%, 100% { opacity: 0.3; transform: scale(1); }
|
||||
50% { opacity: 0.6; transform: scale(1.02); }
|
||||
}
|
||||
|
||||
/* 神经网络效果 */
|
||||
.neural-network {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background:
|
||||
radial-gradient(circle at 20% 30%, rgba(138, 43, 226, 0.15) 2px, transparent 2px),
|
||||
radial-gradient(circle at 80% 20%, rgba(75, 0, 130, 0.12) 1px, transparent 1px),
|
||||
radial-gradient(circle at 40% 70%, rgba(147, 0, 211, 0.1) 1.5px, transparent 1.5px),
|
||||
radial-gradient(circle at 90% 80%, rgba(138, 43, 226, 0.08) 1px, transparent 1px),
|
||||
radial-gradient(circle at 10% 90%, rgba(75, 0, 130, 0.1) 2px, transparent 2px);
|
||||
background-size: 200px 200px, 150px 150px, 300px 300px, 180px 180px, 250px 250px;
|
||||
animation: neuralFlow 15s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes neuralFlow {
|
||||
0% { transform: translate(0, 0) rotate(0deg); }
|
||||
25% { transform: translate(-10px, -5px) rotate(90deg); }
|
||||
50% { transform: translate(-5px, -10px) rotate(180deg); }
|
||||
75% { transform: translate(5px, -5px) rotate(270deg); }
|
||||
100% { transform: translate(0, 0) rotate(360deg); }
|
||||
}
|
||||
|
||||
/* 粒子系统 */
|
||||
.particle-system {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image:
|
||||
radial-gradient(circle, rgba(138, 43, 226, 0.4) 1px, transparent 1px),
|
||||
radial-gradient(circle, rgba(75, 0, 130, 0.3) 0.5px, transparent 0.5px),
|
||||
radial-gradient(circle, rgba(147, 0, 211, 0.2) 0.8px, transparent 0.8px);
|
||||
background-size: 80px 80px, 120px 120px, 160px 160px;
|
||||
background-position: 0 0, 40px 40px, 80px 80px;
|
||||
animation: particleFloat 20s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes particleFloat {
|
||||
0%, 100% { transform: translateY(0px) translateX(0px); }
|
||||
25% { transform: translateY(-20px) translateX(10px); }
|
||||
50% { transform: translateY(-10px) translateX(-15px); }
|
||||
75% { transform: translateY(-30px) translateX(5px); }
|
||||
}
|
||||
|
||||
/* 扫描线效果 */
|
||||
.scan-lines {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: repeating-linear-gradient(
|
||||
0deg,
|
||||
transparent 0px,
|
||||
transparent 2px,
|
||||
rgba(138, 43, 226, 0.03) 2px,
|
||||
rgba(138, 43, 226, 0.03) 4px
|
||||
);
|
||||
animation: scanMove 3s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes scanMove {
|
||||
0% { transform: translateY(-100%); }
|
||||
100% { transform: translateY(100%); }
|
||||
}
|
||||
|
||||
/* 全息投影效果 */
|
||||
.holographic-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background:
|
||||
linear-gradient(45deg,
|
||||
transparent 30%,
|
||||
rgba(138, 43, 226, 0.05) 50%,
|
||||
transparent 70%),
|
||||
linear-gradient(-45deg,
|
||||
transparent 30%,
|
||||
rgba(75, 0, 130, 0.03) 50%,
|
||||
transparent 70%);
|
||||
background-size: 200px 200px, 150px 150px;
|
||||
animation: holographicShift 12s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes holographicShift {
|
||||
0%, 100% {
|
||||
background-position: 0% 0%, 100% 100%;
|
||||
opacity: 0.7;
|
||||
}
|
||||
50% {
|
||||
background-position: 100% 100%, 0% 0%;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* 数据流效果 */
|
||||
.data-stream {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background:
|
||||
linear-gradient(90deg,
|
||||
transparent 0%,
|
||||
rgba(138, 43, 226, 0.1) 50%,
|
||||
transparent 100%);
|
||||
background-size: 300px 100%;
|
||||
animation: dataFlow 8s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes dataFlow {
|
||||
0% { transform: translateX(-100%); }
|
||||
100% { transform: translateX(100%); }
|
||||
}
|
||||
|
||||
/* 量子波动效果 */
|
||||
.quantum-waves {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background:
|
||||
radial-gradient(ellipse 200px 100px at 50% 0%,
|
||||
rgba(138, 43, 226, 0.1) 0%,
|
||||
transparent 50%),
|
||||
radial-gradient(ellipse 300px 150px at 50% 100%,
|
||||
rgba(75, 0, 130, 0.08) 0%,
|
||||
transparent 50%);
|
||||
animation: quantumPulse 10s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes quantumPulse {
|
||||
0%, 100% {
|
||||
transform: scale(1) rotate(0deg);
|
||||
opacity: 0.5;
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.1) rotate(180deg);
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
/* 响应式优化 */
|
||||
@media (max-width: 768px) {
|
||||
.geometric-grid {
|
||||
background-size: 50px 50px, 50px 50px, 10px 10px, 10px 10px;
|
||||
}
|
||||
|
||||
.neural-network {
|
||||
background-size: 100px 100px, 75px 75px, 150px 150px, 90px 90px, 125px 125px;
|
||||
}
|
||||
|
||||
.particle-system {
|
||||
background-size: 40px 40px, 60px 60px, 80px 80px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 减少动画偏好 */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.geometric-grid,
|
||||
.neural-network,
|
||||
.particle-system,
|
||||
.scan-lines,
|
||||
.holographic-overlay,
|
||||
.data-stream,
|
||||
.quantum-waves {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* 高对比度模式 */
|
||||
@media (prefers-contrast: high) {
|
||||
.background-container {
|
||||
background: radial-gradient(ellipse at center,
|
||||
rgba(25, 0, 50, 0.95) 0%,
|
||||
rgba(10, 0, 25, 0.98) 50%,
|
||||
rgba(0, 0, 0, 1) 100%);
|
||||
}
|
||||
|
||||
.geometric-grid {
|
||||
background-image:
|
||||
linear-gradient(rgba(200, 100, 255, 0.2) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(200, 100, 255, 0.2) 1px, transparent 1px);
|
||||
}
|
||||
}
|
||||
1159
frontend/60sapi/实用功能/链接OG信息/css/style.css
Normal file
1159
frontend/60sapi/实用功能/链接OG信息/css/style.css
Normal file
File diff suppressed because it is too large
Load Diff
223
frontend/60sapi/实用功能/链接OG信息/index.html
Normal file
223
frontend/60sapi/实用功能/链接OG信息/index.html
Normal file
@@ -0,0 +1,223 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>链接OG信息查询 - 神秘解析器</title>
|
||||
<meta name="description" content="高级链接OG信息查询工具,解析网页元数据">
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
<link rel="stylesheet" href="css/background.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<!-- 背景特效容器 -->
|
||||
<div class="background-container">
|
||||
<div class="matrix-rain"></div>
|
||||
<div class="geometric-shapes"></div>
|
||||
<div class="neural-network"></div>
|
||||
</div>
|
||||
|
||||
<!-- 主容器 -->
|
||||
<div class="main-container">
|
||||
<!-- 头部区域 -->
|
||||
<header class="header">
|
||||
<div class="header-content">
|
||||
<div class="logo-section">
|
||||
<i class="fas fa-link logo-icon"></i>
|
||||
<h1 class="title">OG 解析器</h1>
|
||||
<span class="subtitle">链接元数据神秘解析</span>
|
||||
</div>
|
||||
<div class="status-indicator">
|
||||
<div class="pulse-dot"></div>
|
||||
<span class="status-text">系统就绪</span>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- 查询区域 -->
|
||||
<section class="query-section">
|
||||
<div class="input-container">
|
||||
<div class="input-wrapper">
|
||||
<i class="fas fa-globe input-icon"></i>
|
||||
<input type="url" id="url-input" placeholder="输入链接地址进行深度解析..." class="url-input">
|
||||
<div class="input-border"></div>
|
||||
</div>
|
||||
<button id="analyze-btn" class="analyze-btn">
|
||||
<span class="btn-text">开始解析</span>
|
||||
<div class="btn-effects">
|
||||
<div class="ripple"></div>
|
||||
<div class="glow"></div>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 加载状态 -->
|
||||
<div id="loading" class="loading-container" style="display: none;">
|
||||
<div class="loading-content">
|
||||
<div class="scanner">
|
||||
<div class="scanner-line"></div>
|
||||
<div class="scanner-grid">
|
||||
<div class="grid-line"></div>
|
||||
<div class="grid-line"></div>
|
||||
<div class="grid-line"></div>
|
||||
<div class="grid-line"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="loading-text">
|
||||
<span class="loading-title">正在解析链接</span>
|
||||
<span class="loading-subtitle">深度扫描元数据中...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 结果展示区域 -->
|
||||
<section id="results" class="results-section" style="display: none;">
|
||||
<div class="results-header">
|
||||
<h2 class="results-title">
|
||||
<i class="fas fa-chart-network"></i>
|
||||
解析结果
|
||||
</h2>
|
||||
<div class="results-actions">
|
||||
<button id="copy-btn" class="action-btn">
|
||||
<i class="fas fa-copy"></i>
|
||||
<span>复制数据</span>
|
||||
</button>
|
||||
<button id="clear-btn" class="action-btn">
|
||||
<i class="fas fa-trash"></i>
|
||||
<span>清除结果</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="og-card">
|
||||
<!-- 基础信息 -->
|
||||
<div class="info-section basic-info">
|
||||
<div class="section-header">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
<span>基础信息</span>
|
||||
</div>
|
||||
<div class="info-grid">
|
||||
<div class="info-item">
|
||||
<label>标题</label>
|
||||
<div id="og-title" class="info-value">-</div>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<label>描述</label>
|
||||
<div id="og-description" class="info-value">-</div>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<label>网站名称</label>
|
||||
<div id="og-site-name" class="info-value">-</div>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<label>类型</label>
|
||||
<div id="og-type" class="info-value">-</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 媒体信息 -->
|
||||
<div class="info-section media-info">
|
||||
<div class="section-header">
|
||||
<i class="fas fa-image"></i>
|
||||
<span>媒体信息</span>
|
||||
</div>
|
||||
<div class="media-preview" id="media-preview">
|
||||
<div class="no-media">
|
||||
<i class="fas fa-image-slash"></i>
|
||||
<span>暂无媒体内容</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="media-details">
|
||||
<div class="info-item">
|
||||
<label>图片URL</label>
|
||||
<div id="og-image" class="info-value url-value">-</div>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<label>图片尺寸</label>
|
||||
<div id="og-image-size" class="info-value">-</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 技术信息 -->
|
||||
<div class="info-section tech-info">
|
||||
<div class="section-header">
|
||||
<i class="fas fa-code"></i>
|
||||
<span>技术信息</span>
|
||||
</div>
|
||||
<div class="info-grid">
|
||||
<div class="info-item">
|
||||
<label>URL</label>
|
||||
<div id="og-url" class="info-value url-value">-</div>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<label>域名</label>
|
||||
<div id="og-domain" class="info-value">-</div>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<label>语言</label>
|
||||
<div id="og-locale" class="info-value">-</div>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<label>字符编码</label>
|
||||
<div id="og-charset" class="info-value">-</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 错误信息 -->
|
||||
<div id="error" class="error-container" style="display: none;">
|
||||
<div class="error-content">
|
||||
<div class="error-icon">
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
</div>
|
||||
<div class="error-text">
|
||||
<h3 class="error-title">解析失败</h3>
|
||||
<p id="error-message" class="error-message">未知错误</p>
|
||||
</div>
|
||||
<button id="retryBtn" class="retry-btn">
|
||||
<i class="fas fa-redo"></i>
|
||||
<span>重新尝试</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 提示消息 -->
|
||||
<div id="tip-message" class="tip-container">
|
||||
<div class="tip-content">
|
||||
<i class="fas fa-lightbulb tip-icon"></i>
|
||||
<span class="tip-text"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Toast消息 -->
|
||||
<div id="toast" class="toast-container">
|
||||
<div class="toast-content">
|
||||
<i class="toast-icon"></i>
|
||||
<span class="toast-message"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 页脚 -->
|
||||
<footer class="footer">
|
||||
<div class="footer-content">
|
||||
<p class="footer-text">
|
||||
<i class="fas fa-shield-alt"></i>
|
||||
高级链接解析系统 | 神秘数据挖掘
|
||||
</p>
|
||||
<div class="footer-links">
|
||||
<span class="footer-link">隐私保护</span>
|
||||
<span class="footer-divider">|</span>
|
||||
<span class="footer-link">安全解析</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="js/script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
555
frontend/60sapi/实用功能/链接OG信息/js/script.js
Normal file
555
frontend/60sapi/实用功能/链接OG信息/js/script.js
Normal file
@@ -0,0 +1,555 @@
|
||||
// 链接OG信息查询 - JavaScript功能代码
|
||||
// 神秘高级风格的交互体验
|
||||
|
||||
class OGAnalyzer {
|
||||
constructor() {
|
||||
this.apiUrl = 'https://60s.viki.moe/v2/og';
|
||||
this.isAnalyzing = false;
|
||||
this.currentUrl = '';
|
||||
this.animationFrameId = null;
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
this.bindEvents();
|
||||
this.createBackgroundEffects();
|
||||
this.initializeAnimations();
|
||||
this.showWelcomeMessage();
|
||||
this.initPageAnimations();
|
||||
}
|
||||
|
||||
// 初始化页面动画
|
||||
initPageAnimations() {
|
||||
// 延迟添加动画类,确保CSS已加载
|
||||
setTimeout(() => {
|
||||
const header = document.querySelector('.header');
|
||||
const querySection = document.querySelector('.query-section');
|
||||
|
||||
if (header) header.classList.add('animate-in');
|
||||
if (querySection) querySection.classList.add('animate-in');
|
||||
}, 100);
|
||||
}
|
||||
|
||||
bindEvents() {
|
||||
const urlInput = document.getElementById('url-input');
|
||||
const analyzeBtn = document.getElementById('analyze-btn');
|
||||
const copyBtn = document.getElementById('copy-btn');
|
||||
const clearBtn = document.getElementById('clear-btn');
|
||||
|
||||
// 输入框事件
|
||||
urlInput.addEventListener('input', (e) => this.handleUrlInput(e));
|
||||
urlInput.addEventListener('keypress', (e) => {
|
||||
if (e.key === 'Enter' && !this.isAnalyzing) {
|
||||
this.analyzeUrl();
|
||||
}
|
||||
});
|
||||
urlInput.addEventListener('focus', () => this.handleInputFocus());
|
||||
urlInput.addEventListener('blur', () => this.handleInputBlur());
|
||||
|
||||
// 按钮事件
|
||||
analyzeBtn.addEventListener('click', () => this.analyzeUrl());
|
||||
copyBtn.addEventListener('click', () => this.copyResults());
|
||||
clearBtn.addEventListener('click', () => this.clearResults());
|
||||
|
||||
// 键盘快捷键
|
||||
document.addEventListener('keydown', (e) => this.handleKeyboard(e));
|
||||
}
|
||||
|
||||
handleUrlInput(e) {
|
||||
const url = e.target.value.trim();
|
||||
const analyzeBtn = document.getElementById('analyze-btn');
|
||||
|
||||
if (this.isValidUrl(url)) {
|
||||
analyzeBtn.classList.add('ready');
|
||||
e.target.classList.remove('error');
|
||||
} else {
|
||||
analyzeBtn.classList.remove('ready');
|
||||
if (url.length > 0) {
|
||||
e.target.classList.add('error');
|
||||
} else {
|
||||
e.target.classList.remove('error');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handleInputFocus() {
|
||||
const inputContainer = document.querySelector('.input-container');
|
||||
inputContainer.classList.add('focused');
|
||||
this.createInputGlow();
|
||||
}
|
||||
|
||||
handleInputBlur() {
|
||||
const inputContainer = document.querySelector('.input-container');
|
||||
inputContainer.classList.remove('focused');
|
||||
}
|
||||
|
||||
handleKeyboard(e) {
|
||||
// Ctrl/Cmd + Enter 快速分析
|
||||
if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
if (!this.isAnalyzing) {
|
||||
this.analyzeUrl();
|
||||
}
|
||||
}
|
||||
|
||||
// Escape 清除结果
|
||||
if (e.key === 'Escape') {
|
||||
this.clearResults();
|
||||
}
|
||||
}
|
||||
|
||||
isValidUrl(string) {
|
||||
try {
|
||||
const url = new URL(string);
|
||||
return url.protocol === 'http:' || url.protocol === 'https:';
|
||||
} catch (_) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async analyzeUrl() {
|
||||
const urlInput = document.getElementById('url-input');
|
||||
const url = urlInput.value.trim();
|
||||
|
||||
if (!this.isValidUrl(url)) {
|
||||
this.showError('请输入有效的URL地址');
|
||||
this.shakeInput();
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isAnalyzing) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.currentUrl = url;
|
||||
this.isAnalyzing = true;
|
||||
this.showLoading();
|
||||
this.hideError();
|
||||
this.hideResults();
|
||||
|
||||
try {
|
||||
const response = await fetch(`${this.apiUrl}?url=${encodeURIComponent(url)}`);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.code === 200 && data.data) {
|
||||
await this.displayResults(data.data);
|
||||
this.showSuccessMessage('分析完成!');
|
||||
|
||||
// 添加按钮闪烁效果
|
||||
const analyzeBtn = document.getElementById('analyze-btn');
|
||||
analyzeBtn.classList.add('flash');
|
||||
setTimeout(() => {
|
||||
analyzeBtn.classList.remove('flash');
|
||||
}, 300);
|
||||
} else {
|
||||
throw new Error(data.message || '获取OG信息失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('分析失败:', error);
|
||||
this.showError(`分析失败: ${error.message}`);
|
||||
} finally {
|
||||
this.isAnalyzing = false;
|
||||
this.hideLoading();
|
||||
}
|
||||
}
|
||||
|
||||
showLoading() {
|
||||
const loadingElement = document.getElementById('loading');
|
||||
const analyzeBtn = document.getElementById('analyze-btn');
|
||||
|
||||
loadingElement.classList.add('active');
|
||||
analyzeBtn.disabled = true;
|
||||
analyzeBtn.textContent = '分析中...';
|
||||
|
||||
this.startScannerAnimation();
|
||||
}
|
||||
|
||||
hideLoading() {
|
||||
const loadingElement = document.getElementById('loading');
|
||||
const analyzeBtn = document.getElementById('analyze-btn');
|
||||
|
||||
loadingElement.classList.remove('active');
|
||||
analyzeBtn.disabled = false;
|
||||
analyzeBtn.textContent = '开始分析';
|
||||
|
||||
this.stopScannerAnimation();
|
||||
}
|
||||
|
||||
async displayResults(data) {
|
||||
const resultsElement = document.getElementById('results');
|
||||
const ogCard = document.getElementById('og-card');
|
||||
|
||||
// 基础信息
|
||||
this.updateElement('og-title', data.title || '未获取到标题');
|
||||
this.updateElement('og-description', data.description || '未获取到描述');
|
||||
this.updateElement('og-url', data.url || this.currentUrl);
|
||||
this.updateElement('og-site-name', data.site_name || '未知站点');
|
||||
this.updateElement('og-type', data.type || 'website');
|
||||
|
||||
// 媒体信息
|
||||
this.updateImageElement('og-image', data.image);
|
||||
this.updateElement('og-image-alt', data.image_alt || '图片描述不可用');
|
||||
|
||||
// 技术信息
|
||||
this.updateElement('og-locale', data.locale || '未指定');
|
||||
this.updateElement('og-updated-time', this.formatDate(data.updated_time));
|
||||
this.updateElement('response-time', `${Date.now() - this.startTime}ms`);
|
||||
|
||||
// 显示结果
|
||||
resultsElement.classList.add('active');
|
||||
|
||||
// 添加动画效果
|
||||
await this.animateResults();
|
||||
|
||||
// 启用操作按钮
|
||||
document.getElementById('copy-btn').disabled = false;
|
||||
document.getElementById('clear-btn').disabled = false;
|
||||
}
|
||||
|
||||
updateElement(id, content) {
|
||||
const element = document.getElementById(id);
|
||||
if (element) {
|
||||
element.textContent = content;
|
||||
}
|
||||
}
|
||||
|
||||
updateImageElement(id, imageSrc) {
|
||||
const element = document.getElementById(id);
|
||||
if (element && imageSrc) {
|
||||
element.src = imageSrc;
|
||||
element.style.display = 'block';
|
||||
element.onerror = () => {
|
||||
element.style.display = 'none';
|
||||
const placeholder = element.nextElementSibling;
|
||||
if (placeholder && placeholder.classList.contains('image-placeholder')) {
|
||||
placeholder.style.display = 'flex';
|
||||
}
|
||||
};
|
||||
} else if (element) {
|
||||
element.style.display = 'none';
|
||||
const placeholder = element.nextElementSibling;
|
||||
if (placeholder && placeholder.classList.contains('image-placeholder')) {
|
||||
placeholder.style.display = 'flex';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
formatDate(timestamp) {
|
||||
if (!timestamp) return '未知';
|
||||
try {
|
||||
const date = new Date(timestamp);
|
||||
return date.toLocaleString('zh-CN');
|
||||
} catch (e) {
|
||||
return '格式错误';
|
||||
}
|
||||
}
|
||||
|
||||
async animateResults() {
|
||||
const cards = document.querySelectorAll('.info-card');
|
||||
|
||||
for (let i = 0; i < cards.length; i++) {
|
||||
setTimeout(() => {
|
||||
cards[i].classList.add('animate-in');
|
||||
}, i * 100);
|
||||
}
|
||||
|
||||
// 等待动画完成
|
||||
await new Promise(resolve => setTimeout(resolve, cards.length * 100 + 300));
|
||||
}
|
||||
|
||||
showError(message) {
|
||||
const errorElement = document.getElementById('error-message');
|
||||
const errorText = errorElement.querySelector('.error-text');
|
||||
const inputContainer = document.querySelector('.input-container');
|
||||
|
||||
errorText.textContent = message;
|
||||
errorElement.classList.add('active');
|
||||
|
||||
// 添加震动效果
|
||||
if (inputContainer) {
|
||||
inputContainer.classList.add('shake');
|
||||
setTimeout(() => {
|
||||
inputContainer.classList.remove('shake');
|
||||
}, 600);
|
||||
}
|
||||
|
||||
// 自动隐藏错误信息
|
||||
setTimeout(() => {
|
||||
this.hideError();
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
hideError() {
|
||||
const errorElement = document.getElementById('error-message');
|
||||
errorElement.classList.remove('active');
|
||||
}
|
||||
|
||||
hideResults() {
|
||||
const resultsElement = document.getElementById('results');
|
||||
resultsElement.classList.remove('active');
|
||||
|
||||
// 重置动画状态
|
||||
const cards = document.querySelectorAll('.info-card');
|
||||
cards.forEach(card => card.classList.remove('animate-in'));
|
||||
}
|
||||
|
||||
showSuccessMessage(message) {
|
||||
const tipElement = document.getElementById('tip-message');
|
||||
const tipText = tipElement.querySelector('.tip-text');
|
||||
|
||||
tipText.textContent = message;
|
||||
tipElement.classList.add('active');
|
||||
|
||||
setTimeout(() => {
|
||||
tipElement.classList.remove('active');
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
shakeInput() {
|
||||
const inputContainer = document.querySelector('.input-container');
|
||||
inputContainer.classList.add('shake');
|
||||
|
||||
setTimeout(() => {
|
||||
inputContainer.classList.remove('shake');
|
||||
}, 600);
|
||||
}
|
||||
|
||||
copyResults() {
|
||||
const ogData = {
|
||||
title: document.getElementById('og-title').textContent,
|
||||
description: document.getElementById('og-description').textContent,
|
||||
url: document.getElementById('og-url').textContent,
|
||||
site_name: document.getElementById('og-site-name').textContent,
|
||||
type: document.getElementById('og-type').textContent,
|
||||
image: document.getElementById('og-image').src,
|
||||
locale: document.getElementById('og-locale').textContent
|
||||
};
|
||||
|
||||
const jsonString = JSON.stringify(ogData, null, 2);
|
||||
|
||||
navigator.clipboard.writeText(jsonString).then(() => {
|
||||
this.showSuccessMessage('结果已复制到剪贴板!');
|
||||
this.flashCopyButton();
|
||||
}).catch(err => {
|
||||
console.error('复制失败:', err);
|
||||
this.showError('复制失败,请手动选择内容');
|
||||
});
|
||||
}
|
||||
|
||||
flashCopyButton() {
|
||||
const copyBtn = document.getElementById('copy-btn');
|
||||
copyBtn.classList.add('flash');
|
||||
|
||||
setTimeout(() => {
|
||||
copyBtn.classList.remove('flash');
|
||||
}, 300);
|
||||
}
|
||||
|
||||
clearResults() {
|
||||
const urlInput = document.getElementById('url-input');
|
||||
const resultsElement = document.getElementById('results');
|
||||
const errorElement = document.getElementById('error-message');
|
||||
|
||||
urlInput.value = '';
|
||||
urlInput.classList.remove('error');
|
||||
resultsElement.classList.remove('active');
|
||||
errorElement.classList.remove('active');
|
||||
|
||||
document.getElementById('analyze-btn').classList.remove('ready');
|
||||
document.getElementById('copy-btn').disabled = true;
|
||||
document.getElementById('clear-btn').disabled = true;
|
||||
|
||||
this.currentUrl = '';
|
||||
|
||||
// 重置动画状态
|
||||
const cards = document.querySelectorAll('.info-card');
|
||||
cards.forEach(card => card.classList.remove('animate-in'));
|
||||
|
||||
this.showSuccessMessage('已清除所有内容');
|
||||
}
|
||||
|
||||
createBackgroundEffects() {
|
||||
const container = document.querySelector('.background-container');
|
||||
|
||||
// 创建各种背景效果层
|
||||
const effects = [
|
||||
'geometric-grid',
|
||||
'neural-network',
|
||||
'particle-system',
|
||||
'scan-lines',
|
||||
'holographic-overlay',
|
||||
'data-stream',
|
||||
'quantum-waves'
|
||||
];
|
||||
|
||||
effects.forEach(effectClass => {
|
||||
const layer = document.createElement('div');
|
||||
layer.className = effectClass;
|
||||
container.appendChild(layer);
|
||||
});
|
||||
}
|
||||
|
||||
createInputGlow() {
|
||||
const inputContainer = document.querySelector('.input-container');
|
||||
|
||||
// 创建光晕效果
|
||||
const glow = document.createElement('div');
|
||||
glow.className = 'input-glow';
|
||||
inputContainer.appendChild(glow);
|
||||
|
||||
setTimeout(() => {
|
||||
if (glow.parentNode) {
|
||||
glow.remove();
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
startScannerAnimation() {
|
||||
const scanner = document.querySelector('.scanner');
|
||||
if (scanner) {
|
||||
scanner.classList.add('active');
|
||||
}
|
||||
}
|
||||
|
||||
stopScannerAnimation() {
|
||||
const scanner = document.querySelector('.scanner');
|
||||
if (scanner) {
|
||||
scanner.classList.remove('active');
|
||||
}
|
||||
}
|
||||
|
||||
initializeAnimations() {
|
||||
// 初始化页面动画
|
||||
const header = document.querySelector('.header');
|
||||
const querySection = document.querySelector('.query-section');
|
||||
|
||||
setTimeout(() => {
|
||||
header.classList.add('animate-in');
|
||||
}, 100);
|
||||
|
||||
setTimeout(() => {
|
||||
querySection.classList.add('animate-in');
|
||||
}, 300);
|
||||
}
|
||||
|
||||
showWelcomeMessage() {
|
||||
const tips = [
|
||||
'支持分析网页的标题、描述、图片等元信息',
|
||||
'可以预览社交媒体分享时的显示效果',
|
||||
'检测网页的SEO优化情况',
|
||||
'分析Open Graph协议标签'
|
||||
];
|
||||
|
||||
setTimeout(() => {
|
||||
this.showSuccessMessage('欢迎使用链接OG信息分析器!');
|
||||
}, 1000);
|
||||
|
||||
// 显示提示信息
|
||||
this.showTips(tips);
|
||||
}
|
||||
|
||||
// 显示提示信息
|
||||
showTips(tips) {
|
||||
const tipElement = document.getElementById('tip-message');
|
||||
const tipText = tipElement.querySelector('.tip-text');
|
||||
|
||||
let currentTip = 0;
|
||||
|
||||
const showNextTip = () => {
|
||||
tipText.textContent = tips[currentTip];
|
||||
tipElement.classList.add('active');
|
||||
tipElement.style.animation = 'fadeInUp 0.5s ease-out';
|
||||
|
||||
setTimeout(() => {
|
||||
tipElement.style.animation = 'fadeOutDown 0.5s ease-in';
|
||||
setTimeout(() => {
|
||||
tipElement.classList.remove('active');
|
||||
currentTip = (currentTip + 1) % tips.length;
|
||||
}, 500);
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
// 首次显示
|
||||
setTimeout(showNextTip, 2000);
|
||||
|
||||
// 每8秒显示一次
|
||||
setInterval(showNextTip, 8000);
|
||||
}
|
||||
}
|
||||
|
||||
// 工具函数
|
||||
function debounce(func, wait) {
|
||||
let timeout;
|
||||
return function executedFunction(...args) {
|
||||
const later = () => {
|
||||
clearTimeout(timeout);
|
||||
func(...args);
|
||||
};
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(later, wait);
|
||||
};
|
||||
}
|
||||
|
||||
function throttle(func, limit) {
|
||||
let inThrottle;
|
||||
return function() {
|
||||
const args = arguments;
|
||||
const context = this;
|
||||
if (!inThrottle) {
|
||||
func.apply(context, args);
|
||||
inThrottle = true;
|
||||
setTimeout(() => inThrottle = false, limit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 页面加载完成后初始化
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
// 检查必要的DOM元素
|
||||
const requiredElements = [
|
||||
'url-input', 'analyze-btn', 'copy-btn', 'clear-btn',
|
||||
'loading', 'results', 'error-message', 'tip-message'
|
||||
];
|
||||
|
||||
const missingElements = requiredElements.filter(id => !document.getElementById(id));
|
||||
|
||||
if (missingElements.length > 0) {
|
||||
console.error('缺少必要的DOM元素:', missingElements);
|
||||
return;
|
||||
}
|
||||
|
||||
// 初始化应用
|
||||
window.ogAnalyzer = new OGAnalyzer();
|
||||
|
||||
// 添加全局错误处理
|
||||
window.addEventListener('error', (e) => {
|
||||
console.error('全局错误:', e.error);
|
||||
if (window.ogAnalyzer) {
|
||||
window.ogAnalyzer.showError('发生未知错误,请刷新页面重试');
|
||||
}
|
||||
});
|
||||
|
||||
// 添加网络状态监听
|
||||
window.addEventListener('online', () => {
|
||||
if (window.ogAnalyzer) {
|
||||
window.ogAnalyzer.showSuccessMessage('网络连接已恢复');
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener('offline', () => {
|
||||
if (window.ogAnalyzer) {
|
||||
window.ogAnalyzer.showError('网络连接已断开');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 导出给其他模块使用
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = { OGAnalyzer, debounce, throttle };
|
||||
}
|
||||
3
frontend/60sapi/实用功能/链接OG信息/接口集合.json
Normal file
3
frontend/60sapi/实用功能/链接OG信息/接口集合.json
Normal file
@@ -0,0 +1,3 @@
|
||||
[
|
||||
"https://60s.api.shumengya.top"
|
||||
]
|
||||
66
frontend/60sapi/实用功能/链接OG信息/返回接口.json
Normal file
66
frontend/60sapi/实用功能/链接OG信息/返回接口.json
Normal file
@@ -0,0 +1,66 @@
|
||||
{
|
||||
"code": 200,
|
||||
"message": "success",
|
||||
"data": {
|
||||
"url": "https://example.com",
|
||||
"title": "示例网站标题",
|
||||
"description": "这是一个示例网站的描述信息,用于展示OG标签解析功能。",
|
||||
"image": "https://example.com/og-image.jpg",
|
||||
"site_name": "示例网站",
|
||||
"type": "website",
|
||||
"locale": "zh_CN",
|
||||
"author": "网站作者",
|
||||
"keywords": "示例,网站,OG标签,元数据",
|
||||
"favicon": "https://example.com/favicon.ico",
|
||||
"canonical_url": "https://example.com",
|
||||
"robots": "index,follow",
|
||||
"viewport": "width=device-width, initial-scale=1.0",
|
||||
"charset": "UTF-8",
|
||||
"language": "zh-CN",
|
||||
"published_time": "2024-01-01T00:00:00Z",
|
||||
"modified_time": "2024-01-15T12:30:00Z",
|
||||
"section": "技术",
|
||||
"tags": ["前端", "元数据", "SEO"],
|
||||
"twitter": {
|
||||
"card": "summary_large_image",
|
||||
"site": "@example",
|
||||
"creator": "@author",
|
||||
"title": "Twitter标题",
|
||||
"description": "Twitter描述",
|
||||
"image": "https://example.com/twitter-image.jpg"
|
||||
},
|
||||
"facebook": {
|
||||
"app_id": "123456789",
|
||||
"admins": "987654321"
|
||||
},
|
||||
"structured_data": {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "WebPage",
|
||||
"name": "示例网页",
|
||||
"description": "示例网页描述",
|
||||
"url": "https://example.com"
|
||||
},
|
||||
"meta_tags": {
|
||||
"generator": "WordPress 6.0",
|
||||
"theme-color": "#000000",
|
||||
"msapplication-TileColor": "#ffffff",
|
||||
"apple-mobile-web-app-capable": "yes",
|
||||
"apple-mobile-web-app-status-bar-style": "default"
|
||||
},
|
||||
"performance": {
|
||||
"load_time": 1.25,
|
||||
"page_size": "2.3MB",
|
||||
"requests_count": 45
|
||||
},
|
||||
"seo_score": {
|
||||
"overall": 85,
|
||||
"title_score": 90,
|
||||
"description_score": 80,
|
||||
"image_score": 85,
|
||||
"structure_score": 88
|
||||
}
|
||||
},
|
||||
"timestamp": "2024-01-15T12:30:45Z",
|
||||
"request_id": "req_123456789",
|
||||
"processing_time": 0.85
|
||||
}
|
||||
Reference in New Issue
Block a user