Проблема вызвана определением перехода в позиции квадратного элемента в CSS в сочетании с установкой позиции квадрата перед чтением его текущей позиции:
Установка позиции сразу к позиции перемещения мыши:
square.setAttribute("style", `top: ${y}px; left: ${x}px`);
может перемещать квадрат из области просмотра и создавать полосы прокрутки, если длина курсора мыши меньше длины стороны квадрата от нижнего или правого края окна браузера .
Чтение следующего положения квадрата:
let getBottom = square.getBoundingClientRect().bottom;
let getRight = square.getBoundingClientRect().right;
возвращает обновленное положение квадрата, если перехода нет, но с переходом возвращается туда, где квадрат сейчас, до начала перехода. Поскольку квадрат еще не находится за окном, ни один из условных операторов, использующих его старую позицию, не обнаруживает, что он окажется за пределами окна.
Самое простое решение - удалить CSS переход - сохранение значения 0,01 секунды меньше, чем время обновления монитора sh и не особенно полезно.
Получение положения квадрата один раз , перед обновлением его положения - другое решение.
В любом случае может быть более плавным обновить положение квадрата не более одного раза с положением, в которое он переходит.
В этом коде, используемом для поиска ответа, Свойства clientWidth
и clientHeight
элемента html
представляют собой особый случай этих свойств и отражают размер порта просмотра, за исключением полос прокрутки. Время перехода установлено на 0,05 секунды, чтобы избежать стробоскопии c эффект от обновления экрана sh:
let square = document.querySelector(".square");
const HTML = document.firstElementChild;
document.addEventListener("mousemove", function (e) {
if (square !== null) {
let domRect = square.getBoundingClientRect()
let x = e.pageX;
let y = e.pageY;
x = Math.min( HTML.clientWidth - domRect.width, x);
y = Math.min( HTML.clientHeight - domRect.height, y);
square.style.top = `${y}px`;
square.style.left = `${x}px`;
//square.setAttribute("style", `top: ${y}px; left: ${x}px`);
}
});
*,
*::before,
*::after{
box-sizing: border-box;
}
body{
margin: 0;
border: 1px solid blue;
}
.square {
position: absolute;
height: 50px;
width: 50px;
border: 5px solid red;
transition: .05s ease-in-out;
}
<div class="square"></div>