优化 jQuery 悬停代码以更好地执行(更流畅的动画)

Posted

技术标签:

【中文标题】优化 jQuery 悬停代码以更好地执行(更流畅的动画)【英文标题】:Optimize jQuery hover code to perform better (smoother animation) 【发布时间】:2010-12-04 13:24:56 【问题描述】:

最近我一直在阅读有关 jQuery 优化技巧的文章,这些技巧确实有助于提高我的脚本的性能。

但是,我在我的网站上有这个精选新闻部分,鼠标悬停时可以将更多信息滑入适当的位置,并且该部分在除 Safari 之外的任何浏览器中都表现不佳(那么可能还有 Chrome。)

我相信这样做的原因是它在动画之前对每个 mouseover/mouseout 事件进行了相当多的 DOM 遍历和计算。

我的问题很简单:有没有办法优化下面的代码,让动画运行更流畅?

$('#featuredSide .featuredBox,#featuredBottom .featuredBox,#archiveVideos .featuredBox').hover(function() 
var boxHeight = parseInt($(this).css('height'))-8;
var bottomOrSide = $(this).parents("div[id^='featured']").attr("id")
var captionPos = 76;
var captionHeight = parseInt($(this).find(".videoCaption").css('height'));
var animateTo = boxHeight-captionHeight;

$(".videoCaption", this).stop().animate(top:animateTo + 'px',queue:false,duration:160);
, function() 
$(".videoCaption", this).stop().animate(top:captionPos,queue:false,duration:100);
);

由于我正在开发的网站尚未发布,我已经uploaded a screenshot of the news section 让您了解它的外观。

谢谢!

【问题讨论】:

【参考方案1】:

另一种解决方案是memoize all 计算。

不要直接调用hover,使用“each”,计算,然后应用“hover”。 因此(我试图尽可能少地更改代码):

$('#featuredSide .featuredBox,#featuredBottom .featuredBox,#archiveVideos .featuredBox').each(function() 
  var boxHeight = parseInt($(this).css('height'))-8;
  var bottomOrSide = $(this).parents("div[id^='featured']").attr("id")
  var captionPos = 76;
  var captionHeight = parseInt($(this).find(".videoCaption").css('height'));
  var animateTo = boxHeight-captionHeight;

  var params = top:animateTo + 'px';
  var options = queue:false,duration:160;
  var target = $(".videoCaption", this);

  $(this).hover(function () 
    target.stop().animate(params, options);
  );

这个解决方案会使我之前的回答变得毫无意义(它们并不重要,尽管仍然适用)。不过,请记住配置文件。

【讨论】:

这是一个非常优雅的解决方案。我当然会尝试看看它是否会在性能方面产生更好的结果。谢谢 - 再次!【参考方案2】:

对于初学者,可以使用Common subexpression elimination,例如,而不是调用

$(this)

多次,将该对象存储在一个变量中,然后使用该变量。

var current = $(this);

另一方面,可以内联一次性使用的变量。 有些人可能会称它们为过早优化,但既然已经说明代码很慢,我认为这还不算过早。

bottomOrSide 变量似乎没有在那里使用。

至于选择器,可以把整个长的东西都换成这个吗?

$('.featuredBox')

【讨论】:

在我的小脑袋里,我想象我的选择器会因为限制范围而更快,但这可能不适用于这种特殊情况? 我希望一个简单的 .featuredBox 选择器在这种情况下执行得更快 - 但是,一如既往,如果你想知道的话,benchmark它! 顺便说一句,那个特定的选择器不会减慢你的悬停动画;选择器似乎只执行一次。 @Alex Barrett:是的,我想最后一个不是那么重要。另一方面,指定 ID 和类似乎是多余的,它们都需要吗? 谢谢Alex,我试试看我朋友FireBug能否对选择器问题给出明确的答案:-)【参考方案3】:

你重复做一些工作,这会伤害你。多少很难说,但试试这个...

var el = $(this);
var vid = $(".videoCaption", this);
// use el.blar() instead of $(this) and vid.blar() instead of $(".videoCaption", this).blar()

看起来您的 dom 结构在使用此面板的所有不同位置都必须不同,因为您的代码似乎必须做大量工作才能找到要使用的适当 dom 位。如果可能,我建议在所有不同位置使 DOM 结构相同,然后在代码中使用该结构。

如果这不可能,请尝试为每个位置编写此函数的唯一版本 - 不理想,但如果它解决了您的性能问题,那可能是值得的。

【讨论】:

很好的建议——谢谢!相关后续问题:自从使用 jQuery 开始,我一直想知道在动画上提供更短或更长的持续时间是否会对速度和性能产生任何影响。这个有固定的答案吗? fadeOut("fast") 会比 fadeOut("slow") 快还是慢? 我不这么认为。在这两种情况下,我认为它将更新元素的不透明度并以浏览器允许的速度刷新页面。更快的浏览器只会挤进更多的步骤,从而产生更流畅的动画。

以上是关于优化 jQuery 悬停代码以更好地执行(更流畅的动画)的主要内容,如果未能解决你的问题,请参考以下文章

jquery性能优化的十种方法

悬停时的Jquery动画子菜单不流畅

如何用VB.NET StringBuilder优化字符串操作性能

如何优化 mp4 视频以在浏览器中尽可能流畅地播放 (HTML5)

在悬停时调用元素上的函数(没有唯一的id)

哪个jQuery选择器可以更好地优化多个元素