#jquery
#jquery
Вопрос:
Я хочу реализовать выделение, подобное firebug, при наведении курсора на элемент
$("*").mouseover(function()
{
$(this).css({border:'1px solid blue'});
})
.mouseleave(function()
{
$(this).css({border: ''});
});
но это не меняет css при наведении курсора на внутренний элемент, стиль внешнего элемента по-прежнему изменяется вместо возврата к исходному css из-за mouseleave()
Ответ №1:
Не делайте таких тяжелых вещей на *
. Используйте .delegate
вместо этого.
$('body').delegate('*', 'mouseover mouseout', function (e) {
if (this === e.target) {
$(e.target).css('border', (e.type === 'mouseover' ? '1px solid blue' : ''));
}
});
Я не тестировал это, но моя точка зрения заключается в использовании .delegate
.
Редактировать Добавленное предложение от Crowder (спасибо!)
Комментарии:
1. Мне нравится, как вы сгустили вещи, и я согласен с
delegate
(добавлялdelegate
решение к моему ответу, как вы опубликовали), но обратите внимание, что вышеупомянутое будет повторно вызыватьсяcss
неоднократно для одного и того же элемента (e.target
). Если у вас есть (скажем)ul
сli
strong
, если пользователь наведет курсор наstrong
элемент, ваш код вызоветcss
этотstrong
элемент три раза (один раз дляstrong
, снова дляli
и снова дляul
). В данном случае это в значительной степени безвредно, но требует много ненужной работы. @ianace, ты захочешь добавитьthis === e.target
проверку.2. Да, я только что jsbined и проверил, вы правы. Забавно, я все еще не могу представить, почему он это делает. придется поискать повнимательнее 🙂 спасибо, кстати jsbin.com/eveno4/8/edit
3. @Shrikant: Не беспокойтесь. 🙂 Он делает это, потому что
delegate
он фантастический и на самом деле выполняет пузырящиеся вызовы, аmouseover
иmouseout
являются пузырящимися событиями (так чтоmouseover
на дочернем элементе также видно на родительском элементе).4. @Crowder, верно, но для родительских элементов это событие с пузырьками, верно? не событие, которое возникло на них, поэтому
delegate
не следует его поднимать …. о, подождите! мы используем*
селектор, который соответствует им всем, и событие запускается! черт! спасибо 🙂
Ответ №2:
Как и у Noufal, моей первой мыслью было «лучше сделать это с помощью :hover
псевдокласса CSS» (если только вам не нужно поддерживать IE6, который не поддерживает :hover
ничего, кроме ссылок), но я не могу сразу придумать, как бы вы справились с тем, чтобы у элементов-предков также не было границы. И наличие границы для всех предков выглядит для меня довольно уродливо:http://jsbin.com/eveno4/2
Что касается решения на JavaScript: вы были близки к этому, но обычно вы использовали mouseover
и mouseout
, или использовали mouseenter
и mouseleave
, но не mouseover
и mouseleave
(обычно нет; есть места, где вы бы это сделали).
В этом случае я бы, вероятно, использовал mouseover
и mouseout
, но действовал бы только на события, фактически инициируемые рассматриваемым элементом (не пузырьковые):
$("*").mouseover(function(event)
{
if (this === event.target) {
$(this).css({border:'1px solid blue'});
}
})
.mouseout(function(event)
{
if (this === event.target) {
$(this).css({border:''});
}
});
Обратите внимание на использование event.target
, чтобы убедиться, что мы не обрабатываем событие с пузырьками.
Или, вместо того, чтобы подключать обработчик к каждому элементу на странице, подключите обработчики только к body
элементу и воспользуйтесь тем фактом, что они всплывают, используя delegate
:
$(document.body).delegate("*", "mouseover", function(event)
{
if (this === event.target) {
$(this).css({border:'1px solid blue'});
}
})
.delegate("*", "mouseout", function(event)
{
if (this === event.target) {
$(this).css({border:''});
}
});
(Или вы могли бы использовать live
, это в значительной степени сводится к тому же.)
Комментарии:
1. Насколько я знаю,
if
условия вdelegate
примере бесполезны, посколькуthis
всегда равноevent.target
.2. @Shrikant: Нет, они действительно служат определенной цели. Посмотрите на это без них: jsbin.com/eveno4/5
3. @Crowder Виноват, я имел это в виду, когда говорил это jsbin.com/eveno4/6/edit (заимствовано из моего ответа)
Ответ №3:
Разве вы не можете сделать что-то вроде
*:hover {
border: 1px solid blue;
}
в ваших правилах CSS вместо того, чтобы полагаться на Javascript?
Обновить. Я только что попробовал это, и, похоже, это работает достаточно хорошо.
Комментарии:
1. никогда не думал об этом, но решит ли это проблему отсутствия родительского элемента, который также зависает? я имею в виду, что если я перейду к внутреннему элементу, то основное внимание будет уделено внутреннему элементу, а не родительскому, и, следовательно, не изменит его css
2. Ну, родительский элемент тоже будет выделен, но вы могли бы найти более узкий селектор и использовать его. Кроме того, это не так отвлекает, как кажется.
3. Как бы вы это сделали? (Надежно кроссбраузерный, конечно.) Нацеливаться на любой элемент, но только по одному за раз? На мой взгляд, это выглядит ужасно, поскольку у родителей также есть граница: jsbin.com/eveno4/2
4. Вы правы. Способа нет (я все равно не могу придумать ни одного). На мой взгляд, это не так плохо, но и не идеально. Я пытался получить что-то лучшее, используя вместо этого непрозрачность и цвета фона, но не смог.