您现在的位置是:网站首页 > 代码里藏 Easter Egg(“按 Alt+F4 有惊喜”)文章详情
代码里藏 Easter Egg(“按 Alt+F4 有惊喜”)
陈川
【
前端综合
】
28923人已围观
11801字
代码里藏 Easter Egg(“按 Alt+F4 有惊喜”)
程序员总喜欢在代码里埋彩蛋,就像游戏开发者藏秘密关卡一样。这些隐藏的小惊喜不仅能给用户带来意外乐趣,还能体现开发者的幽默感。前端领域尤其适合玩这种花样,毕竟用户直接交互的就是界面。
键盘事件监听实现经典彩蛋
监听组合键是最常见的彩蛋触发方式。比如那个流传甚广的"Alt+F4有惊喜",虽然实际效果是关闭窗口,但我们可以创造更有趣的版本:
document.addEventListener('keydown', (e) => {
if (e.altKey && e.key === 'F4') {
e.preventDefault();
document.body.style.background = 'pink';
alert('骗你的!才不让你关呢~');
}
});
更复杂的组合键检测可以这样实现:
const konamiCode = ['ArrowUp', 'ArrowUp', 'ArrowDown', 'ArrowDown',
'ArrowLeft', 'ArrowRight', 'ArrowLeft', 'ArrowRight',
'b', 'a'];
let currentPosition = 0;
document.addEventListener('keydown', (e) => {
if (e.key === konamiCode[currentPosition]) {
currentPosition++;
if (currentPosition === konamiCode.length) {
// 科乐美代码触发成功
launchEasterEgg();
currentPosition = 0;
}
} else {
currentPosition = 0;
}
});
function launchEasterEgg() {
const dancingDino = document.createElement('div');
dancingDino.innerHTML = '🦖';
dancingDino.style.position = 'fixed';
dancingDino.style.bottom = '0';
dancingDino.style.fontSize = '100px';
dancingDino.style.animation = 'dance 1s infinite';
document.body.appendChild(dancingDino);
// 添加CSS动画
const style = document.createElement('style');
style.textContent = `
@keyframes dance {
0%, 100% { transform: rotate(-10deg); }
50% { transform: rotate(10deg); }
}
`;
document.head.appendChild(style);
}
隐藏式UI触发彩蛋
除了键盘事件,还可以设计隐藏的UI交互:
<div class="secret-area" style="
position: fixed;
bottom: 10px;
right: 10px;
width: 30px;
height: 30px;
opacity: 0.01;
cursor: pointer;
"></div>
<script>
document.querySelector('.secret-area').addEventListener('click', () => {
const fireworks = document.createElement('div');
fireworks.innerHTML = '🎆🎇✨';
fireworks.style.position = 'fixed';
fireworks.style.top = '0';
fireworks.style.left = '0';
fireworks.style.width = '100%';
fireworks.style.height = '100%';
fireworks.style.fontSize = '30px';
fireworks.style.textAlign = 'center';
fireworks.style.pointerEvents = 'none';
document.body.appendChild(fireworks);
// 随机位置显示烟花
setInterval(() => {
const spark = document.createElement('div');
spark.innerHTML = ['🎆', '🎇', '✨', '💥'][Math.floor(Math.random()*4)];
spark.style.position = 'absolute';
spark.style.left = `${Math.random()*100}%`;
spark.style.top = `${Math.random()*100}%`;
spark.style.fontSize = `${Math.random()*50 + 20}px`;
spark.style.animation = `fadeOut ${Math.random()*2 + 1}s forwards`;
fireworks.appendChild(spark);
setTimeout(() => spark.remove(), 3000);
}, 300);
});
</script>
<style>
@keyframes fadeOut {
to { opacity: 0; transform: translateY(-100px); }
}
</style>
控制台彩蛋进阶玩法
给喜欢打开开发者工具的用户准备惊喜:
const styles = [
'color: #fff',
'background: #f00',
'font-size: 20px',
'padding: 10px',
'border-radius: 5px'
].join(';');
console.log('%c 嘿!好奇的开发者!', styles);
console.log('%c 想不想看看我们的秘密?', 'color: #09f; font-size: 16px;');
// 重写console.log添加彩蛋
const originalLog = console.log;
console.log = function() {
if (arguments[0] && arguments[0].includes('password')) {
originalLog.apply(console, [
'%c 抓到你了!别偷看密码!',
'color: red; font-weight: bold; font-size: 14px;'
]);
return;
}
originalLog.apply(console, arguments);
};
// 控制台输入特定命令触发彩蛋
Object.defineProperty(window, 'secretCommand', {
get() {
document.body.style.background = 'linear-gradient(45deg, #ff0, #f0f)';
return '彩蛋已激活!';
}
});
基于时间的彩蛋设计
特殊日期触发不同的彩蛋效果:
function checkDateEggs() {
const now = new Date();
const month = now.getMonth() + 1;
const date = now.getDate();
// 愚人节彩蛋
if (month === 4 && date === 1) {
document.querySelectorAll('img').forEach(img => {
img.style.transform = 'rotate(180deg)';
});
}
// 万圣节彩蛋
if (month === 10 && date === 31) {
document.body.style.filter = 'hue-rotate(180deg) brightness(70%)';
const ghost = document.createElement('div');
ghost.innerHTML = '👻';
ghost.style.position = 'fixed';
ghost.style.right = '0';
ghost.style.fontSize = '100px';
ghost.style.animation = 'float 10s linear infinite';
document.body.appendChild(ghost);
}
// 开发者生日
if (month === 8 && date === 15) {
console.log('%c 今天是我的生日!', 'color: gold; font-size: 24px;');
document.title = '🎂 Happy Birthday!';
}
}
// 每分钟检查一次日期
setInterval(checkDateEggs, 60000);
checkDateEggs(); // 初始检查
本地存储的持久化彩蛋
让彩蛋状态可以保持:
// 点击计数器彩蛋
if (!localStorage.getItem('clickEgg')) {
localStorage.setItem('clickEgg', '0');
}
document.addEventListener('click', (e) => {
if (e.target.tagName !== 'BUTTON') {
const count = parseInt(localStorage.getItem('clickEgg')) + 1;
localStorage.setItem('clickEgg', count.toString());
if (count === 100) {
const party = document.createElement('div');
party.innerHTML = '🎉';
party.style.position = 'fixed';
party.style.left = `${e.clientX}px`;
party.style.top = `${e.clientY}px`;
party.style.fontSize = '30px';
party.style.zIndex = '9999';
party.style.animation = 'floatUp 2s forwards';
document.body.appendChild(party);
setTimeout(() => party.remove(), 2000);
}
}
});
// 彩虹模式彩蛋
function toggleRainbowMode() {
const rainbow = localStorage.getItem('rainbowMode');
if (rainbow === 'on') {
localStorage.setItem('rainbowMode', 'off');
document.body.classList.remove('rainbow-mode');
} else {
localStorage.setItem('rainbowMode', 'on');
document.body.classList.add('rainbow-mode');
}
}
// 检查是否启用彩虹模式
if (localStorage.getItem('rainbowMode') === 'on') {
document.body.classList.add('rainbow-mode');
}
// CSS彩虹效果
const style = document.createElement('style');
style.textContent = `
.rainbow-mode {
animation: rainbow 5s infinite;
}
@keyframes rainbow {
0% { background: #ff0000; }
14% { background: #ff7f00; }
28% { background: #ffff00; }
42% { background: #00ff00; }
57% { background: #0000ff; }
71% { background: #4b0082; }
85% { background: #9400d3; }
100% { background: #ff0000; }
}
`;
document.head.appendChild(style);
基于用户行为的智能彩蛋
// 记录用户行为模式
const behaviorPattern = {
scrollCount: 0,
clickPositions: [],
lastActiveTime: Date.now()
};
// 滚动事件监听
window.addEventListener('scroll', () => {
behaviorPattern.scrollCount++;
// 疯狂滚动触发彩蛋
if (behaviorPattern.scrollCount > 50) {
const message = document.createElement('div');
message.textContent = '找什么呢?这么着急...';
message.style.position = 'fixed';
message.style.top = '20px';
message.style.left = '50%';
message.style.transform = 'translateX(-50%)';
message.style.padding = '10px 20px';
message.style.background = '#fff';
message.style.borderRadius = '20px';
message.style.boxShadow = '0 2px 10px rgba(0,0,0,0.2)';
document.body.appendChild(message);
setTimeout(() => message.remove(), 3000);
behaviorPattern.scrollCount = 0;
}
});
// 鼠标移动轨迹分析
document.addEventListener('mousemove', (e) => {
behaviorPattern.clickPositions.push({x: e.clientX, y: e.clientY});
// 保留最近20个位置
if (behaviorPattern.clickPositions.length > 20) {
behaviorPattern.clickPositions.shift();
}
// 检测画圈动作
if (behaviorPattern.clickPositions.length >= 20) {
const first = behaviorPattern.clickPositions[0];
const last = behaviorPattern.clickPositions[19];
const distance = Math.sqrt(
Math.pow(last.x - first.x, 2) +
Math.pow(last.y - first.y, 2)
);
// 如果起点和终点接近,可能是在画圈
if (distance < 50) {
const canvas = document.createElement('canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
canvas.style.position = 'fixed';
canvas.style.top = '0';
canvas.style.left = '0';
canvas.style.pointerEvents = 'none';
document.body.appendChild(canvas);
const ctx = canvas.getContext('2d');
ctx.strokeStyle = `hsl(${Math.random()*360}, 100%, 50%)`;
ctx.lineWidth = 3;
ctx.beginPath();
behaviorPattern.clickPositions.forEach((pos, i) => {
if (i === 0) ctx.moveTo(pos.x, pos.y);
else ctx.lineTo(pos.x, pos.y);
});
ctx.stroke();
setTimeout(() => canvas.remove(), 2000);
behaviorPattern.clickPositions = [];
}
}
});
彩蛋的实用化变体
除了纯娱乐,彩蛋也可以有实用功能:
// 开发者快速工具
document.addEventListener('keydown', (e) => {
if (e.ctrlKey && e.shiftKey && e.key === 'D') {
const devTools = document.createElement('div');
devTools.style.position = 'fixed';
devTools.style.bottom = '0';
devTools.style.left = '0';
devTools.style.background = '#333';
devTools.style.color = '#fff';
devTools.style.padding = '10px';
devTools.style.zIndex = '9999';
devTools.innerHTML = `
<button onclick="document.body.contentEditable='true'">编辑模式</button>
<button onclick="document.body.contentEditable='false'">退出编辑</button>
<button onclick="localStorage.clear()">清除本地存储</button>
<button onclick="document.querySelectorAll('*').forEach(el => el.style.outline='1px solid #f00')">显示边界</button>
<button onclick="devTools.remove()">关闭工具</button>
`;
document.body.appendChild(devTools);
}
});
// 性能监控彩蛋
if (window.performance && performance.memory) {
const memMonitor = document.createElement('div');
memMonitor.style.position = 'fixed';
memMonitor.style.bottom = '10px';
memMonitor.style.right = '10px';
memMonitor.style.background = 'rgba(0,0,0,0.7)';
memMonitor.style.color = '#0f0';
memMonitor.style.padding = '5px';
memMonitor.style.fontFamily = 'monospace';
memMonitor.style.zIndex = '9999';
document.body.appendChild(memMonitor);
function updateMemInfo() {
const mem = performance.memory;
memMonitor.textContent = `JS内存: ${(mem.usedJSHeapSize / 1048576).toFixed(2)}MB / ${(mem.jsHeapSizeLimit / 1048576).toFixed(2)}MB`;
}
setInterval(updateMemInfo, 1000);
updateMemInfo();
}
彩蛋设计注意事项
- 性能考量:确保彩蛋不会影响正常功能性能
// 不好的实现 - 每次按键都执行复杂计算
document.addEventListener('keydown', () => {
heavyCalculation(); // 避免这种设计
});
// 好的实现 - 只有匹配特定模式才执行
let pattern = '';
document.addEventListener('keydown', (e) => {
pattern += e.key;
if (pattern.includes('secret')) {
activateEgg();
pattern = '';
}
});
- 可访问性:确保彩蛋不会干扰辅助功能
// 添加彩蛋时考虑屏幕阅读器
function accessibleEgg() {
const egg = document.createElement('div');
egg.textContent = '你发现了一个彩蛋!';
egg.setAttribute('role', 'alert');
egg.setAttribute('aria-live', 'polite');
document.body.appendChild(egg);
}
- 维护性:彩蛋代码也应该整洁
// 组织良好的彩蛋代码
const EasterEggs = {
konami: {
code: ['ArrowUp', 'ArrowUp', 'ArrowDown', 'ArrowDown',
'ArrowLeft', 'ArrowRight', 'ArrowLeft', 'ArrowRight',
'b', 'a'],
position: 0,
activate() {
// 激活逻辑
}
},
devTools: {
requiredKeys: ['Control', 'Shift', 'D'],
pressedKeys: new Set(),
activate() {
// 开发者工具逻辑
}
},
init() {
document.addEventListener('keydown', this.handleKeys.bind(this));
},
handleKeys(e) {
// 处理所有键盘彩蛋
}
};
EasterEggs.init();
- 国际化考虑:彩蛋文本也应该翻译
const eggMessages = {
'en-US': {
foundEgg: 'You found an easter egg!',
secret: 'This is a secret message'
},
'zh-CN': {
foundEgg: '你发现了一个彩蛋!',
secret: '这是一条秘密消息'
}
};
function getEggMessage(key) {
const lang = navigator.language || 'en-US';
return eggMessages[lang]?.[key] || eggMessages['en-US'][key];
}