我最近问了一个问题,当你将鼠标悬停在图像中心时,会将图像的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/
感谢您的支持。
答案 0 :(得分: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');
});
});
不是在每个mouseenter/mouseleave
创建和销毁div,而是在document.ready()
生成div一次更好,并在用户将鼠标悬停在它们上时显示/隐藏它们。
它实际上应该会提高整体表现。
默认情况下,.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
,have a look at this,这可能会澄清事情。
答案 1 :(得分:1)
您可以查看event.relatedTarget
媒体资源,了解它是.title
功能中的mouseout
元素:
function(event){
if (!$(event.relatedTarget).hasClass('title')) {
$(this).css('opacity','1').siblings().remove();
}
}
演示:http://jsfiddle.net/ysSJu/1/
另请注意我如何链接函数调用,因此您不必从this
创建两个jQuery对象。
<强>更新强>
我注意到,如果将光标从一个图像移动到另一个图像,则.title
元素将不会被删除,因为它应该来自上一个图像。您可以通过重置img
元素的opacity
和.remove()
额外.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');
}
}
);
答案 2 :(得分: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上触发。但是,当mouseenter
和mouseleave
悬停在alt <div>
上时,不会触发mouseleave
的{{1}}。