我正在尝试获取99designs将鼠标悬停在设计上时获得的图像效果。[99designs.ca] Logo design contest: Runningbug Needs Logo 220626
我目前正在鼠标移动中获取鼠标的位置,然后使用它移动我的popover <img>
,一切正常,但它非常滞后...并且可能是它的来自如此多的电话。
获取鼠标的位置:
jQuery(document).ready(function(){
//$("#special").click(function(e){
$(".imgWrap").mousemove(function(e){
//$('#status2').html(e.pageX +', '+ e.pageY);
//alert(e.pageX + ', ' + e.pageY);
mouseX = e.pageX;
mouseY = e.pageY;
});
})
我不确定我能做到的另一种方式......任何想法?
关于完整的事件过程如下:
<img>
标记还调用js函数,该函数将img标记的位置更改为鼠标的位置。实际上,您可以在此处查看:pokemonsite
更新:我看到有一个赏金(谢谢!)。我现在有点忙,无法检查所有其他答案,但我会确保尽快检查
答案 0 :(得分:2)
使用mousemove事件时,有几种方法可以提高性能。
在popover元素上使用backface-visibility: hidden
来强制加速硬件。同样的事情可以通过transform: translate3d(0,0,0)
获得,但这使得使用CSS transform
函数变得困难(参见第2点)。
使用CSS transform
函数进行绝对定位以避免重新绘制,但保持popover元素绝对定位或固定定位。
通过JS设置内联CSS时,请使用requestAnimationFrame以避免不必要的布局垃圾。
(可选,可选)在悬停时隐藏光标,并使用popover元素作为位置指示符。
将所有可能的东西从JS移到CSS即。 :hover
状态可用于切换popover元素的显示。
我制作了结合列出的所有内容的演示示例。光标位置和弹出窗口图像之间仍然存在一些延迟,原始问题中的示例链接都没有工作,所以我无法与之进行比较,但我希望有人认为这很有用。
<强> DEMO 强>
<div id="imgHolder" class="imgHolder">
<img src="//placehold.it/200x200" alt="" />
</div>
<div id="bigImgHolder" class="imgHover">
<img src="//placehold.it/500x500" alt="" />
</div>
.imgHover {
display: none;
backface-visibility: hidden;
position: fixed;
top: 0; left: 0;
pointer-events: none;
}
.imgHolder:hover ~ .imgHover { display: block; }
// uncomment if it makes sense
//.imgHolder:hover { cursor: none; }
var posX, posY;
$('#imgHolder').mousemove(HoverImg);
function HoverImg(e) {
posX = e.pageX;
posY = e.pageY;
window.requestAnimationFrame(showBigImg);
}
function showBigImg() {
$('#bigImgHolder').css({'-webkit-transform': 'translateX(' + posX + 'px) translateY(' + posY + 'px)', 'transform': 'translateX(' + posX + 'px) translateY(' + posY + 'px)' });
}
的引用:
答案 1 :(得分:1)
如果绝对(x,y)位置不那么重要(意思是:在不破坏逻辑的情况下可以省略一些像素值),你可以尝试跳过mousemove-event的一些帧。
var globalSkipCounter = 0;
var globalSkipRate = 5;
$(".imgWrap").mousemove(function(e){
if(globalSkipCounter >= globalSkipRate){
var mouseX = e.pageX;
var mouseY = e.pageY;
do_stuff(mouseX, mouseY);
globalSkipCounter = 0;
}
else{
globalSkipCounter+=1;
}
});
这样,您可以省略在每次mousemove事件上重绘图像,而只调用draw-routine(do_stuff
),每5个事件一次。
答案 2 :(得分:1)
使用e.offsetX
和e.offsetY
或(推荐)e.clientX
和e.clientY
代替pageX和pageY。也许这将是一个更好的解决方案。注意:据我所知,offsetx
和offsety
在Firefox中不起作用。
答案 3 :(得分:1)
试试这个:
jQuery(document).ready(function(){
$(".imgWrap").mousemove(function(e){
e.stopPropagation();
mouseX = e.pageX;
mouseY = e.pageY;
});
})
答案 4 :(得分:1)
缓存位置并将更新包装在if(oldpos !== newpos)
类型检查中(记住更新其中的oldpos)。
使用requestAnimationFrame
来处理更新 - 如果你有一个正常的函数并将其作为回调传递,那么每帧只调用一次(即不使用匿名函数)。
最后使用transform:translate(x,y)
设置位置并更好地利用GPU等。与此相关,如果你想使用top,那么使用css will-change
关键字是没有害处的/而是改为。
答案 5 :(得分:0)
尝试基于每秒最大事件的方法:
jQuery(document).ready(function(){
var now, then, delta, interval = 1000/60; //maximum 60 eps, you can change
//$("#special").click(function(e){
$(".imgWrap").mousemove(function(e){
now = Date.now();
delta = now - then;
if (delta > interval) {
then = now - delta % interval; //subtract extra waited time
//$('#status2').html(e.pageX +', '+ e.pageY);
//alert(e.pageX + ', ' + e.pageY);
mouseX = e.pageX;
mouseY = e.pageY;
// do your thing
}
});
})
编辑:不知道javascript中是一个保留字,你可以重命名。
答案 6 :(得分:0)
我有一个可排序的 angular 列表视图,但是在 chrome 中使用鼠标拖动项目滞后很多。我尝试禁用所有 chrome 扩展程序,现在延迟完全消失了。
事实证明是 TamperMonkey 造成的。