Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   как переопределить обработчик для всех элементов, кроме одного? (https://javascript.ru/forum/events/80069-kak-pereopredelit-obrabotchik-dlya-vsekh-ehlementov-krome-odnogo.html)

zxazx 23.04.2020 14:24

как переопределить обработчик для всех элементов, кроме одного?
 
нужно убрать возможность выделения для всей страницы, кроме одного элемента.
запретить выделение для всех элементов на странице не сложно:
document.onmousedown = document.onselectstart = function() {
  return false;
};


но в этом случае не понятно, как оставить возможность выделения для одного элемента.

пс: убирать для каждого элемента по отдельности можно, конечно, но не интересно.

voraa 23.04.2020 15:07

Мот так
let elem = ... // тот, для которого не отменяем
document.onmousedown =  function(ev) {
  return ev.target === elem;
};

zxazx 23.04.2020 15:30

let elem = document.getElementById('test');
document.onmousedown = function(ev) {

  return ev.target === elem;
};
document.onselectstart = function(ev) {

  return ev.target === elem;
};

document.onmousedown = document.onselectstart = function() {
  return false;
};


не работает.
при клике на элементе "test" браузер идет в переназначенную функцию.

voraa 23.04.2020 15:37

Просто вот так. Без всего остального

let elem = document.getElementById('test');
document.onmousedown = function(ev) {
  return [].includes.call(ev.path, elem)
};


Я немного изменил, что бы можно было выделять и дочерние элементы 'test'

zxazx 23.04.2020 15:44

Ух ты! работает :)
теперь бы еще понять как...
спасибо

voraa 23.04.2020 15:58

Цитата:

Сообщение от zxazx (Сообщение 523292)
Ух ты! работает :)
теперь бы еще понять как...
спасибо

Когда кликается мышка, событие mousedown начинает "всплывать" от того элемента, на котором кликнули, через все родительские, до document.
При этом будут вызываться обработчики события назначенные для него для этих элементов. Но у нас он назначен только для document.
В свойстве event.path - содержится вся последовательность элементов через которое всплывало событие.
event.path[0] - тот на котором нажали
event.path[event.path.length - 1] - document
Когда событие пришло в document мы ищем проходило ли оно, через элемент elem.
Функция массива includes(item) - возвращает true если элемент item содержится в массиве.
Но event.path не массив, а массивоподобный объект, поэтому includes приходится вызывать через Ж так [].includes.call(ev.path, elem)
Если событие не прошло через elem, то функция вернет false и тем самым отменится стандартная реакция на событие. В том числе и начало выделения.

рони 23.04.2020 16:00

:-?
document.onmousedown = function(ev) {
  return !!ev.target.closest('#test');
  };

voraa 23.04.2020 16:05

Для данного случая можно и так.
Но если elem получен как то по другому, без id или селекторов то только через ev.path.

Хотя так тоже можно
document.onmousedown = function(ev) {
  return elem.contains(ev.target)
  };

zxazx 23.04.2020 17:08

разобрался. было интересно. всем спасибо

zxazx 29.04.2020 17:15

появился еще один близкий вопрос. поэтому, в эту же тему.
есть два элемента canvas. как при правом клике мышкой на первом canvas, скопировать картинку из другого canvas?
попытки изменить значение event.path[0] не получаются :((
пробую так:
document.oncontextmenu = function(e){
	if(e.path[0].id == "topCanv"){
		var x = document.getElementById("chart");
		e.path[0] = x;
	}
};


Часовой пояс GMT +3, время: 10:38.