Почему условие значений элемента getBoundingClientRect () не работает должным образом? - PullRequest
2 голосов
/ 20 июня 2020

У меня есть .square элемент, когда я перемещаю мышь, он должен перемещаться с помощью мыши. Почти все хорошо, когда я двигаю мышью нормально, но когда я быстро перемещаю мышь вправо и в нижнюю часть, поле .square переходит вниз или вправо и образует полосу прокрутки.

Как сделать мой код лучше, чем сейчас? ИЛИ Как исправить проблему?

[ПРИМЕЧАНИЕ]: Переход должен иметь

let square = document.querySelector(".square");

document.addEventListener("mousemove", function (e) {
  if (square !== null) {
    let x = e.pageX;
    let y = e.pageY;

    square.setAttribute("style", `top: ${y}px; left: ${x}px`);

    let getBottom = square.getBoundingClientRect().bottom;
    let getRight = square.getBoundingClientRect().right;

    if (getBottom > window.innerHeight) {
      square.setAttribute("style", `bottom: 0; left: ${x}px`);
    }

    if (getRight > window.innerWidth) {
      square.setAttribute("style", `top: ${y}px; right: 0`);
    }

    if (getRight > window.innerWidth && getBottom > window.innerHeight) {
      square.setAttribute("style", `bottom: 0; right: 0`);
    }
  }
});
*,
*::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: .01s ease-in-out;
}
<div class="square"></div>

1 Ответ

1 голос
/ 20 июня 2020

Проблема вызвана определением перехода в позиции квадратного элемента в CSS в сочетании с установкой позиции квадрата перед чтением его текущей позиции:

  1. Установка позиции сразу к позиции перемещения мыши:

     square.setAttribute("style", `top: ${y}px; left: ${x}px`);
    

    может перемещать квадрат из области просмотра и создавать полосы прокрутки, если длина курсора мыши меньше длины стороны квадрата от нижнего или правого края окна браузера .

  2. Чтение следующего положения квадрата:

    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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...