每日一言同款圣经网站:24小时独立开发从设计到上线

文章摘要
收起
周末闲来无事,我注意到"每日一言"这类简约网站越来越受欢迎,而作为一个有着基督教背景的开发者,突然想到:为什么不做一个每日圣经金句的版本呢?

说干就干!这个项目的目标很明确:创建一个简洁优雅的网站,每次访问都能展示一段随机的圣经经文,配上精美背景,让人在匆忙的生活中能有片刻安静思考。从构思到上线,我给自己设定了24小时的挑战期限。

每日一言圣经版

技术选型与API调研

首先需要找到一个可靠的圣经API。经过一番调研,选定了bible-api.com:

  1. 提供JSON格式的圣经经文
  2. 支持多种语言翻译版本
  3. 有专门的随机经文接口
  4. 支持CORS跨域请求
  5. 使用简单,文档清晰
这个API提供两种调用方式:
  1. 用户输入API - 直接通过URL指定书卷章节(如bible-api.com/john 3:16)
  2. 参数化API - 通过结构化路径获取(如/data/web/JHN/3)
    最重要的是它有一个/data/[translation]/random接口,完美符合"每日一节经文"的需求
设计理念:简约而不简单

设计上我决定遵循极简主义:

  1. 深色半透明遮罩 + 全屏背景图
  2. 经文居中展示,使用优雅的衬线字体
  3. 简洁交互,不干扰阅读体验
  4. 响应式设计,在任何设备上都能完美展示
