1. 机关教学日志2.新增全局表格横向拖拽滚动指令3.学员模块

This commit is contained in:
2026-08-23 15:10:56 +08:00
parent df7800f001
commit d20c490c74
11 changed files with 1922 additions and 52 deletions
+96
View File
@@ -0,0 +1,96 @@
/**
* 表格横向拖拽滚动
* 隐藏表格的横向滚动条,按住鼠标左键横向拖动即可查看后面的字段。
* 通过 document 事件委托全局生效,所有 el-table 自动支持,无需逐页绑定。
*
* 手感优化:
* - 文本选中已在全局样式中禁用(user-select: none),拖拽过程不会再误选文字
* - 位移以横向为主且超过阈值才触发滚动,轻微手抖、普通点击、纵向拖拽(如行排序)不受影响
* - 光标仅在真正拖动时变为抓手,平时保持默认
* - 拖拽结束(确实发生了滚动)后屏蔽本次 click,避免误触发行点击、复选框等
*/
const DRAG_THRESHOLD = 4 // 横向位移超过该像素且以横向为主,才判定为拖动
// 在这些元素上按下鼠标不触发拖拽,保证按钮、复选框等交互不受影响
const INTERACTIVE_SELECTOR = [
'a', 'button', 'input', 'textarea', 'select', 'label',
'.el-button', '.el-checkbox', '.el-radio', '.el-switch', '.el-select',
'.el-link', '.el-dropdown', '.el-tooltip', '.el-color-picker',
'[contenteditable="true"]'
].join(',')
let wrapper = null
let startX = 0
let startY = 0
let startScrollLeft = 0
let dragging = false
function isHorizontallyScrollable(el) {
return el.scrollWidth > el.clientWidth + 1
}
function handleMouseDown(e) {
if (e.button !== 0) return
if (e.target.closest(INTERACTIVE_SELECTOR)) return
const wrap = e.target.closest('.el-table__body-wrapper')
if (!wrap || !isHorizontallyScrollable(wrap)) return
wrapper = wrap
startX = e.clientX
startY = e.clientY
startScrollLeft = wrap.scrollLeft
dragging = false
}
function handleMouseMove(e) {
if (!wrapper) return
const dx = e.clientX - startX
const dy = e.clientY - startY
if (!dragging) {
// 轻微位移视为点击,不触发滚动;位移必须以横向为主,避免与纵向拖拽(如行排序)冲突
if (Math.abs(dx) <= DRAG_THRESHOLD || Math.abs(dx) <= Math.abs(dy)) return
// 开始拖动:以当前位置为基准,避免起始跳变
dragging = true
startX = e.clientX
startY = e.clientY
startScrollLeft = wrapper.scrollLeft
wrapper.classList.add('is-dragging')
}
e.preventDefault()
wrapper.scrollLeft = startScrollLeft - (e.clientX - startX)
}
function handleMouseUp() {
if (!wrapper) return
wrapper.classList.remove('is-dragging')
if (dragging) {
// 拖拽确实发生了滚动,屏蔽本次 click,避免误触发行点击、复选框等
const blockClick = (ev) => {
ev.preventDefault()
ev.stopPropagation()
document.removeEventListener('click', blockClick, true)
}
document.addEventListener('click', blockClick, true)
}
wrapper = null
dragging = false
}
// 鼠标拖出窗口外时清理拖拽状态,防止状态残留
function handleMouseLeave() {
if (!wrapper) return
wrapper.classList.remove('is-dragging')
wrapper = null
dragging = false
}
const install = function() {
if (install.installed) return
install.installed = true
document.addEventListener('mousedown', handleMouseDown, false)
document.addEventListener('mousemove', handleMouseMove, false)
document.addEventListener('mouseup', handleMouseUp, false)
document.addEventListener('mouseleave', handleMouseLeave, false)
}
export default install