iT邦幫忙

2026 iThome 鐵人賽

DAY 9
0
Software Development

從零打造網頁簡報編輯器系列 第 9

Day 09|選取、文字焦點與中文輸入如何共存

  • 分享至 

  • xImage
  •  

系列:一張投影片背後的工程:從零打造網頁簡報編輯器

對應程式版本:Git tag v0.1.0

版本說明:本文整理第一版的文字互動規則;後續多選、群組與文字格式功能仍先判斷是否正在輸入或組字。

物件可以選取後,DeleteBackspace 就有兩種完全不同的意思:可能是刪除一個投影片物件,也可能只是刪除文字中的一個字。中文輸入法更容易暴露這個衝突,因為組字期間的按鍵不能被全域快捷鍵搶走。

這一篇先把「選取」、「正在編輯」和「文件內容」分開,再決定每個事件應該由誰處理。

兩個介面狀態,不寫進簡報文件

文件只保存投影片與物件內容;選取框和游標焦點屬於目前畫面的暫時狀態:

狀態 用途 是否保存
selectedElementId 顯示選取框,決定快捷鍵的操作目標
editingElementId 讓指定文字框取得焦點並可輸入
element.text 真正要在下次開啟時還原的文字

因此,一個文字框可以被選取但尚未編輯;只有雙擊、按下 Enter,或新增文字後,才會讓兩個 ID 指向同一個物件。按 Esc 離開文字輸入時保留選取,按畫布空白處或在非輸入狀態按 Esc 才完全取消選取。

全域快捷鍵先讓輸入框通過

刪除物件的事件監聽器掛在視窗上,但它先排除播放模式、中文組字、文字編輯和所有文字輸入目標:

if (
  event.isComposing ||
  editingElementId ||
  isTextEntryTarget(event.target)
) {
  return
}

if (
  (event.key === 'Delete' || event.key === 'Backspace') &&
  selectedElementId
) {
  event.preventDefault()
  updateDocument({
    type: 'element/delete',
    slideId: resolvedActiveSlideId,
    elementId: selectedElementId,
  })
}

isTextEntryTarget 同時辨識 inputtextareacontenteditable。所以只要焦點在可輸入的地方,刪除鍵就交還給瀏覽器;只有沒有輸入焦點、且已選取物件時,才會刪除整個物件。

KeyboardEvent.isComposing 表示按鍵正處於 compositionstartcompositionend 之間。即使焦點或事件路徑之後增加新元件,這一層檢查仍能避免中文組字被當成編輯器快捷鍵。

文字元件也要保護自己的事件

文字框使用原生 textarea,平常是唯讀,進入編輯後才取得焦點。輸入元件再做一層事件隔離:

onCompositionStart={() => { compositionRef.current = true }}
onCompositionEnd={() => { compositionRef.current = false }}
onKeyDown={(event) => {
  event.stopPropagation()
  if (event.key === 'Escape' && !compositionRef.current) {
    event.currentTarget.blur()
  }
}}

這裡不攔截 Delete 或 Backspace 的預設行為,讓瀏覽器正常刪除文字;stopPropagation() 則避免事件再傳到畫布的快捷鍵處理。組字期間按 Esc 也不會強制失焦,等組字結束後才可用 Esc 結束編輯。onBlur 只清除 editingElementId,文字內容已經由 onChange 寫回文件。

用回歸測試鎖住破壞性邊界

測試刻意把兩條容易互相衝突的路徑放在一起:先在文字框觸發組字與 Delete,確認文字框仍存在;再離開輸入狀態,對已選取物件按 Delete,確認物件真的被刪除。這比只測試「可以輸入中文」更能防止未來新增快捷鍵時誤傷輸入法。

v0.1.0 的 8 個測試檔共定義 32 個案例,其中包含中文文字輸入、組字期間不刪物件、選取後 Delete 刪除物件。後續 Edge 手動驗收也以中文輸入法操作 Backspace 與 Delete,結果通過。

這個規則的重點不是把每個按鍵都特判,而是先確認目前事件屬於「輸入文字」還是「操作物件」。下一篇會把選取後的拖曳拉回實際操作,驗證不同縮放比例下如何仍然跟著游標移動。

參考資料


上一篇
Day 08|畫布縮放後座標如何保持正確
下一篇
Day 10|讓拖曳在不同縮放比例下都正確
系列文
從零打造網頁簡報編輯器13
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言