I have a data grid component that supports arbitrary cell range selection similar to excel/google sheets. I determine the start cell by a mousedown and the end node by recording the last cell that gets mouseenter (not mouseup because the user could mouseup outside of the grid). I am currently adding an enhancement so that when the user drag selecting beyond the current viewport of the grid, it would automatically scroll both horizontally and vertically. My idea was to leverage native text selection, because when you selecting text the browser by default would scroll the container. But then I found out it works in Chrome but not in Firefox.
Here is a simplified example: https://jsfiddle.net/n6gm5ekr/43/. Run it in both Chrome and Firefox, should be easy to spot the difference.
body {
padding: 20px;
}
.mouseTarget {
box-sizing: border-box;
width: 70px;
border: 2px solid grey;
display: inline-block;
cursor: default;
padding: 2px;
margin: 2px;
box-sizing: border-box;
overflow: hidden;
/* user-select: none; */
}
.mouseTarget span::selection {
color: black;
background-color: yellow;
}
.table {
width: 500px;
height: 200px;
overflow: auto;
border: 2px solid blue;
}
const numRows = 130;
const numCols = 10;
const table = document.createElement('div');
table.classList.add('table');
for (let i = 0; i < numRows; i++) {
const row = document.createElement('div');
for (let j = 0; j < numCols; j++) {
const cell = document.createElement('div');
const span = document.createElement('span');
cell.append(span);
span.textContent = `Cell ${i}-${j}`;
cell.classList.add("mouseTarget");
cell.draggable=false;
row.append(cell);
row.style.width = `${numCols * 74}px`;
}
table.append(row);
}
document.body.append(table);
let downEventCount = 0;
let upEventCount = 0;
let enterEventCount = 0;
let leaveEventCount = 0;
const mouseTargets = document.querySelectorAll(".mouseTarget");
for (let mouseTarget of mouseTargets) {
mouseTarget.addEventListener("mouseenter", (e) => {
mouseTarget.style.border = "2px dotted orange";
mouseTarget.style.backgroundColor = "orange";
mouseTarget.classList.add('hover');
enterEventCount++;
console.log(`This is mouseenter event ${enterEventCount}.`);
});
mouseTarget.addEventListener("mouseleave", (e) => {
mouseTarget.style.border = "2px solid grey";
mouseTarget.style.backgroundColor = "transparent";
mouseTarget.classList.add('hover');
leaveEventCount++;
console.log(`This is mouseleave event ${leaveEventCount}.`);
});
mouseTarget.addEventListener("mousedown", (e) => {
mouseTarget.style.border = "2px solid red";
downEventCount++;
console.log(`This is mousedown event ${downEventCount}.`);
});
mouseTarget.addEventListener("mouseup", (e) => {
mouseTarget.style.border = "2px solid green";
upEventCount++;
console.log(`This is mouseup event ${upEventCount}.`);
});
}
I couldn't find an official documentation confirming this behavior as by design, that Firefox would not emit any mouseenter/mouseleave/mouseover/mousemove/etc. events when I drag selecting across text in multiple divs.
Looking for suggestions for workarounds, as well as pointers to the rationale behind the behavior difference between Chrome and Firefox.
Thanks!