предисловие
В этой статье автор представит процесс использования текстового редактора Baidu Ueditor в проекте React. Обратите внимание, что в этой статье не представлен универсальный метод использования, а только кратко изложены некоторые идеи реализации в процессе использования для справки. При импорте ueditor в реактивный проект будут возникать различные неортогональные проблемы, на которые необходимо обратить внимание.
представлять
Сначала загрузите последний установочный пакет на официальном сайте ueditor, а затем импортируйте его в html записи проекта (метод импорта другой, вы можете использовать метод импорта, вам нужно сделать это самостоятельно. Но не важно, какой метод импорта , если вы хотите настроить функцию, она не является ортогональной. Проблема, которую трудно избежать QAQ). Не важно что? .
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>ueditor demo</title>
</head>
<body>
<!-- 配置文件 -->
<script type="text/javascript" src="path/ueditor.config.js"></script>
<!-- 编辑器源码文件 -->
<script type="text/javascript" src="path/ueditor.all.js"></script>
······
</body>
</html>
Обратите внимание на использование ueditor в проекте React.
- Путь импорта, автор использует относительный путь после упаковки проекта webpack.
- Порядок импорта, файл конфигурации должен предшествовать исходному коду.
- В методе введения автора есть проблема с кешем, поэтому после модификации ueditor.all.js необходимо вовремя очищать кеш и тестировать новый код.
упаковка
/**
* 封装UEditor
*/
import React from 'react';
import './index.less';
class UEditor extends React.Component {
constructor(props) {
super(props);
this.editor = {};
this.id = '';
}
······
componentDidMount() {
let UE = window.UE;
let id = this.id;
if (id) {
try {
/* 加载之前先执行删除操作,否则如果存在页面切换,
再切回带编辑器页面重新加载时不刷新无法渲染出编辑器 */
UE.delEditor(id);
} catch (e) {}
let ueditor = UE.getEditor(id, {
toolbars: [
['bold', 'italic', 'underline', 'kityformula', 'diyimg']
],
initialContent: '',
autoHeightEnabled: false,
autoFloatEnabled: false,
elementPathEnabled: false,
wordCount: false,
enableAutoSave: false,
initialFrameWidth: this.props.width,
initialFrameHeight: this.props.height
});
}
}
render() {
this.id = this.props.id;
return <div styleName="content" id={this.id} />;
}
}
export default UEditor;
Автор использует в проекте такие функции, как выделение жирным шрифтом, курсивом, подчеркиванием, вставка изображений, формул и т. д. Если вы хотите настроить конфигурацию, вы можете обратиться к ueditor.config.js, чтобы изменить ее. Конкретные будут вводиться один за другим, и окончательный эффект будет следующим:
итог проблемы:
1. Отключить автоматическое увеличение высоты и вместо этого использовать полосу прокрутки
autoHeightEnabled: false
initialFrameWidth:this.props.width
initialFrameHeight:this.props.height
autoHeightEnabled
Вы можете запретить автоматическую высоту, а затем настроить ширину и высоту контейнера.
2. Настройте глобальные стили, такие как заполнение контейнера, высота строки тега p и т. д.
Решение: строка 6800+ файла ueditor.all.jsrender
метод, в котором можно настроить глобальные стили.
3. После переключения панели навигации ее нельзя отобразить снова.
Решение: перед созданием каждого экземпляра ueditor удалить соответствующий идентификатор
UE.delEditor(id);
Анализ причин:
Из исходного кода создания и выгрузки экземпляра:
getEditor
:
UE.getEditor = function (id, opt) {
var editor = instances[id];
if (!editor) {
editor = instances[id] = new UE.ui.Editor(opt);
editor.render(id);//渲染编辑器
}
return editor;
};
delEditor
:
UE.delEditor = function (id) {
var editor;
if (editor = instances[id]) {
editor.key && editor.destroy();
delete instances[id]
}
};
UE глобально управляет пулом экземпляров, и каждый экземпляр извлекается в соответствии с идентификатором, а затем генерируется экземпляр. отgetEditor
Как видно из исходного кода, экземпляр ueditor находится вПри инициализации в первый разесть одинeditor.render(), который отображает экземпляр этого идентификатора в соответствующий контейнер идентификаторов. Однако, когда вкладка пользователя переключает редактор и переключается обратно, в это время из-заЭкземпляр уже существует в пуле экземпляров, так что непосредственно выполнитьreturn editor
, поэтому шаг editor.render() отсутствует, поэтому его нельзя повторно отобразить. Таким образом, перед каждым созданием экземпляра компонента Ueditor сначала удаляется delEditor. Здесь следует отметить, что изdelEditor
Видно, что метод уничтожения экземпляра вызывается, когда редактор выгружает экземпляр. Из комментария уничтожить:Уничтожьте экземпляр редактора, вместо этого используйте текстовое поле, что объясняет, почему редактор становится текстовой областью при переключении редакторов или удалении редакторов, как показано на рисунке:
4. Имитация заполнителя для реализации предустановленной копии
Решение: Настройте метод в экземпляре UE, чтобы добиться эффекта заполнения текста для имитации заполнителя.Код выглядит следующим образом:
//模拟placeholder和控制toolbar显示隐藏
UE.Editor.prototype.initDiy = function (placeholder) {
var _editor = this;
//获取焦点
_editor.addListener("focus", function () {
UE.isEditored = true;
var Text = `<p style="color: #CDCDCD">${placeholder}</p>`
var localHtml = _editor.getContent();
if (localHtml === Text) {
_editor.setContent("");//点击时清空
_editor.focus(true);
}
//使得其他工具条display置为none
var list = document.querySelectorAll('.edui-editor-toolbarbox');
list.forEach((ele) => {
ele.style.display = 'none';
});
var toolbar = findKey(_editor.key);
toolbar.style.display = 'block';
});
// 插入图片时存在问题
// _editor.addListener("blur", function () {
// var localHtml = _editor.getContent();
// if (localHtml === '') {
// _editor.setContent(`<p style="color: #CDCDCD">${placeholder}</p>`);
// }
// // window.activeEditor = _editor.key;
// });
_editor.ready(function () {
// _editor.fireEvent("blur");
_editor.setContent(`<p style="color: #CDCDCD">${placeholder}</p>`);//填充预置文案
});
}
//寻找工具条
function findKey(key) {
let ele = document.querySelector(`#${key}`);
let toolbar = ele.querySelector('.edui-editor-toolbarbox');
return toolbar;
}
Оказалось, что эффект, достигнутый автором, заключается в очистке при нажатии и восстановлении при расфокусировке. Однако при создании пользовательских панелей инструментов возникла ошибка (подробнее я расскажу в 5), поэтому я выбрал другой подход:Первоначально установить предустановленную копию, очистить предустановку, когда пользователь фокусируется, и больше не восстанавливать предустановленную копию, когда пользователь теряет фокус.. То есть событие размытия аннотируется. . .
5. Панель инструментов отображается в шапке редактора, отображается в виде плавающего эффекта, скрыта по умолчанию и появляется при наведении фокуса
Реализовать идеи: добавить в themes/default/css/ueditor.css:
.edui-default .edui-editor-toolbarbox {
position: absolute;
······
top: -36px;
}
Сначала реализуйте смещение головы, а затем скройте панель инструментов, управляя отображением панели инструментов, соответствующей элементу dom. Эффект следующий:
Давайте объяснимПочему редактор не восстанавливает копию пресета, когда он не в фокусе?:
Как видно из кода в 4, мы очищаем и заполняем содержимое редактора, вызывая события фокуса и размытия соответственно. Но когда мы нажимаем на панель инструментов, редактор запускает событие размытия! ! Так что будут разные баги. Взяв в качестве примера редактора официального сайта Baidu, консольный ввод:
Зарегистрируйте событие щелчка для редактора, при нажатии жирной кнопки вывод консоли:
Чтобы избежать запуска события размытия при нажатии на панель инструментов, автор аннотировал все пользовательские события размытия.
6. Пользовательская кнопка и загрузка облачного изображения Qiniu
Сначала найдите массив панелей инструментов в ueeditor.config.js, добавьте строку diyimg, затем найдите массив labelMap в zh-cn.js и добавьте его в конец.'diyimg': '插入图片'
. Наконец, найдите массив btnCmds в ueeditor.all.js и добавьте строку diyimg. Используя эту строку при инициализации, на панели инструментов будет отображаться кнопка, но мы обнаружили, что она отображается так:
Это связано с тем, что ueditor по умолчанию использует значок полужирного шрифта в качестве значка пользовательской кнопки по умолчанию, поэтому, чтобы использовать значок по умолчанию для вставки изображений, нам нужно перейти в themes/default/css/ueditor.css и добавить его в Последняя линия:
/*自定义图片上传按钮 */
.edui-default .edui-toolbar .edui-for-diyimg .edui-icon {
background-position: -380px 0px;//这个位置是“插入图片”的icon,其他图标可自行调整
}
После добавления эффект отображения выглядит следующим образом:
После того, как значок отобразится нормально, вам нужно добавить соответствующее событие щелчка для значка и добавить его в ueditor.all.js:
//图片上传
UE.commands['diyimg'] = {
execCommand : function(){
const upload = async(e) => {
······//完成图片上传的代码
}
const fileInput = document.getElementById('diyimg');//获取dom上隐藏的一个input标签
fileInput.onchange = upload;
fileInput.click();//触发input标签实现文件上传
return true;
},
queryCommandState:function(){
}
};
Автор не будет здесь повторять код загрузки картинок, их много на Du Niang, коротко расскажу об идее реализации:
Сначала реализуйте кнопку, которая вставляет картинку, а затем зарегистрируйте соответствующее событие для кнопкиdiyimg
,Потомдобавить один на страницуinput file
пометить и спрятать,diyimg
Событие вызовет событие щелчка тега, и появится всплывающее окно загрузки файла, в это время оно сработает после выбора файла и нажатия на него.событие onchangeи выполните соответствующий код загрузки изображения. После успешной загрузки на сервер сервер вернет URL-адрес, соответствующий изображению.В это время получите URL-адрес и заполните соответствующий экземпляр редактора и выполните код редактора, чтобы вставить изображение:
this.execCommand('insertimage', {
src: res.data.downloadUrl,//回调传来的url
width:'60'
// height:'45'
});
7. Добавьте встроенные стили в теги, такие как img, внутри редактора.
udeditor существует по умолчаниюxss-фильтр! ! ! здесь, чтобы датьimg
Добавьте в тег style="vertical-top" в качестве примера.
Сначала найдите ueditor.config.js, ищите в нем xss, там код вокруг строки 403:
img: [src', 'alt', 'title', 'width', 'height', 'id', '_src', 'loadingclass', 'class', 'data-latex'],
добавить в массивstyle
String, затем найдите UE.commands['insertimage'] в ueeditor.all.js, найдите строку str примерно в строке 11172 и добавьте к ней встроенные стили.