0

我最近问了一个问题,当您将鼠标悬停在图像的中心时,我会在图像的中心显示该图像的 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;
}

我尝试过使用和不使用 inline 块,结果相同,但标签的位置需要不同。

任何想法为什么会发生这种情况?

这是问题的一个例子:http: //jsfiddle.net/ysSJu/

感谢您的任何支持。

4

3 回答 3

2

解释

当您将鼠标悬停在标题上时效果消失的原因是因为您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');
    });
});

替代解决方案

与其在 every 处创建和销毁一个 div,mouseenter/mouseleave不如在 处只生成一次 div document.ready(),并在用户将鼠标悬停在它们上方时显示/隐藏它们。
它实际上应该提高整体性能。

这是一个例子。

默认情况下,.title具有 style 属性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();
        });
});

附加信息,很高兴知道

请注意,我使用mouseenterandmouseleave而不是hover. 悬停实际上是这两个事件组合的简写功能。我倾向于使用前者,因为它通常更容易阅读,也更可靠。

另请注意,在这两种解决方案中,我都使用了函数.each(). 通过将元素分配给变量,每次引用节点时,JQuery 都不必浪费更多的处理来查找节点;使其更有效率。

通过在选择器中将元素作为第二个参数传递,就像这样

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

我不必使用像.children()or之类的函数.next()。它也非常有效。

你提到你很难用positioning, 看看这个,它可能会澄清一些事情。


呸,这些长帖子很难阅读,是吗?好吧,我想我已经涵盖了所有需要的东西。

祝你好运,编码愉快!:)

于 2011-12-30T23:48:01.393 回答
1

您可以检查该event.relatedTarget属性以查看它是否是您的函数中的一个.title元素:mouseout

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

演示:http: //jsfiddle.net/ysSJu/1/

还要注意我是如何链接函数调用的,这样您就不必从this.

更新

我注意到,如果您将光标从一个图像移动到另一个图像,则该.title元素不会被删除,因为它应该从前一个图像中删除。您可以通过重置img元素opacity.remove()ing 额外.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/

于 2011-12-30T23:35:32.373 回答
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');
 });

正如您所指出的,原因在于,将鼠标悬停在 alt 上<div>会导致悬停事件不再在外部 img 上触发。然而,在 alt上悬停并mouseenter不会触发.mouseleave<div>mouseleave<img>

于 2011-12-30T23:30:15.610 回答