Однако в мобильных браузерах на базе Chromium (в настольных браузерах на базе Chromium такая же проблема возникает, но в меньшей степени) я испытываю то, что кажется ошибкой браузера. Вместо перетаскивания плавающего поля браузер пытается прокрутить страницу. То есть пользователь касается верхней панели плавающего блока и пытается его перетащить, но вместо этого он прокручивает страницу за плавающим блоком.
Я пробовал установить touch-action: none , это определенно улучшило ситуацию, но не решило проблему. Несколько ev.preventDefault и ev.stopPropagation, похоже, не имели никакого значения, равно как и z-index: 1000.
Ниже приведен пример кода:
Код: Выделить всё
const createfloatingbox = () => {
const floatingbox = document.createElement("div");
floatingbox.classList.add("floatingbox");
const topbar = document.createElement("div");
const floatingboxContent = document.createElement("textarea");
floatingboxContent.classList.add("floatingbox-content");
floatingboxContent.value = `some text`;
topbar.innerHTML = `
svg
—
X
`;
floatingbox.style.cssText = `
position: fixed;
top: 3rem;
left: 2rem;
z-index: 10;
border: 1px solid #ccc;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
`;
topbar.style.cssText = `
cursor: move;
user-select: none;
display: flex;
justify-content: flex-end;
width: 100%;
min-width: 5rem;
background-color: #DDD;
/*
* "touch-action" is critical for mobile Chromium,
* because it privileges touch for scrolling, dragging,
* etc., so these take priority over my code
*/
touch-action: none;
`;
// some stylesheet is changing the buttons padding... bad quick fix:
topbar
.querySelectorAll("button")
.forEach((btn) => (btn.style.padding = "0 5px"));
floatingboxContent.style.cssText = `
width: 500px;
height: 500px;
max-width: 90vw;
max-height: 90vh;
`;
floatingbox.append(topbar, floatingboxContent);
document.body.prepend(floatingbox);
// drag box around
let offset = { x: 0, y: 0 };
topbar.addEventListener("pointerdown", (e) => {
offset.x = e.clientX - floatingbox.offsetLeft;
offset.y = e.clientY - floatingbox.offsetTop;
// set pointer capture, because floatingbox is moving on top of different iframes
topbar.setPointerCapture(e.pointerId);
e.preventDefault();
e.stopImmediatePropagation();
const drag = (e) => {
floatingbox.style.left = e.clientX - offset.x + "px";
floatingbox.style.top = e.clientY - offset.y + "px";
/* these seemed to make things a little worse instead of improving:
e.preventDefault();
e.stopPropagation();
*/
};
window.addEventListener("pointermove", drag);
window.addEventListener("pointerup", () => {
window.removeEventListener("pointermove", drag);
}, { once: true });
});
};
createfloatingbox();Мои вопросы:
- Это ошибка браузера или устройства, или что-то не так в моем коде? Тестирование кода на разных мобильных телефонах, но в одном и том же браузере (Brave) дало разные результаты (иногда невозможно перетащить полосу).
- Можно ли как-нибудь избежать такого поведения, когда в браузерах на базе Chromium происходит прокрутка, и заставить мой код работать независимо от ошибок браузера/устройства?
Мобильная версия