【问题标题】:jQuery optimizing access to attributes for hover eventjQuery优化对悬停事件属性的访问
【发布时间】:2012-03-28 07:12:05
【问题描述】:

我正在使用 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,在切换效果发生之前也会有小的延迟。这是已知问题吗

【问题讨论】:

    标签: jquery css animation mouseover css-sprites


    【解决方案1】:

    我只能回答关于缓存的问题(大多数情况下,请参阅下面分隔符下的注释),您可以使用闭包来解决:

    $("*[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);
            }
        );
    });
    

    你说过

    我知道这是微小的性能改进,但做预优化并不好

    ...但我只想强调这一点。以上可行,可能不会造成过多的内存使用,并且会带来微小的性能提升,但我倾向于认为提升会低于人类感知。


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

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

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

    [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只是一个例子;如果您使用精灵,我希望您使用 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。我只是说,对于大多数简单的悬停操作,不需要它。

    【讨论】:

    • :hover 的问题在于,它不适合我在这里设置的方式,例如我在一个元素上获得了右箭头(css sprite image)并且我想悬停在其悬停图像(又是一个 css 精灵)这将在 css .right-arrow{} .right-arrow:hover{background-position:something} 中生成如下代码,但我实际上得到了这个 right-arrow{} right-arrow-hover{} 以便我可以将 right-arrow-hover 应用于任何元素,而不管它的状态如何。这样我就可以编写如下代码/*display red arrow on hover*/right-arrow:hover{background-position:red-arrow-position}
    • 抱歉评论太长了,我不得不拆分引用 - 这使得所有右箭头在悬停时显示红色箭头。通过这种 javascript 方式,我可以自定义在悬停事件期间显示哪个箭头
    • @Deeptechtons:是的,但是您可以完全使用 CSS 和标记来做到这一点。如果您在hover 中所做的只是添加一个类,那么无论如何您已经在使用 CSS 进行所有样式设置。我在答案中添加了一个完整的精灵示例。显然,选择最适合您的方法。
    猜你喜欢
    • 2011-04-16
    • 1970-01-01
    • 2023-04-10
    • 2011-02-12
    • 2015-03-23
    • 2011-11-09
    • 1970-01-01
    • 1970-01-01
    • 2019-02-07
    相关资源
    最近更新 更多