问题描述:默认情况下 vue-grid-layout
移动卡片到页面底部时页面滚动条并不会跟随卡片滚动。
问题解决:
在 grid-item
中的move
事件中,获取到当前移动的元素,并使用scrollIntoView
方法来实现滚动条跟随。
代码如下:
const moveEvent = (i: any) => {
let cIdx = layout.value.findIndex(item => item.i === i)
let el = gridItemRefs.value[cIdx].$el
setTimeout(() => {
el?.scrollIntoView({ behavior: "smooth", block: "end" })
}, 300)
}
此时优化效果如下:
- 但是上面优化还有一个小问题,将卡片右移可以无效无限右移。
所以根据元素的lastX
来控制一下:
const moveEvent = (i: any) => {
let cIdx = layout.value.findIndex(item => item.i === i)
let el = gridItemRefs.value[cIdx].$el
setTimeout(() => {
console.log(gridItemRefs.value[cIdx].lastX, '===gridItemRefs.value[cIdx]');
if (gridItemRefs.value[cIdx].lastX < 900) {
el?.scrollIntoView({ behavior: "smooth", block: "end" })
}
}, 300)
}
同理,如果是从外层拖到元素进来,也可以使用 scrollIntoView
来设置滚动条跟随。
代码如下:
const colNum = 12
const drag = (item: any) => {
let parentRect = document.getElementById('content')?.getBoundingClientRect()!;
let mouseInGrid = false;
if (((mouseXY.x > parentRect.left) && (mouseXY.x < parentRect.right)) && ((mouseXY.y > parentRect.top) && (mouseXY.y < parentRect.bottom))) {
mouseInGrid = true;
}
if (mouseInGrid === true && (layout.value.findIndex(item => item.i === 'drop')) === -1) {
layout.value.push({
x: (layout.value.length * 2) % (colNum || 12),
y: layout.value.length + (colNum || 12), // puts it at the bottom
w: item.w,
h: item.h,
i: 'drop',
});
}
let index = layout.value.findIndex(item => item.i === 'drop');
if (index !== -1) {
try {
gridItemRefs.value[layout.value.length - 1].$refs.item.style.display = "none";
} catch {
}
let el = gridItemRefs.value[index];
if (el) {
setTimeout(() => {
el.$el?.scrollIntoView({ behavior: "smooth", block: "nearest" })
}, 300)
el.dragging = { "top": mouseXY.y - parentRect.top, "left": mouseXY.x - parentRect.left };
let new_pos = el.calcXY(mouseXY.y - parentRect.top, mouseXY.x - parentRect.left);
if (mouseInGrid === true) {
gridlayout.value.dragEvent('dragstart', 'drop', new_pos.x || 0, new_pos.y || 0, item.h, item.w);
// dragEvent('dragstart', 'drop', new_pos.x || 0, new_pos.y || 0, defaultH, defaultW);
DragPos.i = String(new Date().getTime());
DragPos.x = layout.value[index].x;
DragPos.y = layout.value[index].y;
DragPos.w = layout.value[index].w;
DragPos.h = layout.value[index].h;
}
if (mouseInGrid === false) {
gridlayout.value.dragEvent('dragend', 'drop', new_pos.x || 0, new_pos.y || 0, item.h, item.w);
// dragEvent('dragend', 'drop', new_pos.x || 0, new_pos.y || 0, defaultH, defaultW);
layout.value = layout.value.filter(obj => obj.i !== 'drop');
}
}
}
}
const dragend = () => {
let parentRect = document.getElementById('content')?.getBoundingClientRect()!;
let mouseInGrid = false;
if (((mouseXY.x > parentRect.left) && (mouseXY.x < parentRect.right)) && ((mouseXY.y > parentRect.top) && (mouseXY.y < parentRect.bottom))) {
mouseInGrid = true;
}
if (mouseInGrid === true) {
gridlayout.value.dragEvent('dragend', 'drop', DragPos.x, DragPos.y, DragPos.h, DragPos.w);
let delIndex = layout.value.findIndex(item => item.i === 'drop')
layout.value.splice(delIndex, 1)
// UNCOMMENT below if you want to add a grid-item
layout.value.push({
x: DragPos.x,
y: DragPos.y,
w: DragPos.w,
h: DragPos.h,
i: DragPos.i,
});
gridlayout.value.dragEvent('dragend', DragPos.i, DragPos.x, DragPos.y, DragPos.h, DragPos.w);
try {
gridItemRefs.value[layout.value.length - 1].$refs.item.style.display = "block";
} catch {
}
}
}