Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   как различать события onclick и onmousedown на одном элементе (https://javascript.ru/forum/events/8728-kak-razlichat-sobytiya-onclick-i-onmousedown-na-odnom-ehlemente.html)

Gloft 10.04.2010 09:06

как различать события onclick и onmousedown на одном элементе
 
как различать события onclick и onmousedown на одном элементе?
Например обработка событий на элементе id='test' всегда заканчивается с результатом "onMouseDoun"
document.write("<div id='test'>Test onClik and onMouseDoun</div>");
tegTest = document.getElementById('test');
tegTest.onclick = function(){this.innerHTML = "onClick"};
tegTest.onmousedown = function(){this.innerHTML = "onMouseDoun"};

Kolyaj 10.04.2010 09:11

Что значит как различать?

Gloft 10.04.2010 09:15

Элемент должен по разному реагировать на два события onclick и onmousedown.
onmousedown используется для перемещения элемента.
onclick - для раскрытия списка.

Kolyaj 10.04.2010 09:39

Ну так у них разные обработчики событий. В чём проблема?

Gloft 10.04.2010 09:49

Событие onclick не обрабатывается.
Для проверки замени
tegTest.onclick = function(){this.innerHTML = "onClick"};

на
tegTest.onclick = function(){alert('onClick')};

subzey 10.04.2010 11:48

Подтверждаю. Opera 10.50.

Не генерируется событие click при щелчке по тексту. При этом при щелчке на самом диве событие стартует. Замена
tegTest.onmousedown = function(){this.innerHTML = "onMouseDoun"};
на
tegTest.onmousedown = function(){
	this.removeChild(this.childNodes[0]);
	this.appendChild(document.createTextNode("textnode test"));
};

приводит к аналогичным результатам.

Поведение следующее:
— mousedown над текстовой нодой;
— замена одной текстовой ноды на другую;
— mouseup над новой текстовой нодой;
— click не генерируется, так как события совершены над разными нодами.

А вот тут-то самое интересное.
Цитата:

A click is defined as a mousedown and mouseup over the same screen location.

Цитата:

The definition of a click depends on the environment configuration; i.e. it may depend on the screen location or the delay between the press and release of the pointing device button. In any case, the event target must be the same between the mousedown, mouseup, and click.

По всей видимости, опера придерживается модели HTML5, при этом считая «event target» не элемент, а ноду.

Gloft 10.04.2010 12:02

Получется, что фактически нельзя/неэффективно совмещать события onclick и onmousedown на одном элементе.

Для своего случая решил проблему заменив onclick на ondblclick.
Не то что хотел, но зато работает так как и ожидалось.

subzey 10.04.2010 12:25

Да можно, почему нельзя…
Просто не трогайте особо этот элемент — записывайте данные в другой, или, вообще, alert.

Gloft 10.04.2010 12:34

Код в первом сообщении я привел как для примера.
В моем случае мне нужно было разделять эти события для управяления меню.
Меню можно переместить (события onmousedown, onmousemove, onmouseup) и свернуть развернуть (событие onclick/ondblclick).
И все это на одном элементе.

Вот пример решения проблемы который был приведен мной в первом сообшении:
var master = (function() {
   // функция обработки события onDblClick
   function mouseOnDblClick(){
      alert('mouseClick');
      return false;
   }

   // функция обработки события onMouseMove
   function mouseMove(){
      alert('mouseDown and mouseMove');
      return false;
   }

   // функция обработки события onMouseUp
   function mouseUp(){
		// очистить обработчики, т.к перенос закончен
		document.onmousemove = null;
		document.onmouseup = null;
		document.ondragstart = null;
		document.body.onselectstart = null;
   }


	function mouseDown(){
		document.onmousemove = mouseMove;
		document.onmouseup = mouseUp;
      document.onclick = mouseOnDblClick;

		// отменить перенос и выделение текста при клике на обьекте
		document.ondragstart = function() {return false};
		document.body.onselectstart = function() {return false};

		return false;

	}

	return {
		makeDraggable: function(element){
			element.onmousedown = mouseDown;
		}
	}
}());

document.write("<div id='test'>Test onClik and onMouseDoun</div>");
master.makeDraggable(document.getElementById('test'));

subzey 10.04.2010 13:27

Ну, во-первых, для таких вещей используйте, все-таки, addEventListener/attachEvent!

Ну, а во-вторых, Вам таки и не обязатеьно тут использовать событие click.
Поставьте обработчики mouseup, mousedown и mousemove на document, а потом отслеживайте события.
Как это сделать, я расписывал тут и приводил более «живые» примеры тут.

Потом все очень просто. Mousedown на подходящем элементе переводит скрипт в… эм-м… особый режим, когда тот отслеживает mousemove по всему документу, и при этом «гасит» событие через e.preventDefault(). Mouseup, соответственно, это дело завершает.
А теперь мы просто сидим и ждем. Если mousemove случился раньше, чем mouseup, то действет так, будто это драг-н-дроп; если перед mouseup так и не случилось mousemove, то действуем так, будто это клик.


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