jQuery, выборочно исключить в селекторе событие

12
A
На сайте с 04.11.2007
Offline
134
1478

Приветствую всех!

Появились сомнения в возможности сделать подобное в селекторе.

При клики в любом(это важно) месте div-а меняется его фон. Что нужно прописать в селекторе, чтобы исключить смену фона при клике по ссылкам "a href"?

Может другое есть решение, а то я прицепился к селекторам и ни в какую.


--html--
<div id="div">
<a href="#link1">link1</a> text1 <span>span1</span>
<a href="#link2">link2</a> text2 <b>bold</b> <span>span2</span>
<a href="#link3">link3</a> text3 <i>italic</i> <span>span3</span>
</div>

--css--
#div {
height: 5em;
line-height: 5em;
text-align: center;
border: 1px solid green;
}
#div a {
padding: 1em;
border: 1px solid red;
}
.yellow {
background-color: yellow !important;
}

--js--
$('#div').click( function(e) {
$(this).toggleClass('yellow');
});
K
На сайте с 03.06.2015
Offline
45
#1

Сравнить объекты this и event.target

if(this === event.target) /* щелчок идет именно от родителя, а не от его потомков */

Ну или по колхозному

if(event.target.nodeType=='DIV')

значит по div, однако когда вы поменяете div на скажем nav, придется переписывать и тут

asteroid:
Что нужно прописать в селекторе

Разумеется все что выше делается в функции.

MYSQL PHP JS HTML CSS SEO TXT США СССР
viКing
На сайте с 20.03.2008
Offline
124
#2

e.stopPropagation();

K
На сайте с 03.06.2015
Offline
45
#3

Это на все линки придется вешать.

А, ну да, совсем забыл, они же на жиквери так и делают, вообще не парятся. чего-то-там.each(и вперде)

Тогда еще пояснение - все что я выше написал справедливо для 1 функции слушателя на 1 объекте родителя - том самом div. Стандартный мини-контроллер.

RiDDi
На сайте с 06.06.2010
Offline
285
#4

this === event.target

не примет событие от <span>, <b>, <i>..

stopPropagation

было бы лучше и более логично если бы присутствовал обработчик <a>

но, видимо, имеется ввиду просто переход по ссылке и тогда лучше запихать в обработчик div исключение для <a> че уж..


$('#div').click( function(e) {
if(!$(e.target).is('a')) $(this).toggleClass('yellow');
});
Вебмастер отдыхает на бережках морей. Заработок в интернете - дело техники.
A
На сайте с 04.11.2007
Offline
134
#5

kostyanet, решение с target, как по мне, это лучший вариант. Благодарю Вас.


if ( $(e.target).is(':not(a)') ) {
$(this).toggleClass('yellow');
}

Если кто возьмёт идею, то тут есть минусы. Если в ссылке <a> есть элементы, то их тоже придётся указывать и "давить". Например <img>


<a href="#link1"><img src="/img.jpg" />link1</a>

if ( $(e.target).is(':not(a,img)') ) {
$(this).toggleClass('yellow');
}


---------- Добавлено 16.08.2015 в 22:05 ----------

viКing:
e.stopPropagation();

Если я правильно понял, то Вы предлагаете делать второй обработчик на <a> и в нём stopPropagation() "давить" первый. Первый был на <div>.

Благодарю за идею. Не пробовал такой вариант, но возьму на вооружение.

---------- Добавлено 16.08.2015 в 22:11 ----------

RiDDi, Благодарю!

Реально под вечер туплю. Эта строчка красивее и быстрее моей


if ( ! $(e.target).is('a') ) {
...
}
K
На сайте с 03.06.2015
Offline
45
#6
RiDDi:
не примет событие от <span>, <b>, <i>..

Не понял ничего.

Дана ветка хтмля начинающаяся с div. Допустим у него есть id

document.getElementById('foo').addEventListener('click',func);

теперь куда бы не щелкнули, на любой дочерний элемент, а, и, спан, б и тп - событие всплывет до div'а где и спалится функцией func.


