@Danila232

Вопрос по JS-задаче(перемещение элемента)?

Задача простая: есть поле и в нём мяч. Кликаешь куда-то по полю - в место клика перемещается элемент(мяч тобишь)
let field = document.querySelector('#field')
let ball = document.querySelector('#ball')

field.addEventListener('click', function(e){
  ball.style.left = e.clientX - field.offsetLeft - ball.width / 2 + 'px';  // Тут всё праивильно
  ball.style.top = e.clientY - field.offsetTop - ball.height / 2 + 'px';

// ball.style.left = e.clientX - ball.width / 2 + 'px'
// ball.style.top = e.clientY - ball.height / 2 + 'px'  А тут при клике на поле - изобр. улетает куда-то вниз - за пределы поля
})


Не пойму: вот я сначала написал(думал так правильно будет):
ball.style.left = e.clientX - ball.width / 2 + 'px'
ball.style.top = e.clientY - ball.height / 2 + 'px'

По идее, это значит: отступ слева для элемента(мяча) = Координаты клика по X - половинка длины мяча, в px

Вроде бы всё логично, но если кликнуть по Полю - то вместо перемещения в место клика Мяч улетит куда-то вниз за пределы Поля. Не пойму почему
А если добавить - field.offsetLeft, то всё заработает как надо.

А .offsetLeft - это свойство, которое показывает смещение элемента относительно родителя с position(relative, absolute, fixed). А у Поля у меня родитель - body. И у него нет такого position.

В общем не пойму что тут делают field.offsetLeft/field.offsetTop и почему без них не работает, объясните пожалуйста.
  • Вопрос задан
  • 122 просмотра
Решения вопроса 1
Kentavr16
@Kentavr16
long cold winter
Цитируя MDN -
Абсолютно позиционируемый элемент — это элемент, чьё вычисленное значение position является absolute или fixed. top, right, bottom и left (en-US) задают смещения от краёв содержащего блок элемента. (Содержащий блок является предком, относительно которого расположен элемент.)
Объяснение твоего вопроса в последнем предложении. Более наглядно попытался объяснить здесь.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@UthvfyV
css
#field {
width: 200px;
height: 150px;
border: 10px solid black;
background-color: #51DB42;
position: relative;
overflow: hidden;
cursor: pointer;
}
#ball {
position: absolute;
left: 0;
top: 0;
width: 40px;
height: 40px;
transition: all 1s;
}

html
<div id="field"><img src="https://freesvg.org/img/soccer_ball2.png" id="ball" style="left: 149px; top: 65px;"></div>

script
field.onclick = function(event) {
// координаты поля
let fieldCoords = this.getBoundingClientRect();
// мяч имеет абсолютное значение, поле - относительное (relative) таким образом координаты мяча рассчитываются относительно внутреннего верхнего левого угла поля
let ballCoords = {top: event.clientY - fieldCoords.top - field.clientTop - ball.clientHeight / 2, left: event.clientX - fieldCoords.left - field.clientLeft - ball.clientWidth / 2 };
// запрещаем пересекать верхнюю границу поля
if (ballCoords.top < 0) ballCoords.top = 0;
// запрещаем пересекать левую границу поля
if (ballCoords.left < 0) ballCoords.left = 0;
// запрещаем пересекать правую границу поля
if (ballCoords.left + ball.clientWidth > field.clientWidth) {ballCoords.left = field.clientWidth - ball.clientWidth;}
// запрещаем пересекать нижнюю границу поля
if (ballCoords.top + ball.clientHeight > field.clientHeight) {ballCoords.top = field.clientHeight - ball.clientHeight;}
ball.style.left = ballCoords.left + 'px';
ball.style.top = ballCoords.top + 'px';}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы