文字編輯器
Framework7 附帶一個觸控友善的富文字編輯器元件。它基於現代的「可編輯內容」API,因此應該可以在任何地方正常運作。
它附帶基本的一組格式化功能。但它的功能可以輕鬆地延伸和自訂,以符合任何需求。
文字編輯器版面
<div class="text-editor">
<div class="text-editor-content" contenteditable></div>
</div>
為了讓編輯器可以調整大小(當它的高度符合其內容時),我們需要將 text-editor-resizable
類別新增到編輯器元素
<!-- additional "text-editor-resizable" class -->
<div class="text-editor text-editor-resizable">
<div class="text-editor-content" contenteditable></div>
</div>
文字編輯器應用程式方法
讓我們看看相關的應用程式方法來使用文字編輯器
app.textEditor.create(parameters)- 建立文字編輯器執行個體
- parameters - object。具有文字編輯器參數的物件
方法傳回已建立的文字編輯器執行個體
app.textEditor.destroy(el)- 銷毀文字編輯器執行個體
- el - HTMLElement 或 string(帶有 CSS 選擇器)或 object。要銷毀的文字編輯器元素或文字編輯器執行個體。
app.textEditor.get(el)- 透過 HTML 元素取得文字編輯器執行個體
- el - HTMLElement 或 string(帶有 CSS 選擇器)。文字編輯器元素。
方法傳回文字編輯器的執行個體
例如
var textEditor = app.textEditor.create({
el: '#my-text-editor',
value: <code><p>Hello</p></code>,
});
文字編輯器參數
讓我們看看所有可用的文字編輯器參數清單
參數 | 類型 | 預設值 | 說明 |
---|---|---|---|
el | HTMLElement string | 文字編輯器元素。HTMLElement 或帶有編輯器元素 CSS 選擇器的字串 | |
value | string | 文字編輯器初始 html 內容值。初始值也可以放置為
| |
placeholder | string | 編輯器 placeholder 內容,在編輯器為空時顯示。預設未指定 | |
mode | string | toolbar | 文字編輯器按鈕模式。可以是
|
按鈕 | 陣列 | 包含編輯器按鈕的陣列,或包含編輯器按鈕的陣列陣列(群組)。預設所有按鈕都已啟用,其預設值為
| |
分隔線 | 布林值 | true | 在按鈕群組之間加入視覺分隔線 |
imageUrlText | string | 插入圖片網址 | 在圖片網址要求上顯示的提示文字 |
linkUrlText | string | 插入連結網址 | 在連結網址要求上顯示的提示文字 |
clearFormattingOnPaste | 布林值 | true | 啟用後,它會清除從剪貼簿貼上的任何格式 |
customButtons | 物件 | 包含自訂按鈕的物件。物件屬性金鑰是應在 例如,若要指定會加入
| |
on | 物件 | 包含事件處理常式的物件。例如
|
請注意,所有下列參數都可以在 textEditor
屬性下的全域應用程式參數中使用,以設定所有文字編輯器的預設值。例如
var app = new Framework7({
textEditor: {
buttons: ['bold', 'italic'],
}
});
文字編輯器方法和屬性
初始化文字編輯器後,我們在變數中擁有其已初始化的執行個體(例如上述範例中的 textEditor
變數),其中包含有用的方法和屬性
屬性 | |
---|---|
textEditor.app | 連結到全域應用程式執行個體 |
textEditor.el | 文字編輯器容器 HTML 元素 |
textEditor.$el | 包含文字編輯器容器 HTML 元素的 Dom7 執行個體 |
textEditor.contentEl | 文字編輯器內容(contenteditalbe )HTML 元素 |
textEditor.$contentEl | 包含文字編輯器內容(contenteditalbe )HTML 元素的 Dom7 執行個體 |
textEditor.value | 文字編輯器的 HTML 值 |
textEditor.params | 包含初始化參數的物件 |
方法 | |
textEditor.setValue(value) | 設定新的文字編輯器值。value 是 HTML 字串。 |
textEditor.getValue() | 傳回目前的文字編輯器值 |
textEditor.clearValue() | 清除文字編輯器值 |
textEditor.getSelectionRange() | 傳回目前的選取範圍 |
textEditor.setSelectionRange(range) | 根據傳遞的範圍設定選取 |
textEditor.destroy() | 銷毀文字編輯器實例並移除所有事件 |
textEditor.on(event, handler) | 新增事件處理常式 |
textEditor.once(event, handler) | 新增事件處理常式,在觸發後將會移除 |
textEditor.off(event, handler) | 移除事件處理常式 |
textEditor.off(event) | 移除指定事件的所有處理常式 |
textEditor.emit(event, ...args) | 在實例上觸發事件 |
文字編輯器事件
文字編輯器會在文字編輯器元素上觸發下列 DOM 事件,以及在 app 和文字編輯器實例上觸發事件
DOM 事件
事件 | 說明 |
---|---|
texteditor:init | 編輯器初始化時會觸發事件 |
texteditor:change | 編輯器值變更時會觸發事件 |
texteditor:input | 編輯器內容「輸入」事件時會觸發事件 |
texteditor:focus | 編輯器內容獲得焦點時會觸發事件 |
texteditor:blur | 編輯器內容失去焦點時會觸發事件 |
texteditor:buttonclick | 編輯器按鈕被點擊時會觸發事件 |
texteditor:keyboardopen | 編輯器鍵盤工具列出現時會觸發事件 |
texteditor:keyboardclose | 編輯器鍵盤工具列消失時會觸發事件 |
texteditor:popoveropen | 編輯器彈出視窗開啟時會觸發事件 |
texteditor:popoverclose | 編輯器彈出視窗關閉時會觸發事件 |
texteditor:beforedestroy | 文字編輯器實例即將被銷毀之前會觸發事件 |
App 和文字編輯器實例事件
文字編輯器實例會在自身實例和 app 實例上發出事件。App 實例事件名稱相同,但前面加上 textEditor
。
事件 | 目標 | 參數 | 說明 |
---|---|---|---|
init | textEditor | (editor) | 編輯器初始化時會觸發事件。 |
textEditorInit | app | ||
change | textEditor | (editor) | 編輯器初始化時會觸發事件。 |
textEditorChange | app | ||
input | textEditor | (editor) | 編輯器內容「輸入」事件時會觸發事件。 |
textEditorInput | app | ||
focus | textEditor | (editor) | 編輯器內容獲得焦點時會觸發事件。 |
textEditorFocus | app | ||
模糊 | textEditor | (editor) | 事件會在編輯器的內容模糊時觸發。 |
textEditorBlur | app | ||
buttonClick | textEditor | (編輯器,按鈕) | 事件會在編輯器按鈕點擊時觸發。 作為第二個參數,事件處理器會收到點擊按鈕的 ID,例如 bold |
textEditorButtonClick | app | ||
keyboardOpen | textEditor | (editor) | 當編輯器鍵盤工具列出現時,事件會觸發。 |
textEditorKeyboardOpen | app | ||
keyboardClose | textEditor | (editor) | 當編輯器鍵盤工具列消失時,事件會觸發。 |
textEditorKeyboardClose | app | ||
popoverOpen | textEditor | (editor) | 事件會在編輯器彈出視窗開啟時觸發。 |
textEditorPopoverOpen | app | ||
popoverClose | textEditor | (editor) | 事件會在編輯器彈出視窗關閉時觸發。 |
textEditorPopoverClose | app | ||
beforeDestroy | textEditor | (editor) | 事件會在 Text Editor 執行個體被銷毀之前觸發。 |
textEditorBeforeDestroy | app |
Text Editor 自動初始化
如果您不需要使用 Text Editor API,而且您的 Text Editor 在頁面內部,並在頁面初始化時出現在 DOM 中,那麼它可以透過新增額外的 text-editor-init
類別來自動初始化
<!-- Add text-editor-init class -->
<div class="text-editor text-editor-init">
<div class="text-editor-content" contenteditable></div>
</div>
在這種情況下,如果您需要存取已建立的 Text Editor 執行個體,您可以使用 app.textEditor.get
應用程式方法
var textEditor = app.textEditor.get('.my-text-editor');
if (!textEditor.value) {
// do something
}
在使用自動初始化時,您可能需要傳遞額外的參數。這可以使用面板元素上的 data-
屬性來完成。
<!-- parameters set via data- attributes -->
<div
class="text-editor text-editor-init"
data-mode="popover"
data-placeholder="Description"
>
...
</div>
在 camelCase 中使用的參數,例如 imageUrlText,在 data 屬性中應使用 kebab-case,例如 data-image-url-text
CSS 變數
以下是相關 CSS 變數(CSS 自訂屬性)清單。
:root {
--f7-text-editor-font-size: inherit;
--f7-text-editor-font-weight: inherit;
--f7-text-editor-border-width: 1px;
--f7-text-editor-height: 250px;
--f7-text-editor-margin: 16px;
--f7-text-editor-padding: 8px;
--f7-text-editor-button-bg-color: transparent;
--f7-text-editor-button-size: 28px;
--f7-text-editor-button-icon-size: 20px;
--f7-text-editor-button-margin: 2px;
--f7-text-editor-text-color: #000;
--f7-text-editor-bg-color: #fff;
--f7-text-editor-button-divider-color: rgba(0, 0, 0, 0.15);
}
:root .dark,
:root.dark {
--f7-text-editor-bg-color: #121212;
--f7-text-editor-text-color: #fff;
--f7-text-editor-button-divider-color: rgba(255, 255, 255, 0.15);
}
.ios {
--f7-text-editor-toolbar-padding: 6px;
--f7-text-editor-button-border-radius: 2px;
--f7-text-editor-placeholder-color: rgba(0, 0, 0, 0.35);
--f7-text-editor-toolbar-border-color: rgba(0, 0, 0, 0.25);
--f7-text-editor-toolbar-bg-color: #fff;
--f7-text-editor-border-color: rgba(0, 0, 0, 0.1);
--f7-text-editor-button-text-color: #333;
}
.ios .dark,
.ios.dark {
--f7-text-editor-placeholder-color: rgba(255, 255, 255, 0.35);
--f7-text-editor-toolbar-bg-color: #121212;
--f7-text-editor-toolbar-border-color: rgba(255, 255, 255, 0.1);
--f7-text-editor-toolbar-bg-color: #202020;
--f7-text-editor-border-color: rgba(255, 255, 255, 0.1);
--f7-text-editor-button-text-color: #fff;
}
.md {
--f7-text-editor-button-border-radius: 8px;
--f7-text-editor-toolbar-padding: 8px;
}
.md,
.md .dark,
.md [class*='color-'] {
--f7-text-editor-placeholder-color: var(--f7-md-on-surface-variant);
--f7-text-editor-toolbar-bg-color: var(--f7-md-surface-1);
--f7-text-editor-border-color: var(--f7-md-outline);
--f7-text-editor-button-text-color: var(--f7-md-on-surface);
}
範例
<template>
<div class="page">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner sliding">
<div class="title">Text Editor</div>
</div>
</div>
<div class="page-content">
<div class="block">
<p>Framework7 comes with a touch-friendly Rich Text Editor component. It is based on modern "contenteditable"
API so it should work everywhere as is.</p>
<p>It comes with the basic set of formatting features. But its functionality can be easily extended and
customized to fit any requirements.</p>
</div>
<div class="block-title">Default Setup</div>
<div class="text-editor text-editor-init">
<div class="text-editor-content" contenteditable></div>
</div>
<div class="block-title">With Placeholder</div>
<div class="text-editor text-editor-init" data-placeholder="Enter text...">
<div class="text-editor-content" contenteditable></div>
</div>
<div class="block-title">With Default Value</div>
<div class="text-editor text-editor-init" data-placeholder="Enter text...">
<div class="text-editor-content" contenteditable>
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Consequatur sunt, sapiente quis eligendi
consectetur hic asperiores assumenda quidem dolore quasi iusto tenetur commodi qui ullam sint sed alias!
Consequatur, dolor!</p>
<p>Provident reiciendis exercitationem reprehenderit amet repellat laborum, sequi id quam quis quo quos facere
veniam ad libero dolorum animi. Nobis, illum culpa explicabo dolorem vitae ut dolor at reprehenderit magnam?
</p>
<p>Qui, animi. Dolores dicta, nobis aut expedita enim eum assumenda modi, blanditiis voluptatibus excepturi
non pariatur. Facilis fugit facere sequi molestias nemo in, suscipit inventore consequuntur, repellat
perferendis, voluptas odit.</p>
<p>Tempora voluptates, doloribus architecto eligendi numquam facilis perspiciatis autem quam voluptas maxime
ratione harum laudantium cum deleniti. In, alias deserunt voluptatibus eligendi libero nobis est unde et
perspiciatis cumque voluptatum.</p>
<p>Quam error doloribus qui laboriosam eligendi. Aspernatur quam pariatur perspiciatis reprehenderit atque
dicta culpa, aut rem? Assumenda, quibusdam? Reprehenderit necessitatibus facere nemo iure maiores porro
voluptates accusamus quibusdam. Nesciunt, assumenda?</p>
</div>
</div>
<div class="block-title">Specific Buttons</div>
<div class="block-header">It is possible to customize which buttons (commands) to show.</div>
<div class="text-editor text-editor-init" data-placeholder="Enter text..."
data-buttons='[["bold", "italic", "underline", "strikeThrough"], ["orderedList", "unorderedList"]]'>
<div class="text-editor-content" contenteditable></div>
</div>
<div class="block-title">Custom Button</div>
<div class="block-header">It is possible to create custom editor buttons. Here is the custom "hr" button that adds
horizontal rule:</div>
<div class="text-editor text-editor-custom-buttons">
<div class="text-editor-content" contenteditable></div>
</div>
<div class="block-title">Resizable</div>
<div class="block-header">Editor will be resized based on its content.</div>
<div class="text-editor text-editor-init text-editor-resizable" data-placeholder="Enter text..."
data-buttons='["bold", "italic", "underline", "strikeThrough"]'>
<div class="text-editor-content" contenteditable></div>
</div>
<div class="block-title">Popover Mode</div>
<div class="block-header">In this mode, there is no toolbar with buttons, but they appear as popover when you
select any text in editor.</div>
<div class="text-editor text-editor-init" data-placeholder="Enter text..."
data-buttons='["bold", "italic", "underline", "strikeThrough"]' data-mode="popover"
style="--f7-text-editor-height: 150px">
<div class="text-editor-content" contenteditable></div>
</div>
<div class="block-title">Keyboard Toolbar Mode</div>
<div class="block-header">In this mode, toolbar with buttons will appear on top of virtual keyboard when editor is
in the focus. It is supported only in iOS, Android cordova apps and in Android Chrome. When not supported it
will fallback to "popover" mode.</div>
<div class="text-editor text-editor-init" data-placeholder="Enter text..." data-mode="keyboard-toolbar"
style="--f7-text-editor-height: 150px">
<div class="text-editor-content" contenteditable></div>
</div>
<div class="block-title">As List Input</div>
<div class="block-header">Text editor can be used in list with other inputs. In this example it is enabled with
"keyboard-toolbar"/"popover" type for "About" field.</div>
<div class="list list-strong-ios list-dividers-ios list-outline-ios">
<ul>
<li class="item-content item-input">
<div class="item-media">
<i class="icon demo-list-icon"></i>
</div>
<div class="item-inner">
<div class="item-title item-label">Name</div>
<div class="item-input-wrap">
<input type="text" placeholder="Your name" />
</div>
</div>
</li>
<li class="item-content item-input">
<div class="item-media">
<i class="icon demo-list-icon"></i>
</div>
<div class="item-inner">
<div class="item-title item-label">About</div>
<div class="item-input-wrap">
<div class="text-editor text-editor-init text-editor-resizable" data-placeholder="About"
data-buttons='["bold", "italic", "underline", "strikeThrough"]' data-mode="popover">
<div class="text-editor-content" contenteditable></div>
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
</template>
<script>
export default (props, { $f7, $el, $on }) => {
let textEditorCustomButtons;
$on('pageInit', () => {
textEditorCustomButtons = $f7.textEditor.create({
el: $el.value.find('.text-editor-custom-buttons'),
// define custom "hr" button
customButtons: {
hr: {
content: '<hr>',
onClick(editor, buttonEl) {
document.execCommand('insertHorizontalRule', false);
},
},
},
buttons: [["bold", "italic", "underline", "strikeThrough"], "hr"],
});
});
$on('pageBeforeRemove', () => {
textEditorCustomButtons.destroy()
});
return $render;
};
</script>