var func=function(e){
if(this===e.target) /* если зис и таргет один и тот же объект, значит щелкнули именно сам div */
};

Если надо сегрегировать конкретно ссылки, то


var func=function(e){
if(this.nodeName!='A') /* если зис не ссылка то поменять цвет */
};

Ну и вообще что угодно можно проверить, поскольку обрабатывается событие контейнера.

---------- Добавлено 17.08.2015 в 07:56 ----------

asteroid:
Если кто возьмёт идею, то тут есть минусы.

html вообще это один большой минус.

Вы рассуждаете семантически, типа вот ссылка, в ней там барахло может быть, картинки, еще теги - какая разница. Ну да, а для браузера есть разница. Он должен вам показать что щелкнуто, а вы уже можете решать что дальше делать. Так чтобы находить нужный элемент вверх по дереву пишется простейшая функция


var find_by_cb=function(el,cb){
do{
if(cb(el))
return el;
} while(el=el.parentNode);

return false;
};

var a = find_by_cb(e.target,function(el){return el.nodeName=='A';});

По-другому вам придется да, все перечислять.

---------- Добавлено 17.08.2015 в 08:03 ----------

В CSS вроде бы есть какие-то атрибуты делающие элемент "прозрачным" для щелчка. Один раз поискал как-то, запомнил только это "вроде бы есть", то есть не пашут они, говорят.

A
На сайте с 04.11.2007
Offline
134
#7
kostyanet:
... Так чтобы находить нужный элемент вверх по дереву пишется простейшая функция ...

Сейчас голова свежая и исключить вложенные элементы, в данном примере, можно jquery функцией без перечислений и самописной:


<div id="div">
<a href="#link1">
<img src="/img/chart_area.png" />link1<b>bold<i>italic</i></b>
</a>
...
</div>

$('#div').click( function(e) {
if ( ! $(e.target).is('a') && ! $(e.target).parents('#div a').length ) {
$(this).toggleClass('yellow');
}
});

Вот теперь понимаю, что в $селекторе.click() такие условия невозможно было задать.

Ayavryk
На сайте с 11.10.2003
Offline
209
#8
kostyanet:
А, ну да, совсем забыл, они же на жиквери так и делают...Стандартный мини-контроллер.

Можно подумать что навешивание всюду MV[C]* чем-то лучше тотального jquery и не провоцирует появление излишеств.

Тынгыр, мынгыр, комсомол (http://erum.ru). Ехари, ехари, (жалобно) аяврик. /народная тунгусская песня/
K
На сайте с 03.06.2015
Offline
45
#9

Это не mvc, это html. В нем нет правды. Хорошо что текстовая нода не кликабельна. Все остальное хотели и сделали кликабельным. Потому что да, надо. Тогда и пришлось рекурсить ветку, потому что иначе никак.

asteroid:
в данном примере, можно jquery функцией без перечислений и самописной:

Это религия.

Жикверя не может всего предусмотреть и все равно накапливается даже небольшая библиотека, с применением той же жиквери, конечно.

У меня другая религия и повторное использование текстового идентификатора в моей церкви считается грехом. :) А потому что как иначе, ей же надо css подавать, этой parents() да? Туда же не засунешь комбинацию this и "а", который тоже два раза. В общем это мелочи, конечно, но из них и состоит культура.

A
На сайте с 04.11.2007
Offline
134
#10
kostyanet:
Это религия.

Это логика.

kostyanet:

У меня другая религия и повторное использование текстового идентификатора в моей церкви считается грехом. :) А потому что как иначе, ей же надо css подавать, этой parents() да? Туда же не засунешь комбинацию this и "а", который тоже два раза. В общем это мелочи, конечно, но из них и состоит культура.

Ограничение путешествия по дереву вверх не является повтором "использование текстового идентификатора". Это новая задача внутри первой с совпадающими условиями. И мой логический атеизм поощряет минимализм в скриптовых конструкциях. Он же считает jQuery не бескультурной js панацеей, а обычным инструментом.

12

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий