Объяснение
Причина, по которой эффект исчезает при наведении курсора на заголовок, заключается в том, что у вас есть событие только для элемента img
.
Вместо этого вы должны "связать" событие свсего li
, так что когда пользователь наводит курсор на элемент списка, будет затронут весь элемент, включая div.title
.
На изображении выше, вы можете увидеть, как это работает.
В настоящее время у вас есть события, связанные с тем, что соответствует зеленому, img
.Это означает, что желтый div.title
будет рассматриваться как «внешний» элемент (потому что div.title
не находится внутри элемента img
), и поэтому событие mouseleave
будет срабатывать, когда вы наводите курсор наdiv.title
.
Если вы свяжете события с li
, красным, событие будет охватывать все, что находится в красной рамке: зеленый и желтый.
Вы также должны обрабатывать свои li
блоки как display: inline-block
, чтобы вы могли расположить заголовок по отношению к изображению.
Итак, в основном я пытаюсь сказать,вместо
$('#illustration-content ul li img');
вы должны сделать
$('#illustration-content ul li');
Затем отрегулируйте код соответствующим образом.
Решение
Вотрабочее решение .
var $lis = $('#illustration-content ul li');
$lis.each(function(index, el){
var $this = $(el);
var eImg = $("img", $this);
$this.mouseenter(function(){
var eTitle = $('<div class="title">' + eImg .attr('alt') + '</div>');
eImg.css('opacity','.1');
$this.prepend(eTitle);
}).mouseleave(function(){
var eTitle = $("div.title", $this);
eImg.css('opacity','1');
eTitle.remove('.title');
});
});
Альтернативное решение
Вместо того, чтобы создавать и уничтожать div на каждом mouseenter/mouseleave
, может быть лучше создать div только один разна document.ready()
и показывать / скрывать их, когда пользователь наводит на них курсор.
Это должно фактически увеличить общую производительностьnce.
Вот пример.
По умолчанию .title
имеет свойство стиля display: none
.
var $lis = $('#illustration-content ul li');
$lis.each(function(index, el){
var $this = $(el);
var eImg = $("img", $this);
var eTitle = $('<div class="title">' + eImg.attr('alt') + '</div>');
$this.prepend(eTitle)
.mouseenter(function(){
eImg.css('opacity','.1');
eTitle.show();
})
.mouseleave(function(){
eImg.css('opacity','1');
eTitle.hide();
});
});
Дополнительная информация, полезно знать
Обратите внимание, что я использовал mouseenter
и mouseleave
вместо hover
.Hover на самом деле является сокращенной функцией этих двух событий вместе взятых.Я склонен использовать первый, потому что он, как правило, легче читать и более надежен.
Также обратите внимание, что в обоих решениях я использовал функцию .each()
.Передавая элементы переменным, JQuery не придется тратить больше времени на обработку узлов, чтобы найти узлы каждый раз, когда я ссылаюсь на них;делая его более эффективным.
Передавая элемент в качестве второго параметра в селекторе, например,
$(".title", parent_element).css(...);
Мне не нужно использовать такие функции, как .children()
или .next()
.Это также очень эффективно.
Вы упомянули, что у вас были трудные времена с position
ing, посмотрите на это , это может прояснить ситуацию.
Фу, эти длинные посты трудно читать, а?Ну, я думаю, что покрыл все необходимое.
Удачи и счастливого кодирования!:)