395
0

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>YYDS IP地址查询</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif;
}
body {
background: linear-gradient(135deg, #ffc2cd, #ff82ab);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
color: #333;
}
.container {
background: rgba(255, 255, 255, 0.95);
border-radius: 20px;
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.15);
width: 100%;
max-width: 1100px;
overflow: hidden;
animation: fadeIn 0.6s ease-out;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
header {
background: linear-gradient(90deg, #ff82ab, #ff5c8d);
color: white;
padding: 30px;
text-align: center;
position: relative;
overflow: hidden;
}
header::before {
content: "";
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
background: radial-gradient(circle, rgba(255,255,255,0.2) 0%, transparent 70%);
transform: rotate(30deg);
}
h1 {
font-size: 2.5rem;
margin-bottom: 8px;
letter-spacing: 1px;
position: relative;
text-shadow: 0 2px 4px rgba(0,0,0,0.2);
}
.subtitle {
opacity: 0.9;
font-weight: 300;
font-size: 1.1rem;
position: relative;
max-width: 600px;
margin: 0 auto;
line-height: 1.6;
}
.input-section {
padding: 30px;
display: flex;
flex-direction: column;
gap: 20px;
border-bottom: 1px solid #ffe4e8;
}
.input-group {
display: flex;
flex-wrap: wrap;
gap: 15px;
}
#ip-input {
flex: 1;
min-width: 200px;
padding: 18px 25px;
border: 2px solid #ffc2d1;
border-radius: 50px;
font-size: 1.15rem;
transition: all 0.3s;
box-shadow: 0 4px 10px rgba(0,0,0,0.05);
}
#ip-input:focus {
border-color: #ff82ab;
outline: none;
box-shadow: 0 0 0 4px rgba(255, 130, 171, 0.2);
}
#query-btn {
background: linear-gradient(to right, #ff82ab, #ff5c8d);
color: white;
border: none;
border-radius: 50px;
padding: 18px 40px;
font-size: 1.15rem;
font-weight: 600;
cursor: pointer;
transition: all 0.3s;
display: flex;
align-items: center;
gap: 10px;
box-shadow: 0 4px 15px rgba(255, 130, 171, 0.3);
}
#query-btn:hover {
background: linear-gradient(to right, #ff709a, #ff4a7d);
transform: translateY(-3px);
box-shadow: 0 6px 20px rgba(255, 130, 171, 0.4);
}
#query-btn:active {
transform: translateY(-1px);
}
.result-section {
padding: 0 30px 30px;
}
.result-card {
background: #fff9fb;
border-radius: 16px;
padding: 30px;
min-height: 250px;
box-shadow: inset 0 0 15px rgba(0, 0, 0, 0.05);
border: 1px solid #ffe4e8;
}
.result-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 25px;
padding-bottom: 15px;
border-bottom: 2px solid #ffe4e8;
}
.result-title {
font-size: 1.5rem;
color: #ff5c8d;
display: flex;
align-items: center;
gap: 10px;
}
.current-ip {
background: #ffe4e8;
color: #ff5c8d;
padding: 8px 15px;
border-radius: 30px;
font-weight: 600;
font-size: 0.9rem;
display: flex;
align-items: center;
gap: 10px;
}
.result-placeholder {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 150px;
color: #ff82ab;
font-style: italic;
text-align: center;
gap: 15px;
}
.ip-info-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 25px;
margin-bottom: 30px;
}
.info-item {
background: white;
padding: 20px;
border-radius: 12px;
box-shadow: 0 5px 15px rgba(255, 130, 171, 0.1);
border-left: 4px solid #ff82ab;
transition: transform 0.3s;
}
.info-item:hover {
transform: translateY(-5px);
box-shadow: 0 8px 20px rgba(255, 130, 171, 0.15);
}
.info-label {
font-weight: 600;
color: #ff5c8d;
margin-bottom: 12px;
font-size: 1rem;
display: flex;
align-items: center;
gap: 8px;
}
.info-value {
font-size: 1.25rem;
color: #ff709a;
word-break: break-word;
line-height: 1.4;
}
footer {
background: #ffe4e8;
padding: 20px;
text-align: center;
font-size: 0.95rem;
color: #ff5c8d;
display: flex;
justify-content: center;
align-items: center;
gap: 10px;
}
@media (max-width: 768px) {
h1 {
font-size: 2rem;
}
.input-section {
padding: 25px;
}
.result-section {
padding: 0 20px 25px;
}
.result-card {
padding: 25px;
}
.ip-info-grid {
gap: 15px;
}
.result-header {
flex-direction: column;
align-items: flex-start;
gap: 15px;
}
}
@media (max-width: 600px) {
h1 {
font-size: 1.8rem;
}
.subtitle {
font-size: 1rem;
}
.input-section {
padding: 20px;
}
#ip-input, #query-btn {
width: 100%;
}
#ip-input {
padding: 16px 20px;
}
#query-btn {
padding: 16px 20px;
justify-content: center;
}
}
.loader {
display: none;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 30px;
text-align: center;
}
.loader-spinner {
border: 5px solid rgba(255, 130, 171, 0.2);
border-top: 5px solid #ff82ab;
border-radius: 50%;
width: 50px;
height: 50px;
animation: spin 1s linear infinite;
margin-bottom: 20px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.error {
color: #e74c3c;
text-align: center;
padding: 20px;
font-weight: 500;
background: #fdeded;
border-radius: 10px;
margin: 20px;
display: none;
}
.features {
display: flex;
justify-content: space-around;
flex-wrap: wrap;
gap: 15px;
padding: 20px 0;
border-bottom: 1px solid #ffe4e8;
}
.feature {
display: flex;
align-items: center;
gap: 10px;
color: #ff5c8d;
font-weight: 500;
}
.feature i {
color: #ff82ab;
font-size: 1.2rem;
}
.map-container {
margin-top: 20px;
height: 400px;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 8px 25px rgba(0,0,0,0.1);
background: #fff9fb;
position: relative;
border: 1px solid #ffc2d1;
}
.map-placeholder {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background: #fff0f5;
color: #ff82ab;
font-weight: 500;
z-index: 100;
}
.copy-ip {
background: #fff0f5;
border: 1px solid #ffc2d1;
border-radius: 5px;
padding: 5px 10px;
font-size: 0.9rem;
cursor: pointer;
transition: all 0.3s;
display: inline-flex;
align-items: center;
gap: 5px;
margin-top: 10px;
color: #ff5c8d;
}
.copy-ip:hover {
background: #ffe4e8;
border-color: #ff82ab;
}
.notification {
position: fixed;
top: 20px;
right: 20px;
padding: 15px 25px;
background: #ff82ab;
color: white;
border-radius: 8px;
box-shadow: 0 5px 15px rgba(0,0,0,0.15);
transform: translateX(150%);
transition: transform 0.4s ease;
z-index: 1000;
display: flex;
align-items: center;
gap: 10px;
}
.notification.show {
transform: translateX(0);
}
.history {
margin-top: 20px;
padding: 15px;
background: white;
border-radius: 10px;
box-shadow: 0 3px 10px rgba(255,130,171,0.1);
}
.history h3 {
color: #ff5c8d;
margin-bottom: 10px;
display: flex;
align-items: center;
gap: 8px;
}
.history-items {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.history-item {
background: #ffe4e8;
color: #ff5c8d;
padding: 5px 12px;
border-radius: 30px;
font-size: 0.9rem;
cursor: pointer;
transition: all 0.3s;
}
.history-item:hover {
background: #ffc2d1;
transform: translateY(-2px);
}
.map-controls {
position: absolute;
bottom: 15px;
left: 15px;
z-index: 500;
background: rgba(255, 255, 255, 0.9);
border-radius: 5px;
padding: 8px 12px;
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
font-size: 14px;
display: flex;
align-items: center;
gap: 10px;
color: #ff5c8d;
font-weight: 500;
}
.map-controls .copy-btn {
color: #ff82ab;
cursor: pointer;
transition: all 0.3s;
}
.map-controls .copy-btn:hover {
color: #ff5c8d;
transform: scale(1.1);
}
.map-actions {
position: absolute;
top: 15px;
right: 15px;
z-index: 500;
display: flex;
gap: 8px;
}
.map-btn {
background: rgba(255, 255, 255, 0.9);
border: none;
border-radius: 50%;
width: 36px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
cursor: pointer;
transition: all 0.3s;
color: #ff5c8d;
}
.map-btn:hover {
background: white;
transform: translateY(-2px);
color: #ff4a7d;
}
.location-details {
position: absolute;
top: 15px;
left: 15px;
z-index: 500;
background: rgba(255, 255, 255, 0.9);
border-radius: 8px;
padding: 10px 15px;
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
max-width: 300px;
border-left: 4px solid #ff82ab;
}
.location-details h4 {
color: #ff5c8d;
margin-bottom: 5px;
display: flex;
align-items: center;
gap: 8px;
}
.location-details p {
color: #ff709a;
font-size: 1.1rem;
font-weight: 500;
line-height: 1.4;
}
.leaflet-container {
background: #fff9fb;
}
.leaflet-popup-content-wrapper {
border-radius: 8px;
box-shadow: 0 3px 10px rgba(255,130,171,0.2);
border: 2px solid #ffc2d1;
}
.leaflet-popup-content {
color: #ff5c8d;
font-weight: 500;
}
.leaflet-popup-tip {
background: #ffc2d1;
}
.map-legend {
position: absolute;
bottom: 60px;
left: 15px;
z-index: 500;
background: rgba(255, 255, 255, 0.9);
border-radius: 8px;
padding: 10px 15px;
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
max-width: 250px;
border-left: 4px solid #ff82ab;
}
.map-legend h4 {
color: #ff5c8d;
margin-bottom: 8px;
display: flex;
align-items: center;
gap: 8px;
font-size: 0.9rem;
}
.legend-item {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 5px;
font-size: 0.85rem;
}
.legend-color {
width: 15px;
height: 15px;
border-radius: 3px;
}
</style>
</head>
<body>
<div class="container">
<header>
<h1><i class="fas fa-map-marker-alt"></i> IP地址查询工具</h1>
<p class="subtitle">精准定位IP地址的地理位置,提供详细网络信息。粉色主题,细节丰富。</p>
</header>
<div class="features">
<div class="feature"><i class="fas fa-bolt"></i> 实时查询</div>
<div class="feature"><i class="fas fa-mobile-alt"></i> 完全自适应</div>
<div class="feature"><i class="fas fa-map-marked-alt"></i> 详细地图</div>
<div class="feature"><i class="fas fa-history"></i> 查询历史</div>
</div>
<section class="input-section">
<div class="input-group">
<input type="text" id="ip-input" placeholder="请输入要查询的IP地址(例如:8.8.8.8)">
<button id="query-btn">
<i class="fas fa-search"></i> 查询IP信息
</button>
</div>
</section>
<div class="loader" id="loader">
<div class="loader-spinner"></div>
<p>正在获取您的IP地址并查询相关信息...</p>
</div>
<div class="error" id="error"></div>
<section class="result-section">
<div class="result-card">
<div class="result-header">
<div class="result-title">
<i class="fas fa-info-circle"></i> IP地址查询结果
</div>
<div class="current-ip">
<i class="fas fa-network-wired"></i>
<span>您的IP: <span id="user-ip">加载中...</span></span>
<span class="copy-ip" id="copy-ip-btn"><i class="fas fa-copy"></i> 复制</span>
</div>
</div>
<div class="result-placeholder" id="result-placeholder">
<i class="fas fa-cloud" style="font-size: 3rem; color: #ffc2d1;"></i>
<p>正在获取并显示您的IP地址信息...</p>
</div>
<div class="ip-info-grid" id="result-container" style="display: none;">
<!-- 查询结果将通过JS动态填充 -->
</div>
<div class="map-container" id="map-container">
<div class="map-placeholder" id="map-placeholder">
<i class="fas fa-globe-americas" style="font-size: 3rem; margin-bottom: 15px;"></i>
<p>正在加载详细地图...</p>
</div>
<!-- 地图将通过Leaflet动态生成 -->
</div>
<div class="map-legend">
<h4><i class="fas fa-map"></i> 地图图例</h4>
<div class="legend-item">
<div class="legend-color" style="background: #ff82ab;"></div>
<span>当前位置</span>
</div>
<div class="legend-item">
<div class="legend-color" style="background: #ff5c8d;"></div>
<span>城市中心</span>
</div>
<div class="legend-item">
<div class="legend-color" style="background: #ffc2d1;"></div>
<span>主要区域</span>
</div>
</div>
<div class="history" id="history-section" style="display: none;">
<h3><i class="fas fa-history"></i> 查询历史</h3>
<div class="history-items" id="history-items">
<!-- 历史记录将通过JS动态填充 -->
</div>
</div>
</div>
</section>
<footer>
<i class="fas fa-database"></i>
<p>数据由𝒅𝒂𝒐.𝒌𝒆 api提供 | 使用𝑳𝒆𝒂𝒇𝒍𝒆𝒕地图 | 页面由𝒚𝒐𝒖𝒚𝒊.𝒔𝒊设计</p>
</footer>
</div>
<div class="notification" id="notification">
<i class="fas fa-check-circle"></i>
<span id="notification-text">操作成功</span>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const ipInput = document.getElementById('ip-input');
const queryBtn = document.getElementById('query-btn');
const resultContainer = document.getElementById('result-container');
const resultPlaceholder = document.getElementById('result-placeholder');
const loader = document.getElementById('loader');
const errorDiv = document.getElementById('error');
const userIpSpan = document.getElementById('user-ip');
const mapContainer = document.getElementById('map-container');
const mapPlaceholder = document.getElementById('map-placeholder');
const historySection = document.getElementById('history-section');
const historyItems = document.getElementById('history-items');
const copyIpBtn = document.getElementById('copy-ip-btn');
const notification = document.getElementById('notification');
const notificationText = document.getElementById('notification-text');
// 存储查询历史
let queryHistory = [];
let map = null;
let marker = null;
let circle = null;
// 初始加载时显示加载器
loader.style.display = 'flex';
resultPlaceholder.style.display = 'flex';
// 获取用户当前IP地址
function getUserIP() {
return new Promise((resolve, reject) => {
fetch('https://api.ipify.org?format=json')
.then(response => {
if (!response.ok) throw new Error('网络响应异常');
return response.json();
})
.then(data => {
resolve(data.ip);
})
.catch(() => {
fetch('https://ipinfo.io/json')
.then(res => {
if (!res.ok) throw new Error('网络响应异常');
return res.json();
})
.then(data => resolve(data.ip))
.catch(error => reject(error));
});
});
}
// 初始化地图
function initMap(lat, lon, data) {
// 移除旧地图
if (map) {
map.remove();
map = null;
}
// 隐藏占位符
mapPlaceholder.style.display = 'none';
// 创建新地图
map = L.map(mapContainer).setView([lat, lon], 13);
// 添加OpenStreetMap图层
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
maxZoom: 19
}).addTo(map);
// 添加标记
const pinkIcon = L.icon({
iconUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/images/marker-icon.png',
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/images/marker-shadow.png',
shadowSize: [41, 41]
});
marker = L.marker([lat, lon], {icon: pinkIcon}).addTo(map);
// 创建详细弹窗内容
let popupContent = `<div style="min-width:250px;font-family:Arial,sans-serif;">`;
popupContent += `<h4 style="color:#ff5c8d;margin-bottom:8px;border-bottom:1px solid #ffe4e8;padding-bottom:5px;">位置详情</h4>`;
popupContent += `<p><b>IP地址:</b> ${data.ip || '未知'}</p>`;
if (data.city) popupContent += `<p><b>城市:</b> ${data.city}</p>`;
if (data.region) popupContent += `<p><b>区域:</b> ${data.region}</p>`;
if (data.country_name) popupContent += `<p><b>国家:</b> ${data.country_name}</p>`;
if (data.postal) popupContent += `<p><b>邮编:</b> ${data.postal}</p>`;
if (data.timezone) popupContent += `<p><b>时区:</b> ${data.timezone}</p>`;
if (data.latitude && data.longitude) {
popupContent += `<p><b>坐标:</b> ${data.latitude.toFixed(4)}, ${data.longitude.toFixed(4)}</p>`;
}
popupContent += `</div>`;
marker.bindPopup(popupContent).openPopup();
// 添加位置精度圆
circle = L.circle([lat, lon], {
color: '#ff82ab',
fillColor: '#ffc2d1',
fillOpacity: 0.3,
radius: 2000
}).addTo(map);
// 添加城市中心标记
L.marker([lat + 0.02, lon + 0.01], {
icon: L.divIcon({
className: 'city-center-icon',
html: '<div style="background:#ff5c8d;width:15px;height:15px;border-radius:50%;border:2px solid white;box-shadow:0 0 5px rgba(0,0,0,0.3);"></div>',
iconSize: [15, 15]
})
}).addTo(map).bindPopup('城市中心');
// 添加地图控件
addMapControls(lat, lon, data.city, data);
}
// 添加地图控制按钮
function addMapControls(lat, lon, city, data) {
// 创建位置详情框
const locationDetails = document.createElement('div');
locationDetails.className = 'location-details';
locationDetails.innerHTML = `
<h4><i class="fas fa-map-pin"></i> ${city || '未知位置'}</h4>
<p>${data.region || ''}, ${data.country_name || ''}</p>
<p>坐标: ${lat.toFixed(4)}, ${lon.toFixed(4)}</p>
`;
mapContainer.appendChild(locationDetails);
// 创建坐标控件
const mapControls = document.createElement('div');
mapControls.className = 'map-controls';
mapControls.innerHTML = `
<span>${lat.toFixed(4)}, ${lon.toFixed(4)}</span>
<span class="copy-btn" title="复制坐标"><i class="fas fa-copy"></i></span>
`;
mapContainer.appendChild(mapControls);
// 创建操作按钮
const mapActions = document.createElement('div');
mapActions.className = 'map-actions';
mapActions.innerHTML = `
<button class="map-btn" title="放大" id="zoom-in"><i class="fas fa-plus"></i></button>
<button class="map-btn" title="缩小" id="zoom-out"><i class="fas fa-minus"></i></button>
<button class="map-btn" title="定位到我的位置" id="locate-me"><i class="fas fa-location-arrow"></i></button>
<button class="map-btn" title="卫星视图" id="satellite-view"><i class="fas fa-satellite"></i></button>
`;
mapContainer.appendChild(mapActions);
// 添加事件监听
document.getElementById('zoom-in').addEventListener('click', () => {
map.zoomIn();
});
document.getElementById('zoom-out').addEventListener('click', () => {
map.zoomOut();
});
document.getElementById('satellite-view').addEventListener('click', () => {
const isSatellite = map.hasLayer(satelliteLayer);
if (isSatellite) {
map.removeLayer(satelliteLayer);
map.addLayer(osmLayer);
} else {
map.removeLayer(osmLayer);
map.addLayer(satelliteLayer);
}
});
document.getElementById('locate-me').addEventListener('click', () => {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(position => {
map.setView([position.coords.latitude, position.coords.longitude], 13);
}, () => {
showNotification('无法获取您的位置信息');
});
} else {
showNotification('您的浏览器不支持定位功能');
}
});
mapControls.querySelector('.copy-btn').addEventListener('click', () => {
navigator.clipboard.writeText(`${lat.toFixed(4)}, ${lon.toFixed(4)}`)
.then(() => {
showNotification('坐标已复制到剪贴板');
})
.catch(() => {
showNotification('复制失败,请手动复制');
});
});
// 创建图层
const osmLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
maxZoom: 19
});
const satelliteLayer = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community',
maxZoom: 19
});
// 默认添加OSM图层
osmLayer.addTo(map);
}
// 查询IP信息
function queryIPInfo(ip) {
// 隐藏错误和结果,显示加载器
errorDiv.style.display = 'none';
resultPlaceholder.style.display = 'none';
resultContainer.style.display = 'none';
loader.style.display = 'flex';
historySection.style.display = 'none';
// 更新用户IP显示
userIpSpan.textContent = ip;
// 添加到查询历史
addToHistory(ip);
// 使用可靠的API查询
const apiUrl = `https://ipapi.co/${ip}/json/`;
fetch(apiUrl)
.then(response => {
if (!response.ok) throw new Error('网络响应异常');
return response.json();
})
.then(data => {
// 处理API响应数据
displayResults(data);
loader.style.display = 'none';
resultContainer.style.display = 'grid';
historySection.style.display = 'block';
// 更新地图显示
if (data.latitude && data.longitude) {
initMap(parseFloat(data.latitude), parseFloat(data.longitude), data);
} else {
mapPlaceholder.innerHTML = '<i class="fas fa-map-marked-alt" style="font-size: 3rem; margin-bottom: 15px;"></i><p>无法获取该IP的地理位置信息</p>';
}
})
.catch(error => {
loader.style.display = 'none';
errorDiv.textContent = `查询失败: ${error.message || '服务不可用,请稍后重试'}`;
errorDiv.style.display = 'block';
resultPlaceholder.style.display = 'flex';
mapPlaceholder.innerHTML = '<i class="fas fa-exclamation-triangle" style="font-size: 3rem; margin-bottom: 15px;"></i><p>地图加载失败</p>';
});
}
// 显示查询结果
function displayResults(data) {
// 清空之前的结果
resultContainer.innerHTML = '';
// 创建结果卡片
const infoItems = [
{ label: 'IP地址', value: data.ip || 'N/A', icon: 'fa-laptop' },
{ label: '国家/地区', value: (data.country_name || 'N/A') + (data.country ? ` (${data.country})` : ''), icon: 'fa-globe' },
{ label: '区域', value: data.region || 'N/A', icon: 'fa-map' },
{ label: '城市', value: data.city || 'N/A', icon: 'fa-city' },
{ label: '邮政编码', value: data.postal || 'N/A', icon: 'fa-envelope' },
{ label: '运营商', value: data.org || data.asn || 'N/A', icon: 'fa-network-wired' },
{ label: '时区', value: data.timezone || 'N/A', icon: 'fa-clock' },
{ label: '经纬度', value: data.latitude && data.longitude ? `${data.latitude}, ${data.longitude}` : 'N/A', icon: 'fa-location-dot' },
{ label: '货币', value: data.currency || 'N/A', icon: 'fa-money-bill' },
{ label: '语言', value: data.languages || 'N/A', icon: 'fa-language' },
{ label: '调用代码', value: data.country_calling_code || 'N/A', icon: 'fa-phone' },
{ label: 'ASN', value: data.asn || 'N/A', icon: 'fa-network-wired' }
];
infoItems.forEach(item => {
const itemElement = document.createElement('div');
itemElement.className = 'info-item';
itemElement.innerHTML = `
<div class="info-label"><i class="fas ${item.icon}"></i> ${item.label}</div>
<div class="info-value">${item.value}</div>
`;
resultContainer.appendChild(itemElement);
});
}
// 添加到查询历史
function addToHistory(ip) {
// 防止重复添加
if (!queryHistory.includes(ip)) {
queryHistory.unshift(ip);
if (queryHistory.length > 5) {
queryHistory.pop();
}
updateHistoryUI();
}
}
// 更新历史记录UI
function updateHistoryUI() {
historyItems.innerHTML = '';
queryHistory.forEach(ip => {
const historyItem = document.createElement('div');
historyItem.className = 'history-item';
historyItem.textContent = ip;
historyItem.addEventListener('click', () => {
ipInput.value = ip;
queryIPInfo(ip);
});
historyItems.appendChild(historyItem);
});
}
// 显示通知
function showNotification(message) {
notificationText.textContent = message;
notification.classList.add('show');
setTimeout(() => {
notification.classList.remove('show');
}, 3000);
}
// 事件监听
queryBtn.addEventListener('click', () => {
const ip = ipInput.value.trim();
if (ip) {
queryIPInfo(ip);
} else {
errorDiv.textContent = '请输入要查询的IP地址';
errorDiv.style.display = 'block';
}
});
// 按Enter键触发查询
ipInput.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
queryBtn.click();
}
});
// 复制IP地址
copyIpBtn.addEventListener('click', () => {
navigator.clipboard.writeText(userIpSpan.textContent)
.then(() => {
showNotification('IP地址已复制到剪贴板');
})
.catch(err => {
showNotification('复制失败,请手动复制');
});
});
// 页面加载完成后获取当前IP并查询
getUserIP()
.then(ip => {
ipInput.value = ip;
queryIPInfo(ip);
})
.catch(error => {
loader.style.display = 'none';
errorDiv.textContent = `无法获取您的IP地址: ${error.message || '请检查网络连接'}`;
errorDiv.style.display = 'block';
userIpSpan.textContent = '未知';
// 设置默认IP
ipInput.value = '8.8.8.8';
});
});
</script>
</body>
</html>
这家伙太懒了,什么也没留下。