页面描述
这是一个纯静态的动漫角色展示平台,名为"动漫角色图鉴"。平台以网格布局展示10位热门动漫角色的卡片,用户可以通过搜索框按角色名、汉字名或作品名筛选角色。点击角色卡片可打开详情模态框,查看角色的详细信息,包括图片、生日、性别、身高、人气排名和角色简介等。
代码展示
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>动漫角色展示平台</title>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: '#6366F1',
secondary: '#EC4899',
dark: '#1E293B',
light: '#F8FAFC'
},
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif'],
},
}
}
}
</script>
<style type="text/tailwindcss">
@layer utilities {
.content-auto {
content-visibility: auto;
}
.card-hover {
@apply transition-all duration-300 hover:shadow-xl hover:-translate-y-1;
}
.text-shadow {
text-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
}
</style>
</head>
<body class="bg-gray-50 text-gray-800 min-h-screen flex flex-col">
<!-- 导航栏 -->
<header class="bg-gradient-to-r from-primary to-secondary text-white shadow-md">
<div class="container mx-auto px-4 py-4 flex flex-col md:flex-row justify-between items-center">
<div class="flex items-center mb-4 md:mb-0">
<i class="fa fa-fire text-3xl mr-3"></i>
<h1 class="text-[clamp(1.5rem,3vw,2.5rem)] font-bold text-shadow">动漫角色图鉴</h1>
</div>
<div class="w-full md:w-1/3 relative">
<input
type="text"
id="search-input"
placeholder="搜索角色或作品..."
class="w-full px-4 py-2 rounded-full focus:outline-none focus:ring-2 focus:ring-white/50 pl-10"
>
<i class="fa fa-search absolute left-3 top-1/2 transform -translate-y-1/2"></i>
</div>
</div>
</header>
<!-- 主要内容区 -->
<main class="flex-grow container mx-auto px-4 py-8">
<!-- 角色网格 -->
<div id="character-grid" class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-6 hidden">
<!-- 角色卡片将通过JavaScript动态生成 -->
</div>
</main>
<!-- 角色详情模态框 -->
<div id="character-modal" class="fixed inset-0 bg-black/70 flex items-center justify-center z-50 hidden">
<div class="bg-white rounded-2xl max-w-4xl w-full max-h-[90vh] overflow-y-auto m-4 transform transition-all">
<div class="relative">
<button id="close-modal" class="absolute top-4 right-4 bg-black/50 hover:bg-black/70 text-white rounded-full w-8 h-8 flex items-center justify-center z-10 transition-colors">
<i class="fa fa-times"></i>
</button>
<div id="modal-content" class="p-6">
<!-- 模态框内容将通过JavaScript动态生成 -->
</div>
</div>
</div>
</div>
<!-- 页脚 -->
<footer class="bg-dark text-white py-6 mt-12">
<div class="container mx-auto px-4 text-center">
<p>动漫角色图鉴 © 2023 | 数据来源于网络</p>
<p class="text-sm text-gray-400 mt-2">使用Jikan API提供动漫数据</p>
</div>
</footer>
<script>
// DOM元素
const characterGrid = document.getElementById('character-grid');
const searchInput = document.getElementById('search-input');
const characterModal = document.getElementById('character-modal');
const modalContent = document.getElementById('modal-content');
const closeModal = document.getElementById('close-modal');
// 静态角色数据
const allCharacters = [
{
id: 1,
name: '漩涡鸣人',
name_kanji: 'うずまき ナルト',
images: {
jpg: {
image_url: 'https://cdn.myanimelist.net/images/characters/10/50345.jpg'
}
},
anime: [{
anime: {
name: '火影忍者',
url: '#'
}
}],
birthday: '1999-10-10',
gender: '男',
height: '180cm',
popularity: 1,
about: '火之国木叶隐村的忍者,四代目火影波风水门和漩涡玖辛奈之子。刚出生时父母为保护村子而牺牲,并将尾兽九尾封印在鸣人体内。成为忍者后,和旗木卡卡西、宇智波佐助以及春野樱组成第七班进行各种任务。'
},
{
id: 2,
name: '宇智波佐助',
name_kanji: 'うちは サスケ',
images: {
jpg: {
image_url: 'https://cdn.myanimelist.net/images/characters/13/40402.jpg'
}
},
anime: [{
anime: {
name: '火影忍者',
url: '#'
}
}],
birthday: '1997-07-23',
gender: '男',
height: '182cm',
popularity: 2,
about: '火之国木叶隐村宇智波一族的天才忍者,六道仙人长子因陀罗的查克拉转世者。年幼时因宇智波一族被哥哥鼬所歼灭,从而走上复仇之路。在终结之谷与漩涡鸣人展开激战,将鸣人打败后叛离木叶前去追随大蛇丸。'
},
{
id: 3,
name: '蒙奇·D·路飞',
name_kanji: 'モンキー・D・ルフィ',
images: {
jpg: {
image_url: 'https://cdn.myanimelist.net/images/characters/12/339453.jpg'
}
},
anime: [{
anime: {
name: '海贼王',
url: '#'
}
}],
birthday: '1997-05-05',
gender: '男',
height: '174cm',
popularity: 3,
about: '草帽一伙船长,草帽大船团大船长,被称为"草帽小子"。梦想是找到传说中的One Piece,成为海贼王。性格积极乐观,爱憎分明,而且十分重视伙伴,对任何危险的事物都超感兴趣。'
},
{
id: 4,
name: '索隆',
name_kanji: 'ロロノア・ゾロ',
images: {
jpg: {
image_url: 'https://cdn.myanimelist.net/images/characters/7/339455.jpg'
}
},
anime: [{
anime: {
name: '海贼王',
url: '#'
}
}],
birthday: '1991-11-11',
gender: '男',
height: '181cm',
popularity: 4,
about: '草帽一伙战斗员,极恶的世代之一,被称为"海贼猎人"。是使用三把刀战斗的三刀流剑士。梦想是成为世界第一大剑豪。为了小时候与古伊娜的约定而踏上了前往世界第一剑士的道路。'
},
{
id: 5,
name: '春日野穹',
name_kanji: 'かすがの そら',
images: {
jpg: {
image_url: 'https://cdn.myanimelist.net/images/characters/4/122017.jpg'
}
},
anime: [{
anime: {
name: '缘之空',
url: '#'
}
}],
birthday: '2001-02-05',
gender: '女',
height: '152cm',
popularity: 5,
about: '春日野悠的妹妹。沉默寡言,弱不禁风,深居简出。逃避困难的人,麻烦的事情完全推给了哥哥。那犹如人偶一般的脸色,十分引人注目。喜欢除了泡面之外的全部无营养食品,如果不注意她,可能一会就会全部吃光。'
},
{
id: 6,
name: '时崎狂三',
name_kanji: 'ときさき くるみ',
images: {
jpg: {
image_url: 'https://cdn.myanimelist.net/images/characters/6/222357.jpg'
}
},
anime: [{
anime: {
name: '约会大作战',
url: '#'
}
}],
birthday: '2004-06-10',
gender: '女',
height: '157cm',
popularity: 6,
about: '突然转入来禅高中的转校生,自称喜欢士道。转学来时就对五河士道十分亲密,目的是为了和他"合为一体"。有着一头黑色长发,水晶般的紫色眼睛,以及说话时的轻佻语气。'
},
{
id: 7,
name: '初音未来',
name_kanji: '初音ミク',
images: {
jpg: {
image_url: 'https://cdn.myanimelist.net/images/characters/11/112771.jpg'
}
},
anime: [{
anime: {
name: 'VOCALOID',
url: '#'
}
}],
birthday: '2007-08-31',
gender: '女',
height: '158cm',
popularity: 7,
about: 'Crypton Future Media以Yamaha的VOCALOID 2语音合成引擎为基础开发的虚拟女性歌手软件角色主唱系列的第一作,是V家最受欢迎的角色之一。'
},
{
id: 8,
name: '雪之下雪乃',
name_kanji: 'ゆきのした ゆきの',
images: {
jpg: {
image_url: 'https://cdn.myanimelist.net/images/characters/11/214045.jpg'
}
},
anime: [{
anime: {
name: '我的青春恋爱物语果然有问题',
url: '#'
}
}],
birthday: '1996-01-03',
gender: '女',
height: '165cm',
popularity: 8,
about: '总武高中2年J班的学生,社团侍奉部的部长。性格孤傲,毒舌,对人对己都很严格。外表冷淡,内心温柔,有着不为人知的一面。'
},
{
id: 9,
name: '绫波丽',
name_kanji: '綾波 レイ',
images: {
jpg: {
image_url: 'https://cdn.myanimelist.net/images/characters/10/10440.jpg'
}
},
anime: [{
anime: {
name: '新世纪福音战士',
url: '#'
}
}],
birthday: '2001-03-30',
gender: '女',
height: '159cm',
popularity: 9,
about: 'EVA零号机的专属驾驶员,第一适格者。沉默寡言,面无表情,性格冷淡。真实身份是NERV利用第二使徒莉莉丝的灵魂和碇唯的DNA制作的克隆人。'
},
{
id: 10,
name: '黑崎一护',
name_kanji: '黒崎 一護',
images: {
jpg: {
image_url: 'https://cdn.myanimelist.net/images/characters/3/238155.jpg'
}
},
anime: [{
anime: {
name: '死神',
url: '#'
}
}],
birthday: '1987-07-15',
gender: '男',
height: '174cm',
popularity: 10,
about: '空座第一高中三年级学生,黑崎诊所的继承人。有着能看见幽灵的能力。在一次偶然的机会中,为了保护家人,从死神朽木露琪亚那里得到了死神的力量,从而成为了代理死神。'
}
];
// 渲染角色卡片
function renderCharacters(characters) {
characterGrid.innerHTML = '';
characters.forEach(character => {
const card = document.createElement('div');
card.className = 'bg-white rounded-xl overflow-hidden shadow-md card-hover group';
card.innerHTML = `
<div class="relative overflow-hidden aspect-[3/4]">
<img
src="${character.images.jpg.image_url}"
alt="${character.name}"
class="w-full h-full object-cover transition-transform duration-500 group-hover:scale-110"
>
<div class="absolute inset-0 bg-gradient-to-t from-black/70 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex items-end">
<div class="p-4 text-white">
<p class="text-sm font-medium">${character.anime[0]?.anime?.name || '未知作品'}</p>
</div>
</div>
</div>
<div class="p-4">
<h3 class="font-bold text-lg mb-1 truncate">${character.name}</h3>
<p class="text-gray-500 text-sm truncate">${character.name_kanji || '无汉字名称'}</p>
</div>
`;
// 点击卡片打开详情模态框
card.addEventListener('click', () => openCharacterModal(character));
characterGrid.appendChild(card);
});
// 显示网格
characterGrid.classList.remove('hidden');
}
// 打开角色详情模态框
function openCharacterModal(character) {
// 格式化生日
const birthday = character.birthday ? new Date(character.birthday).toLocaleDateString('zh-CN') : '未知';
// 获取主要作品
const mainAnime = character.anime[0]?.anime || { name: '未知作品', url: '#' };
modalContent.innerHTML = `
<div class="flex flex-col md:flex-row gap-6">
<!-- 角色图片 -->
<div class="md:w-1/3 flex justify-center md:justify-start">
<img
src="${character.images.jpg.image_url}"
alt="${character.name}"
class="rounded-lg shadow-lg max-w-full h-auto object-cover md:max-h-[500px] border-4 border-primary/20"
>
</div>
<!-- 角色信息 -->
<div class="md:w-2/3">
<h2 class="text-2xl font-bold mb-1">${character.name}</h2>
<p class="text-gray-500 mb-4">${character.name_kanji || '无汉字名称'}</p>
<div class="grid grid-cols-2 gap-4 mb-6">
<div class="bg-gray-50 p-3 rounded-lg">
<p class="text-sm text-gray-500">生日</p>
<p class="font-medium">${birthday}</p>
</div>
<div class="bg-gray-50 p-3 rounded-lg">
<p class="text-sm text-gray-500">性别</p>
<p class="font-medium">${character.gender || '未知'}</p>
</div>
<div class="bg-gray-50 p-3 rounded-lg">
<p class="text-sm text-gray-500">身高</p>
<p class="font-medium">${character.height || '未知'}</p>
</div>
<div class="bg-gray-50 p-3 rounded-lg">
<p class="text-sm text-gray-500">人气</p>
<p class="font-medium">#${character.popularity}</p>
</div>
</div>
<div class="mb-6">
<h3 class="text-xl font-bold mb-2">简介</h3>
<p class="text-gray-700 leading-relaxed">${character.about || '暂无简介信息'}</p>
</div>
<div>
<h3 class="text-xl font-bold mb-2">登场作品</h3>
<span class="inline-flex items-center bg-primary/10 text-primary px-4 py-2 rounded-full">
<i class="fa fa-film mr-2"></i>
${mainAnime.name}
</span>
</div>
</div>
</div>
`;
characterModal.classList.remove('hidden');
document.body.style.overflow = 'hidden'; // 防止背景滚动
}
// 关闭模态框
function closeCharacterModal() {
characterModal.classList.add('hidden');
document.body.style.overflow = ''; // 恢复背景滚动
}
// 搜索功能
function handleSearch() {
const searchTerm = searchInput.value.toLowerCase().trim();
if (!searchTerm) {
renderCharacters(allCharacters);
return;
}
const filteredCharacters = allCharacters.filter(character => {
// 搜索角色名、汉字名或作品名
const nameMatch = character.name.toLowerCase().includes(searchTerm);
const kanjiMatch = character.name_kanji?.toLowerCase().includes(searchTerm) || false;
const animeMatch = character.anime.some(item =>
item.anime?.name.toLowerCase().includes(searchTerm)
);
return nameMatch || kanjiMatch || animeMatch;
});
renderCharacters(filteredCharacters);
}
// 初始化
function init() {
renderCharacters(allCharacters);
}
// 事件监听
searchInput.addEventListener('input', handleSearch);
closeModal.addEventListener('click', closeCharacterModal);
// 点击模态框外部关闭
characterModal.addEventListener('click', (e) => {
if (e.target === characterModal) closeCharacterModal();
});
// 键盘ESC关闭模态框
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && !characterModal.classList.contains('hidden')) {
closeCharacterModal();
}
});
// 启动应用
init();
</script>
</body>
</html>
对应标签介绍
使用的HTML标签
1. 基础结构标签 : <!DOCTYPE html> , <html> , <head> , <body>
2. 元数据标签 : <meta charset> , <meta name="viewport"> , <title>
3. 资源引入标签 : <script> , <link>
4. 内容布局标签 : <header> , <main> , <footer> , <div>
5. 文本标签 : <h1> , <h2> , <h3> , <p> , <span>
6. 表单标签 : <input>
7. 交互标签 : <button>
8. 媒体标签 : <img>
9. 图标标签 : <i> (配合Font Awesome使用)
使用的CSS技术
1. 框架与工具 :
- Tailwind CSS 用于快速构建响应式UI
- 自定义工具类 (通过 @layer utilities 定义,如 content-auto , card-hover )
2. 布局与响应式 :
- 网格布局 (使用 grid , grid-cols-* , gap-* )
- 弹性布局 (使用 flex , flex-col , justify-between )
- 响应式前缀 ( sm: , md: , lg: , xl: ) 适配不同屏幕尺寸
3. 视觉效果 :
- 渐变背景 ( bg-gradient-to-r )
- 过渡动画 ( transition-all , duration-300 )
- 悬停效果 ( hover:shadow-xl , hover:-translate-y-1 )
- 文本阴影 ( text-shadow )
使用的JavaScript技术
1. DOM操作 :
- 获取DOM元素 ( getElementById )
- 动态创建和修改元素内容 ( innerHTML , createElement )
2. 事件处理 :
- 事件监听 ( addEventListener )
- 点击事件处理 (卡片点击、关闭按钮点击)
- 输入事件处理 (搜索框输入)
- 键盘事件处理 (ESC键关闭模态框)
3. 数据处理 :
- 静态数据存储与遍历 ( allCharacters 数组, forEach )
- 数据筛选 ( filter 用于搜索功能)
- 日期格式化 ( Date 对象)
4. UI交互 :
- 模态框控制 (显示/隐藏)
- 动态渲染角色卡片 ( renderCharacters 函数)
- 防止背景滚动 (修改 body.style.overflow )
项目完全使用静态数据实现,无需后端数据库支持,通过HTML、CSS和JavaScript实现了所有交互功能。