核心功能开发
  1. 随机经文获取
    首先实现了基本的API调用功能:

    async function fetchRandomVerse() {
     try {
         const apiUrl = `https://bible-api.com/data/${currentTranslation}/random`;
         const response = await fetch(apiUrl);
         
         if (!response.ok) {
             throw new Error(`API request failed with status: ${response.status}`);
         }
         
         const data = await response.json();
         
         if (data && data.random_verse) {
             const verse = data.random_verse;
             const text = verse.text;
             const reference = `${verse.book} ${verse.chapter}:${verse.verse}`;
             
             displayVerse(text.trim(), reference);
             return;
         }
         
         // 处理其他可能的响应格式...
         
     } catch (error) {
         console.error('Error fetching bible verse:', error);
         useFallbackVerse();
     }
    }

    有趣的挑战之一是API响应格式可能因不同翻译版本而异,所以代码中包含了多种格式的解析逻辑。
    另外,为了避免API故障时网站无法使用,我添加了本地备用经文集:

    const fallbackVerses = [
     { text: 'For God so loved the world...', reference: 'John 3:16' },
     // 更多备用经文...
    ];
    function useFallbackVerse() {
     const randomFallback = fallbackVerses[Math.floor(Math.random() * fallbackVerses.length)];
     displayVerse(randomFallback.text, randomFallback.reference);
    }
    2. 背景图片功能

    设计了两种背景模式:

  2. 默认的耶稣图片背景
  3. 来自Bing的随机自然风景图
    切换背景时添加了平滑过渡效果:

    function setBackground(url) {
     const img = new Image();
     
     img.onload = () => {
         document.body.classList.add('transitioning');
         
         setTimeout(() => {
             document.body.style.backgroundImage = `url(${url})`;
             
             setTimeout(() => {
                 document.body.classList.remove('transitioning');
             }, 1000);
         }, 200);
     };
     
     img.src = url;
    }

    加载Bing图片时,添加了加载状态提示,避免用户困惑:

    function handleNatureBgClick() {
     if (!natureBgButton.classList.contains('active')) {
         wallpaperLoadingModal.classList.add('show');
         fetchNatureBackground();
         setActiveButton(natureBgButton);
     }
    }
    3. 多语言翻译支持

    实现了16种圣经翻译版本切换功能,包括英文、中文、拉丁文等:

    const translations = [
     { id: 'web', name: 'World English Bible', language: 'English' },
     { id: 'kjv', name: 'King James Version', language: 'English' },
     // 更多翻译版本...
     { id: 'cuv', name: 'Chinese Union Version', language: 'Chinese' },
    ];

    使用localStorage保存用户偏好设置:

    function confirmTranslation() {
     if (selectedTranslation !== currentTranslation) {
         currentTranslation = selectedTranslation;
         localStorage.setItem('bibleTranslation', currentTranslation);
         updateTranslationButton();
         fetchBibleVerse();
     }
     
     closeTranslationModal();
    }
    创意加分项:背景音乐播放器

    为了增强用户体验,添加了一个优雅的圆形音乐播放器,播放赞美诗:

    function setupAudioPlayer() {
     const audioPlayer = document.getElementById('audio-player');
     const playPauseBtn = document.getElementById('play-pause-btn');
     const playerContainer = document.querySelector('.audio-player-container');
     
     let isPlaying = true;
     
     function updatePlayState() {
         playPauseBtn.innerHTML = isPlaying ? 
             '<svg>...</svg>' : // 暂停图标
             '<svg>...</svg>'; // 播放图标
         
         if (isPlaying) {
             playerContainer.classList.add('playing');
         } else {
             playerContainer.classList.remove('playing');
         }
     }
     
     // 播放器交互逻辑...
    }

    播放器设计成能旋转的圆盘样式,音乐播放时会缓慢旋转,增添视觉趣味性。
    遇到的挑战与解决方案

    1. API响应格式不一致

    不同翻译版本的API返回格式略有不同,这需要编写更灵活的解析逻辑:

    // 尝试解析多种可能的响应格式
    if (data && data.random_verse) {
     // 格式1
    } else if (data && data.verse && typeof data.verse === 'object') {
     // 格式2
    } else if (data && data.verses && Array.isArray(data.verses)) {
     // 格式3
    } else if (data && data.text && data.reference) {
     // 格式4
    }
    2. 音频自动播放限制

    现代浏览器限制自动播放音频,解决方案是添加用户交互解锁:

    document.addEventListener('click', function() {
     if (audioPlayer.paused) {
         audioPlayer.play().catch(console.error);
         isPlaying = true;
         updatePlayState();
     }
    }, { once: true });
    3. 移动端适配

    需要确保在各种设备上都有良好体验,使用了媒体查询:

    @media (max-width: 768px) {
     #verse-container {
         padding: 30px;
     }
     
     h1 {
         font-size: 28px;
     }
     
     #verse-text {
         font-size: 20px;
     }
     /* 更多适配样式... */
    }
    
    @media (max-width: 480px) {
     /* 手机屏幕样式... */
    }
    细节处理与优化
  4. 加载动画
    为提升用户体验,添加了优雅的加载过渡:

    @keyframes fadeIn {
     from { opacity: 0; transform: translateY(20px); }
     to { opacity: 1; transform: translateY(0); }
    }
    2. 分享功能

    添加了一键分享功能,方便用户将经文复制到剪贴板:

    function copyVerseToClipboard() {
     const verseText = verseTextElement.textContent;
     const verseReference = verseReferenceElement.textContent;
     const websiteLink = "bible.drinsper.com";
     
     const textToCopy = `"${verseText}" - ${verseReference}\n\nRead more at: ${websiteLink}`;
     
     navigator.clipboard.writeText(textToCopy)
         .then(() => {
             copyConfirmation.classList.add('show');
             setTimeout(() => {
                 copyConfirmation.classList.remove('show');
             }, 3000);
         })
         .catch(err => {
             console.error('Could not copy text: ', err);
             alert('Failed to copy verse to clipboard. Please try again.');
         });
    }
    部署上线

    最后一步是将网站部署到线上。使用了简单的静态网站托管服务,域名选择了bible.drinsper.com,将整个项目打包上传后,网站立即可用!

    短时间内从零到成品,最大的体会是:
  5. 明确目标很重要:从一开始就清楚要做什么,避免了开发中的迷茫
  6. 优先核心功能:先实现核心API调用,再逐步添加其他功能,而不是同时处理所有事情
  7. 用户体验至上:即使是小项目,良好的加载体验、响应式设计和适当动效都能极大提升用户感受
  8. 优雅降级处理:API可能失败、图片可能加载错误,提前设计好容错方案很重要
    这个项目虽小,但涵盖了现代前端开发的多个方面,从API集成到响应式设计,从本地存储到优雅动效。有时候,简单的项目反而能给人带来意想不到的满足感。

    下一步计划添加更多功能,如夜间模式、更多背景选项、经文收藏功能等。
文章目录