KeyboardEvent: code 屬性

可用性有限

此特性不是基線特性,因為它在一些最廣泛使用的瀏覽器中不起作用。

KeyboardEvent.code 屬性代表鍵盤上的一個物理按鍵(而不是按鍵產生的字元)。換句話說,此屬性返回的值不受鍵盤佈局或修飾鍵狀態的影響。

如果輸入裝置不是物理鍵盤,而是虛擬鍵盤或輔助功能裝置,則瀏覽器會盡量使返回的值與物理鍵盤的操作相匹配,以最大程度地提高物理和虛擬輸入裝置之間的相容性。

當您想根據輸入裝置上的物理位置來處理按鍵,而不是根據與這些按鍵關聯的字元來處理時,此屬性非常有用;這在編寫處理遊戲輸入的程式碼時尤其常見,這些遊戲使用鍵盤按鍵來模擬類似遊戲手柄的環境。但請注意,您不能使用 KeyboardEvent.code 報告的值來確定按鍵產生的字元,因為鍵碼的名稱可能與按鍵上實際列印的字元或按下按鍵時計算機生成的字元不匹配。

例如,在 QWERTY 佈局鍵盤上,Q 鍵返回的 code"KeyQ",但相同 code 值在 Dvorak 鍵盤上代表 ' 鍵,在 AZERTY 鍵盤上代表 A 鍵。這使得無法使用 code 的值來確定使用者按鍵的名稱,除非他們使用的是預期的鍵盤佈局。

要確定與按鍵事件對應的字元,請改用 KeyboardEvent.key 屬性。

Windows、Linux 和 macOS 的程式碼值在 KeyboardEvent: code 值頁面上列出。

示例

實踐 KeyboardEvent

HTML

html
<p>
  Press keys on the keyboard to see what the KeyboardEvent's key and code values
  are for each one.
</p>
<div id="output" tabindex="0"></div>

CSS

css
#output {
  font-family: "Helvetica", "Arial", sans-serif;
  border: 1px solid black;
  width: 95%;
  margin: auto;
}
#output:focus-visible {
  outline: 3px solid dodgerblue;
}

JavaScript

js
window.addEventListener("keydown", (event) => {
  const p = document.createElement("p");
  p.textContent = `KeyboardEvent: key='${event.key}' | code='${event.code}'`;
  document.getElementById("output").appendChild(p);
  window.scrollTo(0, document.body.scrollHeight);
});

動手試試

為確保按鍵能夠傳送到示例,請在按下按鍵之前單擊或聚焦下面的輸出框。

在遊戲中處理鍵盤事件

此示例為 keydown 事件設定了一個事件監聽器,該監聽器處理遊戲中的鍵盤輸入,該遊戲使用典型的“WASD”鍵盤佈局進行前、左、後和右的轉向。無論實際對應的字元是什麼,例如使用者使用的是 AZERTY 鍵盤,這四個鍵的物理按鍵都相同。

HTML

html
<p>Use the WASD (ZQSD on AZERTY) keys to move and steer.</p>
<svg
  xmlns="http://www.w3.org/2000/svg"
  version="1.1"
  class="world"
  tabindex="0">
  <polygon id="spaceship" points="15,0 0,30 30,30" />
</svg>

CSS

css
.world {
  margin: 0px;
  padding: 0px;
  background-color: black;
  width: 400px;
  height: 400px;
}
.world:focus-visible {
  outline: 5px solid dodgerblue;
}
#spaceship {
  fill: orange;
  stroke: red;
  stroke-width: 2px;
}

JavaScript

JavaScript 程式碼的第一部分設定了我們將要使用的一些變數。shipSize 包含玩家正在移動的飛船的大小,方便起見。position 用於跟蹤飛船在遊戲區域內的位置。moveRate 是每次按鍵使飛船前進和後退的畫素數,turnRate 是左右轉向控制元件每次按鍵應用的旋轉度數。angle 是當前應用於飛船的旋轉角度(以度為單位);它從 0°(向上直射)開始。最後,spaceship 設定為引用 ID 為 "spaceship" 的元素,這是代表玩家控制的飛船的 SVG 多邊形。

js
let shipSize = {
  width: 30,
  height: 30,
};

let position = {
  x: 200,
  y: 200,
};

let moveRate = 9;
let turnRate = 5;

let angle = 0;

let spaceship = document.getElementById("spaceship");

接下來是 updatePosition() 函式。此函式以要移動的距離作為輸入,其中正數表示前進,負數表示後退。此函式根據移動的距離和飛船當前面向的方向計算飛船的新位置。它還負責確保飛船在遊戲區域邊界內環繞,而不是消失。

js
function updatePosition(offset) {
  let rad = angle * (Math.PI / 180);
  position.x += Math.sin(rad) * offset;
  position.y -= Math.cos(rad) * offset;

  if (position.x < 0) {
    position.x = 399;
  } else if (position.x > 399) {
    position.x = 0;
  }

  if (position.y < 0) {
    position.y = 399;
  } else if (position.y > 399) {
    position.y = 0;
  }
}

refresh() 函式透過使用 SVG transform 來處理應用旋轉和位置。

js
function refresh() {
  let x = position.x - shipSize.width / 2;
  let y = position.y - shipSize.height / 2;
  let transform = `translate(${x} ${y}) rotate(${angle} 15 15) `;

  spaceship.setAttribute("transform", transform);
}
refresh();

最後,使用 addEventListener() 方法開始監聽 keydown 事件,透過更新飛船的位置和旋轉角度來響應每個按鍵,然後呼叫 refresh() 來在飛船的新位置和角度繪製飛船。

js
window.addEventListener("keydown", (event) => {
  if (event.defaultPrevented) {
    return; // Do nothing if event already handled
  }

  switch (event.code) {
    case "KeyS":
    case "ArrowDown":
      // Handle "back"
      updatePosition(-moveRate);
      break;
    case "KeyW":
    case "ArrowUp":
      // Handle "forward"
      updatePosition(moveRate);
      break;
    case "KeyA":
    case "ArrowLeft":
      // Handle "turn left"
      angle -= turnRate;
      break;
    case "KeyD":
    case "ArrowRight":
      // Handle "turn right"
      angle += turnRate;
      break;
  }

  refresh();

  if (event.code !== "Tab") {
    // Consume the event so it doesn't get handled twice,
    // as long as the user isn't trying to move focus away
    event.preventDefault();
  }
});

動手試試

為確保按鍵能夠傳送到示例程式碼,請在按下按鍵之前單擊或聚焦下面的黑色遊戲區域。

此程式碼有幾種可以改進的地方。大多數真正的遊戲會監聽 keydown 事件,在發生時開始移動,並在相應 keyup 事件發生時停止移動,而不是依賴按鍵重複。這將允許更平滑、更快的移動,但也能讓玩家同時進行移動和轉向。還可以使用過渡或動畫使飛船的移動更平滑。

規範

規範
UI 事件
# dom-keyboardevent-code

瀏覽器相容性