Javascript.RU

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

Клик сквозь элемент для разных кнопок мыши
Здравствуйте. Есть простая на первый взгляд задача, которая легко решается на системных языках программирования, но которая поставила меня в тупик при попытке реализации её на Web:

На странице располагается 1 элемент - div.box, к примеру.
Клик левой кнопкой мыши должен проходить сквозь этот элемент. Для клика элемента не должно существовать вообще, а срабатывать он должен на родителе (document.body).
Клик правой кнопкой мыши должен регистрироваться на элементе как обычно.

Как сделать так, чтобы элемент игнорировал сразу все события мыши с помощью CSS, я знаю - pointer-events: none. Но как игнорировать события мыши для одной кнопки и одновременно регистрировать для другой - я не знаю.

Кто-нибудь может подсказать решение или функции языка JavaScript, с помощью которых можно решить эту задачу?
Ответить с цитированием
  #2 (permalink)  
Старый 02.11.2023, 07:47
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,749

Сообщение от roland
Клик правой кнопкой мыши должен регистрироваться на элементе как обычно.
Как обычно это значит, что событие должно всплывать до document? Или document не должен обрабатывать это событие?
const box = document.querySelector('div.box');

box.addEventListener('click', function (event) {
	if(event.button !== 2) return;  // Нажата не правая кнопка
    event.stopPropagation();  // Если не надо всплывать до document
	// Обработка события правой кнопки
})

document.addEventListener('click', function (event) {
	if(event.button !== 0) return;  // Нажата не левая кнопка
	// Обработка события
})

Последний раз редактировалось voraa, 02.11.2023 в 08:13.
Ответить с цитированием
  #3 (permalink)  
Старый 02.11.2023, 09:40
Аспирант
Отправить личное сообщение для roland Посмотреть профиль Найти все сообщения от roland
 
Регистрация: 02.11.2023
Сообщений: 30

Сообщение от voraa Посмотреть сообщение
Как обычно это значит, что событие должно всплывать до document?
Да.

Небольшое замечание по вашему коду:
В вашем примере в обработчике для box события "click" выполнение кода будет всегда завершаться первой строкой (return), так как событие "click" вызывается только для "главной кнопки" (event.button для мыши будет всегда равен "0"). Поэтому событие "click" нужно заменить на "auxclick".

В остальном ваш пример не совсем здесь подходит, так как не происходит главного: клика сквозь элемент div.box. Если под элементом div.box будет другой элемент (к примеру, div.box2) со своим собственным обработчиком:
box2.onclick = () => console.log('box_2')
Он не будет вызван, так как события мыши будут перехватываться div.box.
Ответить с цитированием
  #4 (permalink)  
Старый 02.11.2023, 11:03
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,749

Сообщение от roland
нужно заменить на "auxclick".
В Сафари не будет работать
Значит mouseup на box ловить нужно. И отменять контекстное меню на нем
<head>
<style>
.box2 {
	position: relative;
	background-color: yellow;
	width: 400px;
	height: 200px;	
}
.box {
	position: relative;
	background-color: red;
	width: 200px;
	height: 100px;	
	margin: 30px auto;
}
</style>
</head>
<body>
<div class=box2>
box2
<div class=box>
box<br>
Click
</div>
</div>
<script>
const box = document.querySelector('.box');
const box2 = document.querySelector('.box2');

document.body.addEventListener('click', (event) => {
	console.log('body left click');
})


box2.addEventListener('click', (event) => {
	console.log('box2 left click');
})
/*
box2.addEventListener('mouseup', (event) => {
	console.log('box2 mouse up');
})
*/

box.addEventListener('mouseup', (event) => {
	if (event.button === 2) {
		event.preventDefault();
		console.log('box right click');
	}
})

box.addEventListener('contextmenu', (event) => {
	event.preventDefault();
})

</script>


Надо пересматривать такие интерфейсы. Не принято в WEB кликать правой клавишей. Это для контекстного меню. И реализовать для тачскринов будет проблематично.

Последний раз редактировалось voraa, 02.11.2023 в 11:32.
Ответить с цитированием
  #5 (permalink)  
Старый 02.11.2023, 12:24
Аспирант
Отправить личное сообщение для roland Посмотреть профиль Найти все сообщения от roland
 
Регистрация: 02.11.2023
Сообщений: 30

В вашем примере .box2 является родителем для .box, что является очень специфичным примером, который, к сожалению, нельзя назвать универсальным решением. Это похоже на создание условий задачи под решение, а не создание решения под условия задачи. В любом случае, спасибо вам за уделённое время и старания.

Кажется решение нашлось в виде имитации "pointer-events: none" средствами JаvaScript: Во время клика по ".box" устанавливать "display: none", делать программный клик по элементу под курсором и возвращать для ".box" начальное значение "display".

Сообщение от voraa Посмотреть сообщение
Надо пересматривать такие интерфейсы. Не принято в WEB кликать правой клавишей.
Если под WEB подразумевать веб-сайты со страницами с информацией, я не могу не согласиться и кажется разумным решением не ломать привычки пользователей и классические приёмы взаимодействия. Но сейчас WEB это совокупность технологий, с помощью которой требуется реализовывать самые разнообразные интерфейсы. В том числе для web-приложений, оффлайн приложений, портированных desktop-приложений, игр и других вещей.
Ответить с цитированием
  #6 (permalink)  
Старый 02.11.2023, 12:42
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,749

Сообщение от roland
Это похоже на создание условий задачи под решение, а не создание решения под условия задачи.
А разве не такое условие было?
Сообщение от roland
Если под элементом div.box будет другой элемент (к примеру, div.box2) со своим собственным обработчиком:
Вы четко сформулируйте. Как расположены элементы, какой элемент на что должен реагировать, и на что не должен. Просто описывая трудно понять, что имеет в виду "под" и "над"
Ответить с цитированием
  #7 (permalink)  
Старый 02.11.2023, 13:15
Аватар для ruslan_mart
Профессор
Отправить личное сообщение для ruslan_mart Посмотреть профиль Найти все сообщения от ruslan_mart
 
Регистрация: 30.04.2012
Сообщений: 3,018

box.addEventListener('click', (event) => {
  event.stopImmediatePropagation();
});

box.addEventListener('pointerdown', (event) => {
  event.preventDefault();
});

box.addEventListener('contextmenu', (event) => {
  event.preventDefault();
  alert('Hello');
});


Оно?
Ответить с цитированием
  #8 (permalink)  
Старый 02.11.2023, 17:31
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,749

Сообщение от ruslan_mart
box.addEventListener('click', (event) => {
  event.stopImmediatePropagation();
});
Сообщение от roland
не совсем здесь подходит, так как не происходит главного: клика сквозь элемент div.box.
Я это понял так, что при клике на box все равно должен срабатывать клик на body
Ответить с цитированием
Ответ



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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
поиск классов внутри тега yozuul jQuery 24 14.06.2013 22:00
'click' для разных селекторов bannndi jQuery 4 03.06.2013 18:02
Не могу связать два события для разных элементов. nono Элементы интерфейса 8 07.03.2013 19:36
Один обработчик для нескольких кнопок! frundik Элементы интерфейса 2 10.07.2012 15:30
Немного Юмора - Гуртовщики Мыши antonM Оффтопик 12 23.03.2012 20:04