jQuery 优化对悬停事件属性的访问

标签 jquery css animation mouseover css-sprites

我正在使用 CSS Image sprites 在元素上实现滚动效果,鼠标悬停时应用的新类被分配给属性 data-toggle-class 下面是代码(我现在这是微小的性能改进和预优化,这是不好的)

    $("*[data-toggle-class]").hover(function(ev){
        var a = $(this);
        a.toggleClass(a.attr("data-toggle-class"))
    });
  • 如何缓存 data-toggle-class 属性而不是每次悬停时都检索它。
  • 即使我使用 Image sprite,在切换效果发生之前也有小的滞后。这是已知问题吗

最佳答案

我只能回答有关缓存的问题(主要是,请参阅下面分隔符下的注释),您可以使用闭包来做到这一点:

$("*[data-toggle-class]").each(function() {
    var $elm = $(this),
        cls = $elm.attr('data-toggle-class');
    $elm.hover(function() {
        $elm.toggleClass(cls);
    });
});

它的作用是,它不是在悬停事件期间为所有匹配元素调用一个函数,而是为每个元素生成一个单独的函数,其中该函数关闭对元素的 jQuery 包装器的引用及其 data-toggle-class 属性的副本。它以大小为代价(更多功能 = 更多内存,尽管您必须拥有很多才能开始发挥作用)以换取速度。

如果您的目标是让类处于悬停状态而不是悬停状态,我可能会明确地这样做:

$("*[data-toggle-class]").each(function() {
    var $elm = $(this),
        cls = $elm.attr('data-toggle-class');
    $elm.hover(
        // Start hover
        function() {
            $elm.addClass(cls);
        },
        // Stop hover
        function() {
            $elm.removeClass(cls);
        }
    );
});

你说过

I know this is miniature performance improvement and doing pre-optimization which is not good

...但我只想强调这一点。以上将起作用,可能不会导致内存使用过多,并且会导致微小性能增强,但我倾向于认为增强将低于阈值人类感知。


我想知道您是否真的需要这个类和 JavaScript 代码?除非您需要支持 IE6,否则 :hover CSS 伪类正是用于此目的,并且由浏览器本地处理而不是 JavaScript 代码(阅读:更快)。例如:

[data-toggle-class] {
    color: green;
}
[data-toggle-class]:hover {
    color: blue;
}

...将使任何具有 data-toggle-class 属性的元素正常情况下变为绿色,但在悬停时变为蓝色。如果您需要根据属性的 执行不同的操作,您可以这样做:

[data-toggle-class='foo'] {
    color: green;
}
[data-toggle-class='foo']:hover {
    color: blue;
}
[data-toggle-class='bar'] {
    color: black;
}
[data-toggle-class='bar']:hover {
    color: red;
}

带有 data-toggle-class="foo" 的元素通常为绿色,悬停时为蓝色;带有 data-toggle-class="bar" 的通常是黑色的,悬停时是红色的。无需 JavaScript。

上面你理解的color只是一个例子;如果您使用 Sprite ,我希望您使用 backgroundbackground-position


这是 CSS 技术的一个正确示例 ( live copy | source ):

CSS:

.arrow {
    width: 40px;
    height: 40px;
    background-image: url(http://cdn.sstatic.net/stackoverflow/img/sprites.png);
    background-repeat: none;
    display: inline-block;
}
.style1 {
    background-position: 0px -220px;
}
.style1:hover {
    background-position: 0px -320px;
}
.style2 {
    background-position: 0px -260px;
}
.style2:hover {
    background-position: 0px -290px;
}

HTML:

<div class="arrow style1"></div>
<div class="arrow style2"></div>

请注意如何在没有 JavaScript 的情况下以声明方式轻松控制显示哪个箭头。现在,当然,如果你的箭头应该出现的条件比这更复杂,你可能不得不去 JS。我只是说,对于大多数简单的悬停操作,不需要它。

关于jQuery 优化对悬停事件属性的访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9902748/

相关文章:

javascript - 设置动画速度 - ChartJS?

jquery - CSS 过渡是从左到右而不是从右到左

javascript - jQuery 加载(ajax)文件内容外部脚本出现错误 XMLHttpRequest 已弃用

javascript - jquery slidetoggle 不适用于 div、ul 和显示 : none

javascript - 边界线动画

javascript - 如何改变 body 等级

html - 是什么导致了这种(黑白和模糊)效果?

javascript - 文档加载完成后如何显示收件箱区域?

css - 将 CSS 重置为默认状态

html - SVG 微调器不在 Origin 上旋转