您现在的位置是:网站首页 > 代码里藏 Easter Egg(“按 Alt+F4 有惊喜”)文章详情

代码里藏 Easter Egg(“按 Alt+F4 有惊喜”)

代码里藏 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();
}

彩蛋设计注意事项

  1. 性能考量:确保彩蛋不会影响正常功能性能
// 不好的实现 - 每次按键都执行复杂计算
document.addEventListener('keydown', () => {
  heavyCalculation(); // 避免这种设计
});

// 好的实现 - 只有匹配特定模式才执行
let pattern = '';
document.addEventListener('keydown', (e) => {
  pattern += e.key;
  if (pattern.includes('secret')) {
    activateEgg();
    pattern = '';
  }
});
  1. 可访问性:确保彩蛋不会干扰辅助功能
// 添加彩蛋时考虑屏幕阅读器
function accessibleEgg() {
  const egg = document.createElement('div');
  egg.textContent = '你发现了一个彩蛋!';
  egg.setAttribute('role', 'alert');
  egg.setAttribute('aria-live', 'polite');
  document.body.appendChild(egg);
}
  1. 维护性:彩蛋代码也应该整洁
// 组织良好的彩蛋代码
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();
  1. 国际化考虑:彩蛋文本也应该翻译
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];
}

我的名片

网名:~川~

岗位:console.log 调试员

坐标:重庆市-九龙坡区

邮箱:cc@qdcc.cn

沙漏人生

站点信息

  • 建站时间:2013/03/16
  • 本站运行
  • 文章数量
  • 总访问量
微信公众号
每次关注
都是向财富自由迈进的一步