我最近问了一个问题,当你将鼠标悬停在图片上时,图片的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;
}我试过使用和不使用内联块,结果是一样的,但是标签的位置需要不同。
你知道为什么会发生这种情况吗?
下面是这个问题的一个例子:http://jsfiddle.net/ysSJu/
感谢您的支持。
发布于 2011-12-31 07:48:01
解释
当您将鼠标悬停在标题上时,效果消失的原因是您只有img元素的事件。
相反,您应该将事件“链接”到整个li,这样当用户将鼠标悬停在列表项上时,包括div.title在内的整个元素都会受到影响。

在上图中,您可以看到它是如何工作的。
目前,您已将事件链接到对应于绿色、img的事件。这意味着黄色的div.title将被视为“外部”元素(因为div.title不在img元素内),因此当您将鼠标悬停在div.title上时将触发mouseleave事件。
如果将事件链接到红色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');
});
});替代解决方案
与其在每个mouseenter/mouseleave上创建和销毁一个div,不如在document.ready()上只生成一次div,并在用户将鼠标悬停在它们上时显示/隐藏它们。
实际上,它应该会提高整体性能。
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。Hover实际上是这两个事件组合在一起的速记函数。我倾向于使用前者,因为它通常更容易阅读,也更可靠。
还要注意,在这两个解决方案中,我都使用了函数.each()。通过将元素赋值给变量,JQuery不必在每次引用节点时都浪费更多的处理时间来查找它们;这使得它更加高效。
通过在选择器中传递一个元素作为第二个参数,如下所示
$(".title", parent_element).css(...);我不需要使用像.children()或.next()这样的函数。它也是非常高效的。
你提到过你在使用position时遇到了困难,have a look at this,它可能会澄清一些事情。
嘿,这些长长的帖子很难读,是吧?嗯,我想我已经满足了所有的需要。
祝你好运,编码愉快!:)
发布于 2011-12-31 07:35:32
您可以检查event.relatedTarget属性,以查看它是否为mouseout函数中的.title元素:
function(event){
if (!$(event.relatedTarget).hasClass('title')) {
$(this).css('opacity','1').siblings().remove();
}
}演示:http://jsfiddle.net/ysSJu/1/
还要注意我是如何链接函数调用的,这样您就不必从this创建两个jQuery对象。
更新
我注意到,如果您将光标从一个图像移动到另一个图像,.title元素将不会像从前一个图像中那样被删除。您可以通过重置img元素的opacity并对额外的.title元素执行.remove()来修复此问题:
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-31 07:30:16
更改.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上触发。然而,当mouseenter和mouseleave悬停在alt上时,<div>不会触发<img>的mouseleave。
https://stackoverflow.com/questions/8684977
复制相似问题