draft.js_如何使用快捷方式在Draft.js中创建有序列表和无序列表
draft.js
by Andrey Semin
通過安德烈·塞米(Andrey Semin)
如何使用快捷方式在Draft.js中創(chuàng)建有序列表和無序列表 (How to create ordered and unordered lists in Draft.js with a shortcut)
We at Propeller have encountered many differences between Draft.js and popular text editors. We also found some issues like controlling list depth and multiline items in lists. The biggest difference is the inability to use shortcuts to start a list by default. Surprisingly enough you need to implement this logic yourself.
Propeller的我們?cè)贒raft.js和流行的文本編輯器之間遇到了許多差異。 我們還發(fā)現(xiàn)了一些問題,例如控制列表深度和列表中的多行項(xiàng)目。 最大的區(qū)別是默認(rèn)情況下無法使用快捷方式啟動(dòng)列表。 令人驚訝的是,您需要自己實(shí)現(xiàn)此邏輯。
As always, there is a plugin available to add support for the shortcuts you use. I also want to refer to draft-js-autolist-plugin as a source of inspiration. For some reason, this plugin didn’t work when we tried it. So we’ve come up with our own solution which is now presented in this post.
與往常一樣,有一個(gè)插件可用于添加對(duì)您所使用快捷方式的支持。 我也想?yún)⒖糳raft-js-autolist-plugin作為靈感來源。 出于某種原因,當(dāng)我們嘗試該插件時(shí)無法使用。 因此,我們提出了自己的解決方案,該解決方案現(xiàn)在將在本文中介紹。
問題 (The problem)
Open Google Docs, Word365, or whatever editor you use. Try to type * and then type space. Boom! You’ve started an unordered list. Nice feature to have, right?
打開Goog??le文檔,Word365或您使用的任何編輯器。 嘗試鍵入* ,然后鍵入space 。 繁榮! 您已經(jīng)開始了無序列表。 不錯(cuò)的功能,對(duì)不對(duì)?
If we try the exact same trick with the default Draft.js configuration, we will get nothing but plain text.
如果我們使用默認(rèn)的Draft.js配置嘗試完全相同的技巧,則只會(huì)得到純文本。
Let’s change it!
讓我們改變它!
解 (Solution)
To implement this feature, we need to keep track of the last three pressed buttons. Why three? Well, that’s because the longest character combination we need to support is 1. + space which is exactly three presses.
要實(shí)現(xiàn)此功能,我們需要跟蹤最后按下的三個(gè)按鈕。 為什么是三個(gè)? 好吧,這是因?yàn)槲覀冃枰С值淖铋L(zhǎng)字符組合是1. + space ,正好是三按。
To start, let’s implement the logic to store these presses. Here we would use a simple array named history. This array will store the value of the key that was pressed. We definitely don’t want to process any key presses with modifiers like shift, alt and so on. We can use Draft.js built-inKeyBindingUtil.hasCommandModifier function to perform the check for any modifier.
首先,讓我們實(shí)現(xiàn)存儲(chǔ)這些印刷機(jī)的邏輯。 在這里,我們將使用一個(gè)名為history的簡(jiǎn)單數(shù)組。 該數(shù)組將存儲(chǔ)所按下鍵的值。 我們絕對(duì)不希望使用shift , alt等修飾符來處理任何按鍵。 我們可以使用Draft.js內(nèi)置的KeyBindingUtil.hasCommandModifier函數(shù)執(zhí)行對(duì)任何修飾符的檢查。
Draft.js exposes a keyDown event for us in the keyBindingFn prop function. We are going to check if we need to start a list here. If so, we need to return a so calledDraftEditorCommand, which is a string. Also, to benefit from OS-level commands we need to add a getDefaultKeyBinding function call as a fall-through case.
Draft.js在keyBindingFn prop函數(shù)中為我們公開了一個(gè)keyDown事件。 我們將檢查是否需要在此處開始列表。 如果是這樣,我們需要返回一個(gè)所謂的DraftEditorCommand ,它是一個(gè)字符串。 另外,要從操作系統(tǒng)級(jí)別的命令中受益,我們需要添加getDefaultKeyBinding函數(shù)調(diào)用作為getDefaultKeyBinding案例。
We need to check if the currently pressed key is a space. If so we would run our checks against the history array. We check if we have a suitable set of previously pressed keys — * for an unordered list and 1. for an ordered one. If we find a match, we return a command(string) to be processed later.
我們需要檢查當(dāng)前按下的鍵是否為space 。 如果是這樣,我們將對(duì)history數(shù)組進(jìn)行檢查。 我們檢查是否有一組合適的先前按下的鍵- *表示無序列表, 1. .表示有序鍵。 如果找到匹配項(xiàng),則返回一個(gè)命令(字符串),以便稍后處理。
Now we need to implement the handleKeyCommand prop function and pass it to the editor. The logic is pretty simple. If we get one of our custom commands, we check if we should start a list on the current block. So here is a skeleton of the handleKeyCommand function.
現(xiàn)在,我們需要實(shí)現(xiàn)handleKeyCommand prop函數(shù)并將其傳遞給編輯器。 邏輯很簡(jiǎn)單。 如果得到自定義命令之一,則檢查是否應(yīng)在當(dāng)前塊上啟動(dòng)列表。 因此,這是handleKeyCommand函數(shù)的框架。
To check if we are good to start a list, we check if the currently selected block satisfies all three of the following rules:
要檢查是否可以很好地啟動(dòng)列表,請(qǐng)檢查當(dāng)前選定的塊是否滿足以下所有三個(gè)規(guī)則:
The block type is unstyled
塊類型是無unstyled
The block has a depth of 0
塊的depth為0
the block has * or 1. as a text
該塊具有*或1.作為文本
Let’s wrap it up with the code:
讓我們用代碼包裝一下:
Now we’re able to catch the exact case where Draft.js needs to start a list! Now it’s a time to implement the startList function.
現(xiàn)在,我們可以捕捉到Draft.js需要啟動(dòng)列表的確切情況! 現(xiàn)在是時(shí)候?qū)崿F(xiàn)startList函數(shù)了。
First of all, we need to map our custom commands to a particular list style. This means we need to start an unordered list for the start-unoredered-list command.
首先,我們需要將自定義命令映射到特定的列表樣式。 這意味著我們需要為start-unoredered-list命令啟動(dòng)一個(gè)無序列表。
We start an ordered list for the start-ordered-list command. Next, we need to update the styling of the block to the selected type. To do it we would use the toggleBlockType function of RichUtils module, which comes as a part of Draft.js.
我們?yōu)閟tart-ordered-list命令啟動(dòng)一個(gè)有序列表。 接下來,我們需要將塊的樣式更新為選定的類型。 為此,我們將使用RichUtils模塊的toggleBlockType函數(shù),該函數(shù)是RichUtils的一部分。
Next we need to replace the shortcut text we’ve entered with an empty string. To do it we need to call the replaceText method of the Modifier module. This method requires a selection range to determine what should be replaced. We need to get the selection out of the block and update it to have focusOffset value equal to block length. This combination means we want to replace the whole text we’ve entered.
接下來,我們需要將輸入的快捷方式文本替換為空字符串。 為此,我們需要調(diào)用Modifier模塊的replaceText方法。 此方法需要一個(gè)選擇范圍來確定應(yīng)替換的內(nèi)容。 我們需要從塊中取出選擇并進(jìn)行更新,以focusOffset值等于塊長(zhǎng)度。 這種組合意味著我們要替換輸入的整個(gè)文本。
Great! Now we need to update our local editor state with the new state we get from the startList function. So let’s bring it all together!
大! 現(xiàn)在,我們需要使用從startList函數(shù)獲得的新狀態(tài)來更新本地編輯器狀態(tài)。 因此,讓我們將它們放在一起!
OK! We’re almost done! But there is one more moment we need to handle. In some cases when one of our custom commands fire, we should not start a list based on the output of the shouldStartList function. We need to process the insertion of the space manually.
好! 我們快完成了! 但是,我們還有另外一刻需要處理。 在某些情況下,當(dāng)我們的自定義命令之一觸發(fā)時(shí),我們不應(yīng)基于shouldStartList函數(shù)的輸出來啟動(dòng)列表。 我們需要手動(dòng)處理空間的插入。
For implementation details of the getSelectedBlock method, check out my previous post on this Draft.js topic!
有關(guān)getSelectedBlock方法的實(shí)現(xiàn)細(xì)節(jié),請(qǐng)查看我以前關(guān)于此Draft.js主題的文章!
To do this we may want to use a method called insertText of the Modifier module. Obviously enough, it is used to build a new content state with the provided text inserted into it. As always, we need to provide the current content state, current selection state and the text we want to insert (a single space in our case).
為此,我們可能需要使用Modifier模塊的一個(gè)名為insertText的方法。 顯然,它用于通過插入所提供的文本來構(gòu)建新的內(nèi)容狀態(tài)。 與往常一樣,我們需要提供當(dāng)前的內(nèi)容狀態(tài),當(dāng)前的選擇狀態(tài)和我們要插入的文本(在本例中為單個(gè)空格)。
We need to add a call to this function to our handleKeyCommand function. So here is the final version of it:
我們需要在handleKeyCommand函數(shù)中添加對(duì)此函數(shù)的調(diào)用。 所以這是它的最終版本:
If you’ve read this post all the way through, you may also want to check out my previous post about Draft.js enchantment. You may want to apply it to your project as well.
如果您已經(jīng)閱讀了所有文章,那么您可能還想看看我以前有關(guān)Draft.js附魔的文章。 您可能還希望將其應(yīng)用于您的項(xiàng)目。
翻譯自: https://www.freecodecamp.org/news/how-to-create-ordered-and-unordered-lists-in-draft-js-with-a-shortcut-5de34a1a570f/
draft.js
總結(jié)
以上是生活随笔為你收集整理的draft.js_如何使用快捷方式在Draft.js中创建有序列表和无序列表的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 孕妇梦到老公出轨代表什么预兆
- 下一篇: 在Angular专家Dan Wahlin