今天來看 Events 的部分,Event 的使用方式就和 JavaScript 的事件監聽一樣,透過指定的事件名稱來監聽,並執行指定的方法。
text-change
text-change
事件在編輯器的內容發生變化時觸發。變更的細節、變更前的內容,以及變更的來源都會提供出來。來源如果是使用者觸發的,則 source
就會是 user
。例如:
- 使用者在編輯器中打字
- 使用者使用工具列格式化文字
- 使用者使用快捷鍵回上一步
- 使用者使用作業系統拼寫校正
特例:
觸發內容變更的事件雖然也可能透過 API 呼叫,但如果觸發的原因是使用者操作導致的話,source
仍然要設為 user
。舉個例子:當使用者點擊工具欄的模組功能,該模組會呼叫變更的 API,但由於是使用者點擊所造成的變化,因此我們在模組呼叫 API 的時候,帶入的 source
仍必須是 user
。
Silent Source:
呼叫 API 處理的內容變更也可能以 source
為 silent
的方式觸發,在這樣的情況下 text-change
將不會被觸發。不建議這樣的操作,因為這樣可能會導致撤銷的堆疊紀錄異常,或是間接影響到需要完整內容變化紀錄的功能。
選取 (Selection) 發生變化
文字內容的變化可能導致 selection 變化(例如,打字使游標前進),但是在 text-change
handler 執行期間,selection 尚未更新,加上原生瀏覽器的行為可能導致 selection 狀態不一致的情況。因此要使用 selection-change
或 editor-change
來處理 selection 更新比較穩定。
Callback Signature:
handler(delta: Delta, oldContents: Delta, source: String)
範例:
quill.on('text-change', function(delta, oldDelta, source) {
if (source == 'api') {
console.log("An API call triggered this change.");
} else if (source == 'user') {
console.log("A user action triggered this change.");
}
});
selection-change
當使用者或 API 造成 selection 變更時觸發,range
代表 selection 的邊界。當 range
為 null
時,表示 selection 的丟失(通常是由於編輯器失去焦點)。我們也可以在收到 range
是 null
的時候,用這個事件當作焦點變更的 event 確認。
API 造成的選取範圍變更也可能會以 source
為 silent
觸發,在這樣的情況下就不會觸發 selection-change
。如果 selection-change
是 side effect 的話就很有用。例如:輸入文字造成 selection 變更,但每個字元都觸發 selection-change
的話就可能會造成干擾。
Callback Signature:
handler(range: { index: Number, length: Number },
oldRange: { index: Number, length: Number },
source: String)
範例:
quill.on('selection-change', function(range, oldRange, source) {
if (range) {
if (range.length == 0) {
console.log('User cursor is on', range.index);
} else {
const text = quill.getText(range.index, range.length);
console.log('User has highlighted', text);
}
} else {
console.log('Cursor not in the editor');
}
});
editor-change
當觸發 text-change
或 selection-change
事件時,也會跟著觸發 editor-change
,即使 source
是 silent
也是一樣。第一個參數是事件名稱,不是 text-change
就是 selection-change
,之後的通常是傳遞給這些相應的 handler 參數。
Callback Signature:
handler(name: String, ...args)
範例:
quill.on('editor-change', function(eventName, ...args) {
if (eventName === 'text-change') {
// args[0] will be delta
} else if (eventName === 'selection-change') {
// args[0] will be old range
}
});
on
監聽特定的事件並加入 event handler。
方法:
on(name: String, handler: Function): Quill
範例:
quill.on('text-change', function() {
console.log('Text change!');
});
once
為事件的一次觸發加入 event handler。
方法:
once(name: String, handler: Function): Quill
範例:
quill.once('text-change', function() {
console.log('First text change!');
});
off
移除 event handler
方法:
off(name: String, handler: Function): Quill
範例:
function handler() {
console.log('Hello!');
}
quill.on('text-change', handler);
quill.off('text-change', handler);
小結
Quill 提供了三種事件監聽類型分別是 text-change
,selection-change
,以及 editor-change
,整理一下今天練習的 event 方法:
- text-change:內容變化時觸發,包括使用者操作或API呼叫等。
- selection-change:選取範圍變更時觸發,提供選取的邊界,也能作為焦點變更的事件。
- editor-change:結合觸發
text-change
與selection-change
的變更。 - on:根據監聽類型加入對應的事件處理器。
- once:根據監聽類型加入只執行一次的事件處理器。
- off:移除事件處理器。
雜記
前幾天在 DefinitelyTyped 提的 Quill PR 終於合併了,目前只要重新 npm install 就能夠把 OP 類型錯誤的問題解決了,要確認一下 types 的版本是 2.0.12
。久違的 OpenSource contribution XD 希望對大家有所幫助 :D
Reference
文章同步發表於2023 iThome 鐵人賽