如何在网页中正确打印居中对齐的菱形图案(含空格分隔)

本文详解 javascript 中使用 `document.write` 打印菱形图案时出现错位的根本原因,并提供基于等宽字体与 html 空格处理规范的完整解决方案。

在 Web 环境中用 JavaScript 打印菱形图案(如 * 构成的钻石形),看似是简单的循环逻辑问题,实则涉及 HTML 渲染机制字体排版特性 的双重影响。你遇到的“菱形歪斜”现象,根本原因并非代码逻辑错误,而是:

  • 普通空格(" ")在 HTML 中会被浏览器自动合并压缩(多个连续空格仅渲染为一个),导致缩进失效;
  • ❌ *非等宽字体(如默认的 sans-serif)中,空格字符宽度 ≠ `` 字符宽度**,即使空格未被压缩,视觉上仍无法对齐。

正确解法:双管齐下

1. 使用  (不换行空格)替代普通空格

  是 HTML 实体,表示不可折叠的空白字符,能确保每个“空格”都被独立渲染。注意:必须写为  (带分号),否则部分浏览器可能解析失败。

2. 强制启用等宽字体(Monospace)

在 CSS 中设置容器(如

或包裹 )使用等宽字体,确保   和 * 占据完全相同的水平空间:
body {
  font-family: 'Courier New', Consolas, monospace;
}

3. 修正逻辑:统一使用   控制间距与星号间隔

原代码中 document.write(" ", "*") 混用了普通空格和星号,既易被压缩又不对齐。应全部替换为  ,并注意:每颗星前需一个  ,但首颗星前的空格由外层缩进循环控制,避免冗余。

以下是修复后的完整、可运行代码:

function printDiamond(input) {
  if (typeof input === 'number' && input >= 1 && input <= 100) {
    // 上半部分(含顶点)
    for (let i = 1; i <= input; i++) {
      // 左侧缩进空格(共 input - i 个  )
      for (let b = 1; b <= input - i; b++) {
        document.write(' ');
      }
      // 星号行:i 颗星,每颗前加  (注意:第一颗星前已有缩进,此处从第二颗起补间隔)
      // 更清晰做法:先写一颗星,再循环写 " *" 共 i-1 次
      document.write('*');
      for (let a = 2; a <= i; a++) {
        document.write(' *');
      }
      document.write('
'); } // 下半部分(不含顶点) for (let i = input - 1; i >= 1; i--) { for (let b = 1; b <= input - i; b++) { document.write(' '); } document.write('*'); for (let a = 2; a <= i; a++) { document.write(' *'); } document.write('
'); } } else { console.error('Input must be a number between 1 and 100.'); } } // 调用示例 printDiamond(5);
? 关键细节说明: 每行星号之间用  * 连接,而非 " *",杜绝普通空格风险; 首颗星直接 document.write('*'),避免左侧多出一个无意义的  ; document.write('') 必须显式换行,HTML 不会自动识别 \n; 建议添加输入校验(如 input >= 1),增强鲁棒性。

替代方案(更现代、推荐)

虽然 document.write 可快速验证逻辑,但已不推荐用于生产环境(会阻塞解析、无法在 DOM 加载后调用)。更优实践是:

function printDiamondToElement(input, containerId = 'diamond-output') {
  const container = document.getElementById(containerId);
  if (!container) return;

  let html = '';
  const maxStars = input;

  // 构建上半部
  for (let i = 1; i <= maxStars; i++) {
    const spaces = ' '.repeat(maxStars - i);
    const stars = '*'.padStart(i, ' *'); // 简洁生成 "*,  *, ..."
    html += `${spaces}${stars}`;
  }
  // 构建下半部
  for (let i = maxStars - 1; i >= 1; i--) {
    const spaces = ' '.repeat(maxStars - i);
    const stars = '*'.padStart(i, ' *');
    html += `${spaces}${stars}`;
  }

  container.innerHTML = html;
}

配合 CSS:

#diamond-output {
  font-family: monospace;
  line-height: 1;
}

✅ 总结:菱形对齐 =  (语义化空格) + monospace(视觉等宽) + pre/
(保留格式)。掌握这三点,即可稳定输出工整钻石图案。