- 弹窗改为 flex 三段式:头部固定 / 内容滚动 / 底栏固定 保存按钮常驻底部可见,外层 overflow:hidden 保住 20px 圆角 - 滚动条收进 modal-body,细圆角样式,不再贯穿整个弹窗 - 放大拆两级:弹窗头部 ⤢ 放大整个弹窗(加宽到 880px); 编辑器工具栏 ⤢ 仅编辑器最大化(980px x 92vh 浮层) - Esc 优先还原编辑器最大化,再按一次才关闭弹窗
This commit is contained in:
+55
-12
@@ -201,9 +201,16 @@
|
||||
}
|
||||
.rte-body:empty::before { content: attr(data-ph); color: var(--text-muted); pointer-events: none; }
|
||||
|
||||
/* 放大书写面板:编辑弹窗右上角按钮切换 */
|
||||
/* 弹窗级放大:弹窗头部 ⤢ 按钮切换,加宽整个弹窗 */
|
||||
.modal.lg { max-width: 880px; }
|
||||
.modal.lg .rte-body { min-height: 48vh; max-height: none; }
|
||||
/* 编辑器级最大化:工具栏 ⤢ 按钮切换,编辑器浮层铺满视口 */
|
||||
.rte.max {
|
||||
position: fixed; z-index: 80; top: 4vh; left: 50%; transform: translateX(-50%);
|
||||
width: min(980px, 94vw); height: 92vh; display: flex; flex-direction: column;
|
||||
background: #fff; border-color: transparent; border-radius: 16px;
|
||||
box-shadow: 0 24px 64px rgba(15, 23, 42, .4);
|
||||
}
|
||||
.rte.max .rte-body { flex: 1; min-height: 0; max-height: none; padding: 18px 22px; font-size: 15px; }
|
||||
|
||||
/* 富文本排版(编辑器与卡片展开共用 .fmt) */
|
||||
.fmt h2 { font-size: 17px; font-weight: 700; margin: 10px 0 5px; letter-spacing: -.2px; }
|
||||
@@ -344,16 +351,31 @@
|
||||
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
|
||||
.modal {
|
||||
width: 100%; max-width: 480px; background: #fff; border-radius: 20px;
|
||||
box-shadow: var(--shadow-lg); padding: 24px; margin: auto;
|
||||
animation: popIn .26s cubic-bezier(.16, 1, .3, 1); max-height: 92vh; overflow-y: auto;
|
||||
box-shadow: var(--shadow-lg); margin: auto; padding: 0;
|
||||
animation: popIn .26s cubic-bezier(.16, 1, .3, 1);
|
||||
max-height: 88vh; display: flex; flex-direction: column; overflow: hidden;
|
||||
}
|
||||
@keyframes popIn { from { opacity: 0; transform: scale(.94) translateY(12px); } to { opacity: 1; transform: scale(1) translateY(0); } }
|
||||
.modal h2 { font-size: 18px; font-weight: 700; margin-bottom: 18px; }
|
||||
/* 三段式布局:头部固定 / 内容滚动 / 底栏固定,外层 overflow:hidden 保住圆角 */
|
||||
.modal-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 20px 24px 14px; flex-shrink: 0; }
|
||||
.modal-head h2 { font-size: 18px; font-weight: 700; margin: 0; }
|
||||
.modal-body { padding: 2px 24px 6px; overflow-y: auto; flex: 1; min-height: 0; }
|
||||
.modal-body::-webkit-scrollbar, .rte-body::-webkit-scrollbar { width: 6px; }
|
||||
.modal-body::-webkit-scrollbar-thumb, .rte-body::-webkit-scrollbar-thumb { background: #d5dbea; border-radius: 99px; }
|
||||
.modal-body::-webkit-scrollbar-thumb:hover, .rte-body::-webkit-scrollbar-thumb:hover { background: #b6c0d8; }
|
||||
.modal-body::-webkit-scrollbar-track, .rte-body::-webkit-scrollbar-track { background: transparent; }
|
||||
.modal-foot { display: flex; gap: 10px; justify-content: flex-end; padding: 14px 24px; flex-shrink: 0; border-top: 1px solid var(--line); background: #fff; }
|
||||
.mzoom {
|
||||
width: 30px; height: 30px; border: none; background: #f1f4fa; border-radius: 8px;
|
||||
color: var(--text-sub); cursor: pointer; font-size: 14px; flex-shrink: 0;
|
||||
display: inline-flex; align-items: center; justify-content: center;
|
||||
transition: background .14s, color .14s;
|
||||
}
|
||||
.mzoom:hover { background: rgba(99, 102, 241, .13); color: var(--indigo-dark); }
|
||||
.field { margin-bottom: 15px; }
|
||||
.field label { display: block; font-size: 13px; font-weight: 600; color: var(--text-sub); margin-bottom: 7px; }
|
||||
.field textarea { resize: vertical; min-height: 76px; }
|
||||
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
|
||||
.modal-foot { display: flex; gap: 10px; justify-content: flex-end; margin-top: 22px; }
|
||||
|
||||
/* ===== 危险操作确认弹窗(替代浏览器原生 confirm) ===== */
|
||||
.confirm { max-width: 372px; padding: 26px 24px 20px; text-align: center; }
|
||||
@@ -905,10 +927,9 @@
|
||||
var btn = e.target.closest('.rte-btn')
|
||||
if (!btn) return
|
||||
if (btn.id === 'rteExpand') {
|
||||
var modal = root.closest('.modal')
|
||||
var lg = modal.classList.toggle('lg')
|
||||
btn.innerHTML = lg ? '⤡ 收起' : '⤢ 放大'
|
||||
btn.title = lg ? '恢复默认面板' : '放大书写面板'
|
||||
var maxed = root.classList.toggle('max')
|
||||
btn.innerHTML = maxed ? '⤡ 还原' : '⤢ 放大'
|
||||
btn.title = maxed ? '还原编辑器' : '编辑器最大化'
|
||||
body.focus()
|
||||
return
|
||||
}
|
||||
@@ -1176,7 +1197,9 @@
|
||||
var isNew = !item
|
||||
item = item || { priority: 2, dueDate: '', remark: '', title: '' }
|
||||
var html = '<div class="mask" id="mask"><div class="modal">'
|
||||
+ '<h2>' + (isNew ? '新建待办' : '编辑待办') + '</h2>'
|
||||
+ '<div class="modal-head"><h2>' + (isNew ? '新建待办' : '编辑待办') + '</h2>'
|
||||
+ '<button type="button" class="mzoom" id="mZoom" title="放大弹窗">⤢</button></div>'
|
||||
+ '<div class="modal-body">'
|
||||
+ '<div class="field"><label>标题</label>'
|
||||
+ '<input type="text" id="mTitle" maxlength="200" value="' + esc(item.title) + '" placeholder="要做什么?"></div>'
|
||||
+ '<div class="field-row">'
|
||||
@@ -1187,6 +1210,7 @@
|
||||
+ '<div class="rte">' + RTE_BAR
|
||||
+ '<div class="rte-body fmt" id="mRemark" contenteditable="true" data-ph="补充说明,支持加粗 / 列表 / 待办项 / 代码块…"></div>'
|
||||
+ '</div></div>'
|
||||
+ '</div>'
|
||||
+ '<div class="modal-foot">'
|
||||
+ '<button class="btn btn-ghost" id="mCancel">取消</button>'
|
||||
+ '<button class="btn btn-primary" id="mSave">保存</button>'
|
||||
@@ -1199,11 +1223,30 @@
|
||||
rteBody.innerHTML = sanitizeHtml(item.remark || '')
|
||||
initEditor(rteBody.closest('.rte'))
|
||||
var mask = $('mask')
|
||||
var modal = mask.querySelector('.modal')
|
||||
var mTitle = $('mTitle')
|
||||
setTimeout(function () { mTitle.focus() }, 60)
|
||||
|
||||
// 弹窗头部 ⤢:放大整个弹窗(加宽)
|
||||
$('mZoom').addEventListener('click', function () {
|
||||
var lg = modal.classList.toggle('lg')
|
||||
this.innerHTML = lg ? '⤡' : '⤢'
|
||||
this.title = lg ? '还原弹窗' : '放大弹窗'
|
||||
})
|
||||
|
||||
function close() { elModalRoot.innerHTML = '' }
|
||||
function onKey(e) { if (e.key === 'Escape') close() }
|
||||
function onKey(e) {
|
||||
if (e.key !== 'Escape') return
|
||||
// 编辑器最大化时 Esc 优先还原编辑器,再按一次才关弹窗
|
||||
var maxed = modal.querySelector('.rte.max')
|
||||
if (maxed) {
|
||||
maxed.classList.remove('max')
|
||||
var expBtn = maxed.querySelector('#rteExpand')
|
||||
if (expBtn) { expBtn.innerHTML = '⤢ 放大'; expBtn.title = '编辑器最大化' }
|
||||
return
|
||||
}
|
||||
close()
|
||||
}
|
||||
|
||||
document.addEventListener('keydown', onKey)
|
||||
mask.addEventListener('click', function (e) { if (e.target === mask) { close(); document.removeEventListener('keydown', onKey) } })
|
||||
|
||||
Reference in New Issue
Block a user