Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Распростронение событий за элементами (https://javascript.ru/forum/events/31138-rasprostronenie-sobytijj-za-ehlementami.html)

sannas 28.08.2012 11:16

Распростронение событий за элементами
 
Добрый день форумчане!
Вопрос такой:
Как сделать на jquery (или на чистом js) так, чтобы при клике на элемент стоящий поверх остальных элементов, событие клика распространялось на нижележащие элементы.
Уже не первый раз встречаюсь с данной проблемой, но ответа так и не нашел. Решил обратиться к специалистам.

yura_remnev 28.08.2012 11:35

В jQuery нет механизма распространения события на вложенные элементы ("захват", capturing) и это не просто так :)
Если Вам не нужна поддержка IE6-8, то навешивайте обработчики с помощью addEventListener. jQuery не может себе позволить (пока) отказаться от поддержки этих браузеров, поэтому этого механизма там нет.
Интересно, какая у вас задача. В большинстве случаев можно обойтись красивым решением без фазы захвата.

sannas 28.08.2012 12:00

Меня не интересуют в данном примере поддержка старых браузеров.
Задача у меня такова:
Есть элемент который перетаскивается в рамках родительского элемента средствами JQuery UI

<div id="f_menu">
	 <div id="f_glass"></div>
     <ul id="f_menu_ul">
	  <li id="f_calendar" href="calendar"></li><li id="f_markets" href="markets"></li><li id="f_news" class="f_current" href="news"></li><li id="f_statistics" href="statistics"></li><li id="f_search" href="search"></li>
	 </ul>
	</div>


$('#f_menu_ul').draggable({containment: "#f_menu", axis: "x",  scroll: false});


Над этим всем находится элемент с position: absolute создающий блик в центре перетаскиваемого элемента.
Так вот, он мешает перетаскивать элемент))

http://webfile.ru/image?id=6094621

bes 28.08.2012 12:04

что мешает их вложить
<style>
div {
	position: absolute;
	left: 0px;
	top: 0px;
	width: 100px;
	height: 100px;
	background: green;
}
</style>

<div onclick="alert('div1')">
	div1
	<div onclick="alert('div2')">
		div2
	</div>
</div>

sannas 28.08.2012 12:17

Спасибо bes, но у меня чуть другая ситуация

<style>
 div {
   position: absolute;
   left: 0px;
   top: 0px;
   width: 100px;
   height: 100px;
   background: green;
 }
</style>

<div onclick="alert('div1')">
 div1  
</div>
<div onclick="alert('div2')">
  div2
</div>

bes 28.08.2012 12:20

<style>
 div {
   position: absolute;
   left: 0px;
   top: 0px;
   width: 100px;
   height: 100px;
   background: green;
 }
</style>

<div id="div1">
	div1  
</div>
<div id="div2">
	div2
</div>

<script>
window.onload = function () {
	var div1 = document.getElementById('div1');
	var div2 = document.getElementById('div2');
	div1.onclick = function () {
		alert('div1');
	}
	div2.onclick = function () {
		div1.click();
	}
}
</script>

sannas 28.08.2012 12:28

Вызвать обработчик события это понятная вещь, но у меня div1 является элемент для которого применен JQueryUI draggable.
Вообще мне нужно, что бы div1 таскался, а получается, что div2 этому мешает.

bes 28.08.2012 12:38

Все обработчики будут вызываться для нужного элемента, а не для того, который сверху.
Для примера
Что ниже
<style>
 div {
   position: absolute;
   left: 0px;
   top: 0px;
   height: 100px;
 }
</style>

<div style="width: 100px; background: green; z-index: 98">div</div>
<div style="width: 50px; background: blue; z-index: 100">div1</div>
<div style="width: 50px; left: 50px; background: red; z-index: 100">div2</div>

<script>
window.onload = function () {
	var divs = document.getElementsByTagName('div');
	var div = divs[0];
	var div1 = divs[1];
	var div2 = divs[2];
	
	div1.onclick = function () {
		alert(this.innerHTML);
	}
	
	div2.onclick = function () {
		alert(this.innerHTML);
	}
	
	div.onclick = function (e) {
		e = e || event;
		this.style.zIndex = 99;
		var elem = document.elementFromPoint(e.clientX, e.clientY);
		this.style.zIndex = 101;
		elem.click();
	}
	
}
</script>


Как работает
<style>
 div {
   position: absolute;
   left: 0px;
   top: 0px;
   height: 100px;
 }
</style>

<div style="width: 100px; background: green; z-index: 101">div</div>
<div style="width: 50px; background: blue; z-index: 100">div1</div>
<div style="width: 50px; left: 50px; background: red; z-index: 100">div2</div>

<script>
window.onload = function () {
	var divs = document.getElementsByTagName('div');
	var div = divs[0];
	var div1 = divs[1];
	var div2 = divs[2];
	
	div1.onclick = function () {
		alert(this.innerHTML);
	}
	
	div2.onclick = function () {
		alert(this.innerHTML);
	}
	
	div.onclick = function (e) {
		e = e || event;
		this.style.zIndex = 99;
		var elem = document.elementFromPoint(e.clientX, e.clientY);
		this.style.zIndex = 101;
		elem.click();
	}
	
}
</script>

sannas 28.08.2012 12:56

Я уже подобный вариант реализовывал, только через скрытие элементов.
Тут задача в другом.
У меня есть идея... Есть ли в js или Jquery метод для того, что бы подписаться на все события элемента?

Deff 28.08.2012 13:00

sannas,
При нажатии кнопки мыши - z-indexom перевести блик за элемент драгабле на время 0.5 - 0.7 сек


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