Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 04.10.2019, 16:03
Аватар для Spirtikys
Аспирант
Отправить личное сообщение для Spirtikys Посмотреть профиль Найти все сообщения от Spirtikys
 
Регистрация: 30.12.2015
Сообщений: 49

Touch события
Доброго времени суток.
Суть в том, что у нас есть возможность отлавливать touch события, но в то же время, не могу понять, как просто можно понять, что палец, ушел с конкретного дом элемента.
Сначала на нем срабатывает touch start, при видении пальца внутри элемента отрабатывает touch move, как только я выхожу из элемента, touch move продолжает работать (проверенно на последнем Chrome), touch end возникает в момент как палец был поднят с экрана.
Если простая возможность, как с движением мыши (mouseover, mouseout)?
Ответить с цитированием
  #2 (permalink)  
Старый 05.10.2019, 13:45
Профессор
Отправить личное сообщение для Nexus Посмотреть профиль Найти все сообщения от Nexus
 
Регистрация: 04.12.2012
Сообщений: 3,791

У TouchEvent's есть свойство touches, которое хранит список Touch'ей.
Каждый Touch хранит координаты и элемент, на котором произошло событие.
<div class="outside">
  <div class="inside"></div>
</div>
<style>.inside {
  max-width:30%;
  min-height: 30vh;
  margin: auto;
  background-color: gray;
}</style>
<script>(() => {
  const inside = document.querySelector('.inside');
  const styles = getComputedStyle(inside, null);
  const coordinates = {
    x: [
      inside.offsetLeft, 
      inside.offsetLeft + parseFloat(styles.width.replace('px', ''))
    ],
    y: [
      inside.offsetTop, 
      inside.offsetTop + parseFloat(styles.height.replace('px', ''))
    ]
  };

  document.addEventListener('touchmove', function (event) {
    const hovered = [].some.call(event.touches, touch => {
      const xInside = touch.clientX >= coordinates.x[0] && touch.clientX <= coordinates.x[1];
      const yInside = touch.clientY >= coordinates.y[0] && touch.clientY <= coordinates.y[1];

      return xInside && yInside;
    });

    inside.style.backgroundColor = hovered ? 'green' : 'red';
  });
})()</script>
Ответить с цитированием
  #3 (permalink)  
Старый 05.10.2019, 16:26
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,105

Nexus,
что-то у меня координаты не совпадают.
предложу такой вариант ...

<!DOCTYPE html>

<html>
<head>
  <title>Untitled</title>
  <meta charset="utf-8">

</head>

<body>
<div class="outside">
  <div class="inside"></div>
</div>
<style>
html{
    height: 1800px;
    width: 1800px;
}
.outside {
    padding: 8px;
    background-color: #FFD700;
}

.inside {
  max-width:30%;
  min-height: 30vh;
  margin: auto;
  background-color: gray;
}</style>
<script>
(() => {
  const inside = document.querySelector('.inside');
  document.addEventListener('touchmove', function (event) {
  const box = inside.getBoundingClientRect();
  const coordinates = {
    x: [
      box.left,
      box.left + box.width
    ],
    y: [
      box.top,
      box.top + box.height
    ]
  };
  const hovered = [...event.touches].some(touch => {  console.log(touch)
  const xInside = touch.clientX >= coordinates.x[0] && touch.clientX <= coordinates.x[1];
  const yInside = touch.clientY >= coordinates.y[0] && touch.clientY <= coordinates.y[1];
      return xInside && yInside;
  });

    inside.style.backgroundColor = hovered ? 'green' : 'red';
  });
})()</script>

</body>
</html>
Ответить с цитированием
  #4 (permalink)  
Старый 06.10.2019, 20:51
Аватар для Malleys
Профессор
Отправить личное сообщение для Malleys Посмотреть профиль Найти все сообщения от Malleys
 
Регистрация: 20.12.2009
Сообщений: 1,714

Сообщение от Spirtikys
Есть ли... возможность, как с движением мыши (mouseover, mouseout)?
Вы можете описáть, как должны обрабатываться события mouseover и mouseout. Затем добавить обобщённый код, который переводит прикосновения к этим событиям.

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<style>

html {
	background: black;
	color: white;
}

section#images {
	display: grid;
	grid-template: repeat(3, 200px) / repeat(3, 200px);
}

@media(max-width: 620px) {
	section#images {
		grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
		grid-auto-rows: 200px;
	}
}

section#images > img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	filter: grayscale(1) opacity(0.5);
	transition: 300ms filter;
}

section#images > img.focus {
	filter: none;
}

	</style>
</head>
<body>
	<section id="images">
		<img src="https://picsum.photos/id/237/400/400">
		<img src="https://picsum.photos/id/238/400/400">
		<img src="https://picsum.photos/id/239/400/400">
		<img src="https://picsum.photos/id/247/400/400">
		<img src="https://picsum.photos/id/248/400/400">
		<img src="https://picsum.photos/id/249/400/400">
		<img src="https://picsum.photos/id/257/400/400">
		<img src="https://picsum.photos/id/258/400/400">
		<img src="https://picsum.photos/id/259/400/400">
	</section>
	<button onclick="
		this.textContent = document.fullscreenElement ?
			'↗️ View Fullscreen' : '↙️ Exit Fullscreen';
		document.fullscreenElement ?
			document.exitFullscreen() :
			document.documentElement.requestFullscreen();
	">↗️ View Fullscreen</button>
	<script>

