JQuery Hover Alt Tag Issue - PullRequest
       26

JQuery Hover Alt Tag Issue

0 голосов
/ 31 декабря 2011

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

<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;
}

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

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

Вот пример проблемы: http://jsfiddle.net/ysSJu/

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

Ответы [ 3 ]

2 голосов
/ 31 декабря 2011

Объяснение

Причина, по которой эффект исчезает при наведении курсора на заголовок, заключается в том, что у вас есть событие только для элемента 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'); 

Затем отрегулируйте код соответствующим образом.


Решение

Вотрабочее решение .

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, посмотрите на это , это может прояснить ситуацию.


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

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

1 голос
/ 31 декабря 2011

Вы можете проверить свойство 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() элементов img с дополнительными .title элементами:

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 голосов
/ 31 декабря 2011

Изменение .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');
 });

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

...