forked from liweijie/education
1. 机关教学日志2.新增全局表格横向拖拽滚动指令3.学员模块
This commit is contained in:
@@ -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
|
||||
Reference in New Issue
Block a user