addEventListener("mouseover", function(event) {
	event.target.classList.add("focus");
});

addEventListener("mouseout", function(event) {
	event.target.classList.remove("focus");
});

/* dispatch `mouseover` and `mouseout` events for touch device */
{
function dispatchMouseEventAtTarget(type, node, eventInitDict = {}) {
	return dispatchEvent(Object.defineProperties(new MouseEvent(type, eventInitDict), {
		target: { value: node }
	}));
}
const map = new Map();
for(const type of ["start", "move", "end", "cancel"])
	addEventListener("touch" + type, function(event) {
		if(event instanceof TouchEvent) {
			for(const touch of event.changedTouches) {
				if(event.type === "touchstart") {
					map.set(touch.identifier, touch.target);
					dispatchMouseEventAtTarget("mouseover", event.target);
				} else if(event.type === "touchmove") {
					const currentTarget = map.get(touch.identifier);
					const x = touch.pageX - window.pageXOffset;
					const y = touch.pageY - window.pageYOffset;
					const target = document.elementFromPoint(x, y);

					if(currentTarget !== target) {
						if(currentTarget) dispatchMouseEventAtTarget("mouseout", currentTarget);
						if(target) dispatchMouseEventAtTarget("mouseover", target);
						map.set(touch.identifier, target);
					}
				} else {
					const currentTarget = map.get(touch.identifier);
					if(currentTarget) setTimeout(dispatchMouseEventAtTarget, 40, "mouseout", currentTarget);
					map.delete(touch.identifier);
				}
			}
		}
	});
}
	</script>
</body>
</html>

Последний раз редактировалось Malleys, 06.10.2019 в 22:40.
Ответить с цитированием
  #5 (permalink)  
Старый 06.10.2019, 21:23
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,105

Сообщение от Malleys
Вы можете описать как должны обрабатываться события mouseover и mouseout.
а можно пример или это есть уже в коде?
Ответить с цитированием
  #6 (permalink)  
Старый 06.10.2019, 21:45
Аватар для Malleys
Профессор
Отправить личное сообщение для Malleys Посмотреть профиль Найти все сообщения от Malleys
 
Регистрация: 20.12.2009
Сообщений: 1,714

Сообщение от рони
а можно пример или это есть уже в коде?
Да, в коде идет пример, в котором добавляется класс focus при наведении мыши, и удаляется при отведении мыши. Смотрите стр. 53-59 в примере выше.

На стр. 61-95 находится код, который переводит события прикосновения в события mouseover и mouseout.

Сообщение от рони
а можно пример или это есть уже в коде?
Это так непонятно, если пропустить запятую! Наверное, лучше так: Вы можете описáть, как должны обрабатываться события mouseover и mouseout. Затем...
Ответить с цитированием
  #7 (permalink)  
Старый 06.10.2019, 22:01
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,105

Сообщение от Malleys
Это так непонятно
у меня лезет null в строке 88, идёт ошибка Cannot read property 'classList' of null.
Ответить с цитированием
  #8 (permalink)  
Старый 06.10.2019, 22:19
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,105

Malleys,
хром, консоль, режим эмуляции, увожу курсор с картинки за пределы "устройства". возникает ошибка.
Ответить с цитированием
  #9 (permalink)  
Старый 06.10.2019, 22:40
Аватар для Malleys
Профессор
Отправить личное сообщение для Malleys Посмотреть профиль Найти все сообщения от Malleys
 
Регистрация: 20.12.2009
Сообщений: 1,714

Сообщение от рони
хром, консоль, режим эмуляции, увожу курсор с картинки за пределы "устройства".
А такое, а то я думал, что это вообще не работает! Тогда добавил ещё проверку на наличие элементов!
Ответить с цитированием
  #10 (permalink)  
Старый 07.10.2019, 14:05
Аватар для Spirtikys
Аспирант
Отправить личное сообщение для Spirtikys Посмотреть профиль Найти все сообщения от Spirtikys
 
Регистрация: 30.12.2015
Сообщений: 49

Мой нынешний вариант реализации через elementFromPoint, при touch move я проверяю не вышел ли я с элемента.
На данный момент, подводных камней не обнаружил. По уходу с элемента убиваю touch move и жду снова touch start.

зы Очень похож на то, что было предложено Nexus и рони, но без ручного счета.
зыы Надеялся, что, все таки, есть более простые вариант, как с мышью, но, оказалось, что нет - это расстроило.

Последний раз редактировалось Spirtikys, 07.10.2019 в 15:53.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
свойства объекта события Morr123 Элементы интерфейса 3 10.08.2016 06:36
События Touch MadGest Firefox/Mozilla 0 08.04.2015 17:42
Обработка события внутри события grifangel Общие вопросы Javascript 6 04.09.2014 12:34
Touch события FunBek Мобильный JavaScript 5 16.12.2013 14:12
Дебаг js, или как найти обработчик события для тега jimm88 Events/DOM/Window 1 18.04.2012 15:11