我有一个脚本,当您将鼠标悬停在缩略图上时,可以动态地添加完整图像。我还给出了完整的图像CSS:悬停样式,使它们扩展到更大的宽度(通常它们被约束到缩略图的尺寸)。如果图像快速加载或缓存,这样可以正常工作,但是如果完整图像需要很长时间才能加载,并且在加载时不移动鼠标,那么一旦它出现,它通常会保持缩略图宽度(非:悬停样式),直到再次移动鼠标。我在所有尝试过的浏览器中都会遇到这种情况。我想知道这是不是一个错误,如果有办法修复或解决它。
值得注意的是,我也试图在.on('mouseenter')
的Javascript中做同样的事情,并遇到了同样的问题。
由于问题的性质,可能很难重现,特别是如果您有快速连接。我从维基百科中选择了一张较大的照片进行演示,但要使其工作,您可能需要将其更改为特别大的或慢速域。另请注意,您可能必须清除缓存以进行连续重试。
如果仍然无法重现,可以在致电fullimage.load
之前向anchor.show()
添加人为延迟。
HTML:
<img id="image" src="http://upload.wikimedia.org/wikipedia/commons/thumb/3/32/Cairo_International_Stadium.jpg/220px-Cairo_International_Stadium.jpg" />
CSS:
.kiyuras-image {
position: absolute;
top: 8px;
left: 8px;
max-width: 220px;
}
.kiyuras-image:hover {
max-width: 400px;
}
JS:
$(function () {
var fullimageurl = 'http://upload.wikimedia.org/wikipedia/commons/3/32/Cairo_International_Stadium.jpg';
var fullimage = $('<img/>')
.addClass('kiyuras-image')
.load(function () {
anchor.show();
});
var anchor = $('<a/>').hide().append(fullimage);
$('body').prepend(anchor);
$("#image").on('mouseenter', function () {
fullimage.attr('src',fullimageurl);
$(this).off('mouseenter');
});
});
Updated JS Bin with 1.5-second delay added (Hopefully makes issue clearer)
再次:重现问题包括清除大图像的缓存,然后将鼠标悬停在原始图像上以初始加载大图像,然后在加载时不移动鼠标。预期的行为是大图像在最终加载时正确地使用:hover伪类。问题我发现当加载时间超过0.75秒时它不会占用:在你轻轻摇晃鼠标之前将其悬停。
编辑:有关我的用例的详细信息,请参阅我对@ LucaFagioli答案的评论。
编辑,续集:我以为我已经这样做了,但我只是试图在Firefox中重现这个问题而我却做不到。也许这是一个Chrome bug?
答案 0 :(得分:7)
大多数浏览器仅在光标在元素上移动至少一个像素时才更新其hover
个状态。当光标进入缩略图的img
时,它会应用hover
并运行您的mouseenter
处理程序。如果您将光标保持不变直到加载完整尺寸的图片,那么旧的img
(缩略图)将保持hover
状态,新的状态将无法获得。
要使它在这些浏览器中运行,请将hover
伪类移动到CSS中的公共父元素;例如,enclose both img
s in a span
。
答案 1 :(得分:2)
如果选择器正确,CSS将应用于所有元素,动态或其他。这包括所有伪类,并且会随着DOM中的属性发生变化而改变。
答案 2 :(得分:1)
[编辑:虽然我的解释可能很有意思,pozs' solution above更好,所以如果可以的话,我建议使用它。]
hover
伪类规范是quite relaxed,关于何时应该激活它:
CSS没有定义哪些元素可能处于上述状态, 或状态如何进入和离开。脚本可能会改变 元素是否对用户事件做出反应,并且不同 设备和UA可能有不同的指向方式,或 激活元素。
特别是,当您在加载时更新锚元素的可见性时,它不会被激活。
你可以相当容易地解决这个问题:将hover
样式复制到一个类,拦截光标移动到它最终会覆盖的元素上,并根据该元素从元素中添加或删除你的类。 / p>
演示: JS Bin (based on your delayed example)。
<强>使用Javascript:强>
$("#image")
.on('mouseenter', function () {
fullimage.attr('src',fullimageurl).toggleClass('mouseover', true);
$(this).off('mouseenter');
})
.mouseleave(function() {
fullimage.toggleClass('mouseover', false);
});
<强> CSS:强>
.kiyuras-image:hover, .kiyuras-image.mouseover {
max-width: 400px;
}
答案 3 :(得分:0)
从你的问题的这一部分:“如果图像快速加载或缓存,这可以正常工作,但如果完整的图像需要很长时间才能加载,并且在加载时不移动鼠标,”
首先使用JavaScript“预加载”所有图像是否值得。这可能允许所有图像首先成功加载,对于连接速度较慢的人来说,它可能更友好一些。
答案 4 :(得分:0)
您可以这样做:http://jsfiddle.net/jR5Ba/5/
总之,在图片前添加加载布局,然后附加包含大图像的div,其中包含.load()
回调以移除加载图层。
由于时间不够,上面的小提琴没有被简化和清理,但如果需要的话,我可以在明天继续工作。
$imageContainer = $("#image-container");
$image = $('#image');
$imageContainer.on({
mouseenter: function (event) {
//Add a loading class
$imageContainer.addClass('loading');
$image.css('opacity',0.5);
//Insert div (for styling) containing large image
$(this).append('<div><img class="hidden large-image-container" id="'+this.id+'-large" src="'+fullimageurl+'" /></div>');
//Append large image load callback
$('#'+this.id+'-large').load(function() {
$imageContainer.removeClass('loading');
$image.css('opacity',1);
$(this).slideDown('slow');
//alert ("The image has loaded!");
});
},
mouseleave: function (event) {
//Remove loading class
$imageContainer.removeClass('loading');
//Remove div with large image
$('#'+this.id+'-large').remove();
$image.css('opacity',1);
}
});
修改强>
这是小提琴的新版本,包括正确大小的加载图层,当显示大图片时带有动画:http://jsfiddle.net/jR5Ba/6/
希望它会有所帮助
答案 5 :(得分:0)
在有要下载的图像之前,不要让IMG标记添加到DOM。这样,在加载图像之前,Load事件不会触发。这是修改后的JS:
$(function () {
var fullimageurl = 'http://upload.wikimedia.org/wikipedia/commons/3/32/Cairo_International_Stadium.jpg';
var fullimage = $('<img/>')
.addClass('kiyuras-image')
.load(function () {
anchor.show(); // Only happens after IMG src has loaded
});
var anchor = $('<a/>').hide();
$('body').prepend(anchor);
$("#image").on('mouseenter', function () {
fullimage.attr('src',fullimageurl); // IMG has source
$(this).off('mouseenter');
anchor.append(fullimage); // Append IMG to DOM now.
});
});
答案 6 :(得分:0)
我不是100%确定为什么:hover
声明仅在轻微鼠标移动时触发。一个可能的原因可能是技术上你可能没有悬停元素。基本上你正在加载光标下的元素(直到大图像被完全加载,A
元素有display: none
,因此不可能处于:hover
状态。与此同时,这并没有解释与较小图像的差异......
因此,一种解决方法是仅使用JavaScript并将:hover
语句排除在等式之外。只需向用户显示两个不同的IMG
元素,具体取决于悬停状态(在JavaScript中切换)。作为额外的优势,图像不必由浏览器动态地放大和缩小(Chrome中的视觉故障)。
请参阅http://jsbin.com/ifitep/34/
更新:通过使用JavaScript在大图片上添加.active
类,完全可以继续使用原生CSS动画。见http://jsbin.com/ifitep/48
答案 7 :(得分:0)
我做到了,它适用于Chrome(版本22.0.1229.94 m): 我改变了css:
.kiyuras-image{
position: absolute;
top: 8px;
left: 8px;
max-width: 400px;
}
.not-hovered{
max-width: 220px;
}
和脚本这样:
$(function(){
var fullimageurl = 'http://upload.wikimedia.org/wikipedia/commons/3/32/Cairo_International_Stadium.jpg';
var fullimage = $('<img/>')
.addClass('kiyuras-image')
.load(function () {
anchor.show();
});
var anchor = $('<a/>').hide().append(fullimage);
$('body').prepend(anchor);
$('.kiyuras-image').on('mouseout',function(){
$(this).addClass('not-hovered');
});
$('.kiyuras-image').on('mouseover',function(){
$(this).removeClass('not-hovered');
});
$("#image").one('mouseover', function(){
fullimage.attr('src',fullimageurl);
});
});
基本上我认为检测/渲染'悬停'状态是Chrome错误;事实上当我试图简单地将css更改为:
.kiyuras-image{
position: absolute;
top: 8px;
left: 8px;
max-width: 400px;
}
.kiyuras-image:not(:hover) {
position: absolute;
top: 8px;
left: 8px;
max-width: 220px;
}
它仍然无效。
PS:对不起我的英语。