文件还在测试中
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
/* 固定版面富文本编辑器(依赖 contenteditable + execCommand,无外部依赖)
|
||||
* - 工具栏:加粗/斜体/标题/列表/引用/链接/图片
|
||||
* - 图片:从素材库选择或上传(复用 admin/media 接口)
|
||||
* - 保存前将富文本 HTML 同步到隐藏 textarea(name=content)
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
var ed = document.getElementById('fxEditor');
|
||||
var ta = document.getElementById('fxContent');
|
||||
var form = document.getElementById('fxForm');
|
||||
if (!ed || !ta || !form) return;
|
||||
|
||||
function sync() { ta.value = ed.innerHTML; }
|
||||
ed.addEventListener('input', sync);
|
||||
form.addEventListener('submit', function () { sync(); });
|
||||
|
||||
// 工具栏命令
|
||||
document.querySelectorAll('.fx-toolbar button[data-cmd]').forEach(function (b) {
|
||||
b.addEventListener('mousedown', function (e) { e.preventDefault(); }); // 防止编辑器失焦
|
||||
b.addEventListener('click', function () {
|
||||
var cmd = b.getAttribute('data-cmd');
|
||||
var val = b.getAttribute('data-val') || null;
|
||||
ed.focus();
|
||||
document.execCommand(cmd, false, val);
|
||||
sync();
|
||||
});
|
||||
});
|
||||
|
||||
// 链接
|
||||
var linkBtn = document.getElementById('fxLink');
|
||||
if (linkBtn) linkBtn.addEventListener('click', function () {
|
||||
var url = prompt('链接地址(如 /contact 或 https://...)');
|
||||
if (url) { ed.focus(); document.execCommand('createLink', false, url); sync(); }
|
||||
});
|
||||
|
||||
// 图片弹层
|
||||
var modal = document.getElementById('fxModal');
|
||||
var imgBtn = document.getElementById('fxImg');
|
||||
var closeBtn = document.getElementById('fxModalClose');
|
||||
if (imgBtn) imgBtn.addEventListener('click', openModal);
|
||||
if (closeBtn) closeBtn.addEventListener('click', function () { modal.hidden = true; });
|
||||
if (modal) modal.addEventListener('click', function (e) { if (e.target === modal) modal.hidden = true; });
|
||||
|
||||
function insertImg(url) {
|
||||
ed.focus();
|
||||
document.execCommand('insertHTML', false,
|
||||
'<img src="' + url + '" alt="" style="max-width:100%;border-radius:8px;display:block;margin:8px 0">');
|
||||
sync();
|
||||
modal.hidden = true;
|
||||
}
|
||||
|
||||
function openModal() {
|
||||
modal.hidden = false;
|
||||
var lib = document.getElementById('fxLib');
|
||||
lib.innerHTML = '<span style="font-size:12px;color:#94a3b8">加载中…</span>';
|
||||
fetch(window.__PB_MEDIA__)
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (j) {
|
||||
lib.innerHTML = '';
|
||||
var items = (j && j.items) || [];
|
||||
if (!items.length) { lib.innerHTML = '<span style="font-size:12px;color:#94a3b8">暂无素材,先上传</span>'; return; }
|
||||
items.forEach(function (it) {
|
||||
var img = document.createElement('img');
|
||||
img.src = it.url; img.title = it.name;
|
||||
img.addEventListener('click', function () { insertImg(it.url); });
|
||||
lib.appendChild(img);
|
||||
});
|
||||
})
|
||||
.catch(function () { lib.innerHTML = '<span style="font-size:12px;color:#dc2626">加载失败</span>'; });
|
||||
}
|
||||
|
||||
// 上传图片
|
||||
var up = document.getElementById('fxUp');
|
||||
if (up) up.addEventListener('change', function () {
|
||||
var file = this.files && this.files[0];
|
||||
if (!file) return;
|
||||
var fd = new FormData();
|
||||
fd.append('file', file);
|
||||
fetch(window.__PB_UPLOAD__, { method: 'POST', body: fd, headers: { 'X-CSRF-TOKEN': window.__PB_CSRF__ } })
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (j) {
|
||||
if (j && j.ok) { insertImg(j.url); openModal(); }
|
||||
else alert((j && j.msg) || '上传失败');
|
||||
})
|
||||
.catch(function () { alert('上传失败,请重试'); });
|
||||
this.value = '';
|
||||
});
|
||||
})();
|
||||
Reference in New Issue
Block a user