02.11.2023, 07:03
|
Аспирант
|
|
Регистрация: 02.11.2023
Сообщений: 30
|
|
Клик сквозь элемент для разных кнопок мыши
Здравствуйте. Есть простая на первый взгляд задача, которая легко решается на системных языках программирования, но которая поставила меня в тупик при попытке реализации её на Web:
На странице располагается 1 элемент - div.box, к примеру.
Клик левой кнопкой мыши должен проходить сквозь этот элемент. Для клика элемента не должно существовать вообще, а срабатывать он должен на родителе (document.body).
Клик правой кнопкой мыши должен регистрироваться на элементе как обычно.
Как сделать так, чтобы элемент игнорировал сразу все события мыши с помощью CSS, я знаю - pointer-events: none. Но как игнорировать события мыши для одной кнопки и одновременно регистрировать для другой - я не знаю.
Кто-нибудь может подсказать решение или функции языка JavaScript, с помощью которых можно решить эту задачу?
|
|
02.11.2023, 07:47
|
|
Профессор
|
|
Регистрация: 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.
|
|
02.11.2023, 09:40
|
Аспирант
|
|
Регистрация: 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.
|
|
02.11.2023, 11:03
|
|
Профессор
|
|
Регистрация: 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.
|
|
02.11.2023, 12:24
|
Аспирант
|
|
Регистрация: 02.11.2023
Сообщений: 30
|
|
В вашем примере .box2 является родителем для .box, что является очень специфичным примером, который, к сожалению, нельзя назвать универсальным решением. Это похоже на создание условий задачи под решение, а не создание решения под условия задачи. В любом случае, спасибо вам за уделённое время и старания.
Кажется решение нашлось в виде имитации "pointer-events: none" средствами JаvaScript: Во время клика по ".box" устанавливать "display: none", делать программный клик по элементу под курсором и возвращать для ".box" начальное значение "display".
Сообщение от voraa
|
Надо пересматривать такие интерфейсы. Не принято в WEB кликать правой клавишей.
|
Если под WEB подразумевать веб-сайты со страницами с информацией, я не могу не согласиться и кажется разумным решением не ломать привычки пользователей и классические приёмы взаимодействия. Но сейчас WEB это совокупность технологий, с помощью которой требуется реализовывать самые разнообразные интерфейсы. В том числе для web-приложений, оффлайн приложений, портированных desktop-приложений, игр и других вещей.
|
|
02.11.2023, 12:42
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,749
|
|
Сообщение от roland
|
Это похоже на создание условий задачи под решение, а не создание решения под условия задачи.
|
А разве не такое условие было?
Сообщение от roland
|
Если под элементом div.box будет другой элемент (к примеру, div.box2) со своим собственным обработчиком:
|
Вы четко сформулируйте. Как расположены элементы, какой элемент на что должен реагировать, и на что не должен. Просто описывая трудно понять, что имеет в виду "под" и "над"
|
|
02.11.2023, 13:15
|
|
Профессор
|
|
Регистрация: 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');
});
Оно?
|
|
02.11.2023, 17:31
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,749
|
|
Сообщение от ruslan_mart
|
box.addEventListener('click', (event) => {
event.stopImmediatePropagation();
});
|
Сообщение от roland
|
не совсем здесь подходит, так как не происходит главного: клика сквозь элемент div.box.
|
Я это понял так, что при клике на box все равно должен срабатывать клик на body
|
|
|
|