文本编辑器
Framework7 附带一个触控友好的富文本编辑器组件。它基于现代的 "contenteditable" 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 方法
让我们看看与文本编辑器相关的 App 方法:
app.textEditor.create(参数)- 创建文本编辑器实例
- 参数 - 对象. 带有文本编辑器参数的对象
方法返回创建的文本编辑器实例
app.textEditor.destroy(el)- 销毁文本编辑器实例
- el - HTMLElement或字符串(使用 CSS 选择器) 或对象. 要销毁的文本编辑器元素或文本编辑器实例。
app.textEditor.get(el)- 通过 HTML 元素获取文本编辑器实例
- el - HTMLElement或字符串(带 CSS 选择器)。文本编辑器元素。
方法返回文本编辑器的实例
例如:
var textEditor = app.textEditor.create({
el: '#my-text-editor',
value: <code><p>Hello</p></code>,
});
文本编辑器参数
让我们看所有可用文本编辑器参数的列表:
参数 | 类型 | 默认 | 描述 |
---|---|---|---|
el | HTMLElement 字符串 | 文本编辑器元素。HTMLElement 或编辑器元素的 CSS 选择器字符串 | |
值 | 字符串 | 文本编辑器初始 HTML 内容值。初始值也可以放置为
| |
占位符 | 字符串 | 当编辑器为空时显示的编辑器占位符内容。默认情况下未指定 | |
模式 | 字符串 | toolbar | 文本编辑器按钮模式。可以是:
|
按钮 | 数组 | 带有编辑器按钮的数组,或带有编辑器按钮数组的数组(组)。默认情况下所有按钮都启用,其默认值是:
| |
dividers | 布尔值 | true | 在按钮组之间添加视觉分隔符 |
imageUrlText | 字符串 | 插入图像 URL | 图像 URL 请求时出现的提示文本 |
linkUrlText | 字符串 | 插入链接 URL | 链接 URL 请求时出现的提示文本 |
clearFormattingOnPaste | 布尔值 | true | 当启用时,它将清除从剪贴板粘贴的任何格式 |
customButtons | 对象 | 带有自定义按钮的对象。对象属性键是用于启用它的按钮 ID。 For example to specify custom button that will add
| |
on | 对象 | 带有事件处理程序的对象。例如:
|
注意,所有以下参数都可以在textEditor
属性用于为所有文本编辑器设置默认值。例如:
var app = new Framework7({
textEditor: {
buttons: ['bold', 'italic'],
}
});
文本编辑器方法 & 属性
初始化文本编辑器后,我们在变量中拥有其初始化的实例(例如textEditor
示例中使用的变量)中拥有颜色选择器的初始化实例,其中包含有用的方法和属性:
属性 | |
---|---|
textEditor.app | 链接到全局应用实例 |
textEditor.el | 文本编辑器容器 HTML 元素 |
textEditor.$el | 包含文本编辑器容器 HTML 元素的 Dom7 实例 |
textEditor.contentEl | 文本编辑器内容 (contenteditalbe ) HTML 元素的 Dom7 实例 |
textEditor.$contentEl | 包含文本编辑器内容 (contenteditalbe ) HTML 元素的 Dom7 实例 |
textEditor.value | 文本编辑器的 HTML 值 |
textEditor.params | 包含初始化参数的对象 |
方法 | |
textEditor.setValue(值) | 设置新的文本编辑器值。value 是 HTML 字符串。 |
textEditor.getValue() | 返回当前文本编辑器值 |
textEditor.clearValue() | 清除文本编辑器值 |
textEditor.getSelectionRange() | 返回当前选择范围 |
textEditor.setSelectionRange(范围) | 根据传递的范围设置选择 |
textEditor.destroy() | 销毁文本编辑器实例并移除所有事件 |
textEditor.on(事件上触发, 处理程序) | 添加事件处理程序 |
textEditor.once(事件上触发, 处理程序) | 添加在触发后将被移除的事件处理程序 |
textEditor.off(事件上触发, 处理程序) | 移除事件处理程序 |
textEditor.off(事件上触发) | 移除指定事件的所有处理程序 |
textEditor.emit(事件上触发, ...args) | 在实例上触发事件 |
文本编辑器事件
文本编辑器将在文本编辑器元素和 App 及文本编辑器实例上触发以下 DOM 事件:
DOM 事件
事件 | 描述 |
---|---|
texteditor:init | 当编辑器初始化时将触发此事件 |
文本编辑器:更改 | 当编辑器值发生变化时将触发事件 |
texteditor:input | 当编辑器内容发生“input”事件时将触发事件 |
texteditor:focus | 当编辑器内容获得焦点时将触发事件 |
texteditor:blur | 当编辑器内容失去焦点时将触发事件 |
texteditor:buttonclick | 当编辑器按钮被点击时将触发事件 |
texteditor:keyboardopen | 当编辑器键盘工具栏出现时将触发事件 |
texteditor:keyboardclose | 当编辑器键盘工具栏消失时将触发事件 |
texteditor:popoveropen | 当编辑器弹出框打开时将触发事件 |
texteditor:popoverclose | 当编辑器弹出框关闭时将触发事件 |
texteditor:beforedestroy | 在文本编辑器实例被销毁之前将触发事件 |
App 和文本编辑器实例事件
文本编辑器实例在自身实例和 App 实例上发出事件。App 实例事件具有相同名称,并以textEditor
.
事件 | Target | 参数 | 描述 |
---|---|---|---|
init | textEditor | (editor) | 当编辑器初始化时将触发此事件。 |
textEditorInit | app | ||
change | textEditor | (editor) | 当编辑器初始化时将触发此事件。 |
textEditorChange | app | ||
input | textEditor | (editor) | 当编辑器内容触发 "input" 事件时将触发此事件。 |
textEditorInput | app | ||
focus | textEditor | (editor) | 当编辑器内容获得焦点时将触发此事件。 |
textEditorFocus | app | ||
blur | textEditor | (editor) | 当编辑器内容失去焦点时将触发此事件。 |
textEditorBlur | app | ||
buttonClick | textEditor | (editor, button) | 当编辑器按钮被点击时将触发此事件。 作为第二个参数,事件处理程序接收被点击按钮的 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) | 在文本编辑器实例将被销毁之前将触发此事件。 |
textEditorBeforeDestroy | app |
文本编辑器自动初始化
如果你不需要使用文本编辑器 API,并且你的文本编辑器在页面内,并且在页面初始化时以 DOM 形式呈现,那么它可以通过仅添加额外的text-editor-init
class:
<!-- Add text-editor-init class -->
<div class="text-editor text-editor-init">
<div class="text-editor-content" contenteditable></div>
</div>
自动初始化。在这种情况下,如果你需要访问创建的文本编辑器实例,你可以使用app.textEditor.get
app method:
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>