2011-12-30 3 views
0

Недавно я задал вопрос, чтобы получить метку alt изображения, отображаемого в центре изображения, когда вы наводите на него курсор, и был с благодарностью предоставлен этот следующий код для этого.jQuery Hover Alt Tag Issue

<script type="text/javascript"> 
    $(document).ready(function() { 
     $('#illustration-content ul li img').hover(
      function(){ 
       $(this).css('opacity','.2'); 
       var a = $(this).attr('alt'); 
       $(this).parent().append('<div class="title">' + a + '</div>'); 
      }, 
      function(){ 
       $(this).css('opacity','1'); 
       $(this).next().remove('.title'); 
      } 
     ); 
    }); 
</script> 

Это прекрасно работает.

Проблема, которая возникает у меня сейчас, заключается в том, что если курсор перемещается над тегом alt, когда он находится в центре изображения, он полностью исчезает. Я хочу, чтобы эффект исчез, когда курсор покидает изображение.

Вот css, который я использую, и html представляет собой прямой список изображений UL.

#illustration-content ul li img{ 
    position: relative; 
} 

.title{ 
    position: absolute; 
    z-index: 1000; 
    width: 100px; 
    margin: 80px 0px 0px -150px; 
    color: #fff; 
    font-size: 18px; 
    display: inline-block; 
} 

Я попытался с и без встроенного блока, такой же результат, но тег должен быть позиции по-разному.

Любые идеи, почему это может происходить?

Вот пример задачи: http://jsfiddle.net/ysSJu/

Спасибо за любую поддержку.

ответ

2

Объяснение

Причина, почему эффект исчезает, когда вы наведите курсор мыши на title, это потому, что у вас есть событие только для элемента img.
Вместо этого вы должны «связать» событие со всем li, так что, когда пользователь наведет над элементом списка, весь элемент, включая div.title, будет затронут.

demonstration

На картинке выше вы можете увидеть, как это работает.

В настоящее время у вас есть события, связанные с зеленым, img. Это означает, что div.title, желтый, будет рассматриваться как «внешний» элемент (потому что div.title не находится внутри элемента img), и поэтому событие mouseleave будет срабатывать, когда вы наведите указатель мыши на div.title.
Если вы связываете события с li, красный, событие будет охватывать все, что находится на красной рамке, которая зеленеет и желтый.

Вы также должны обработать свои блоки li как display: inline-block, чтобы вы могли позиционировать название по отношению к изображению.

Так, в основном, то, что я пытаюсь сказать, вместо

$('#illustration-content ul li img'); 

вы должны сделать

$('#illustration-content ul li'); 

Затем установите код соответственно.


Решение

Here is a working solution.

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, это могло бы быть лучше, чтобы произвести Див всего один раз в document.ready(), и показать/скрыть их, когда пользователь парит над их.
Это должно фактически увеличить общую производительность.

Here's an example.

По умолчанию .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. Наведение на самом деле является сокращенной функцией этих двух событий вместе взятых. Я склонен использовать первое, потому что его легче читать и более надежно читать.

Также обратите внимание, что в обоих решениях я использовал функцию .each(). Путем проверки элементов на переменные JQuery не придется тратить больше средств на поиск узлов каждый раз, когда я их ссылаюсь; что делает его более эффективным.

Пропустив элемент в качестве второго параметра в селекторе, как этот

$(".title", parent_element).css(...); 

Я не должны использовать такие функции, как .children() или .next(). Это также очень эффективно.

Вы упомянули, что вам было нелегко с position ing, have a look at this, это может прояснить ситуацию.


Фу, эти длинные посты трудно читать, а? Ну, я думаю, что я все понял.

Удача & счастливая кодировка! :)

+0

Большое вам спасибо за удивительное объяснение. Альтернативный способ кодирования работает как сон. Благодаря! – malicedix

+0

@malicedix Нет проблем. Жаль, что у меня нет никакой репутации. Я думаю, что сделал слишком много изменений. : P – ShadowScripter

+0

Да, это странно. Дайте мне знать, если что-нибудь могу сделать :) – malicedix

0

Изменение .hover. до .mouseenter и .mouseleave.

Поэтому в основном ...

var images = $('#illustration-content ul li img'); 
images.mouseenter(function(){ 
    $(this).css('opacity','.2'); 
    var a = $(this).attr('alt'); 
    $(this).parent().append('<div class="title">' + a + '</div>'); 
}); 
images.mouseleave(function(){ 
    $(this).css('opacity','1'); 
    $(this).next().remove('.title'); 
}); 

Причина, по которой, как вы отметили, зависший над альт <div> вызывает событие парения больше не огня на внешней IMG. Однако с mouseenter и mouseleave, парящими над альт <div> не стреляют mouseleave для <img>.

+0

Мне понравилась идея, но, похоже, она не исправляет проблему: http://jsfiddle.net/ysSJu/2/ – Jasper

1

Вы можете проверить event.relatedTarget свойство, чтобы увидеть, если это .title элемент в вашей mouseout функции:

  function(event){ 
       if (!$(event.relatedTarget).hasClass('title')) { 
        $(this).css('opacity','1').siblings().remove(); 
       } 
      } 

Демо: http://jsfiddle.net/ysSJu/1/

Также обратите внимание, как я прикован функции вызовов, так что вы не нужно сделать два объекта jQuery от this.

UPDATE

Я заметил, что при перемещении курсора от одного изображения к другому, что .title элемент не будет удален, как это должно быть от предыдущего изображения. Вы можете исправить это путем сброса opacity и .remove() ИНГ дополнительных .title элементов img элемента:

var $images = $('#illustration-content ul li img'); 
$images.hover(
    function(){ 
     $images.css('opacity', 1).siblings().remove('.title'); 
     var $this = $(this), 
      a  = $this.attr('alt'); 
     $this.css('opacity','.2').parent().append('<span class="title">' + a + '</span>'); 
    }, 
    function(event){ 
     if (!$(event.relatedTarget).hasClass('title')) { 
      $(this).css('opacity','1').siblings().remove('.title'); 
     } 
    } 
); 

Вот демо: http://jsfiddle.net/ysSJu/3/

+0

Также отлично работает. Спасибо, что посмотрели на это! – malicedix