【问题标题】:jQuery radio buttons with toggle/remove class mystery带有切换/删除类之谜的 jQuery 单选按钮
【发布时间】:2014-01-09 15:05:46
【问题描述】:

jQuery 有问题,但我不知道为什么。

我有三个像单选按钮一样的 div。第一个 div 有“on”类,其他 div 有“off”类。如果我单击“关闭”类,它会更改为“打开”,但这不适用于第一个 div,因为我无法将其转回“打开”。仅当他从一开始就“关闭”课程时才有效。你能告诉我问题出在哪里吗?

HTML:

<div class="slider-radio-buttons">
                    <div class="on"></div>
                    <div class="off"></div>
                    <div class="off"></div>
                </div>

jQuery:

$(".off").click(function() {
    $(".on").removeClass('on').toggleClass('off');
    $(this).toggleClass('on').removeClass('off');
});

http://jsfiddle.net/UyKzf/2/

【问题讨论】:

    标签: jquery class radio-button switch-statement


    【解决方案1】:

    由于关于代码优化(仅在用户界面速度下使用)已经进行了一些(冗长的)讨论,我会反驳说,以下是更快和更简单:

    http://jsfiddle.net/TGc7L/2/

    $("div.slider-radio-buttons div").on("click", function () 
    {
        $(this).removeClass("off").addClass("on").siblings().removeClass("on").addClass("off");
    });
    

    选择器只使用一次。所有其他访问要么是对已知目标元素(使用$(this)),要么是对那个元素的兄弟姐妹,(我相信)可以使用siblings() 更快地访问。

    http://jsperf.com/cached-vs-siblings/3

    *注意:由于对统计数据持怀疑态度,我通过排除最初的 jQuery 选择器将性能测试变成了公平的比较。使用siblings() 似乎比迭代一个 JQuery 集合(在 Chrome 中)要快一点,并且在其他浏览器上的速度大致相同,这很容易知道。

    我最初的观点基本上是“不要担心用户界面交互的速度,除非有问题”。无论如何,我都会使用上述技术,因为它更易于阅读/维护。你可以多快点击鼠标?当然不是每秒 90,000 次 :)

    【讨论】:

    • +1 表示备用尝试。但是,对我来说,这似乎会更慢,因为您每次点击都会调用siblings(),而我使用的方法是预先缓存所有 div 并且只调用一次。
    • @Code Maverick:现在你正在得出结论......兄弟姐妹“可以”更快地运行,因为它可以横向遍历 DOM(因为 DOM 已经在兄弟姐妹之间链接)。当我们依赖其他人编写的 JQuery 代码时,我们再次在速度的前沿争论。我更喜欢这种简单性,但我期待您的性能计时结果:)
    • 我决定运行jsPerf test。它们在 Chrome 和 Firefox 中非常接近且几乎完全相同。我的在 IE 中稍快。
    • @Code Maverick:因为它们非常接近,速度方面,而且每次鼠标点击只执行一次(每秒最多 5 次?)我想我已经表达了我的观点。在维护过其他人的 JQuery 代码后,我总是更喜欢可读性、可维护性和简单性除非速度是一个实际问题 :)
    • 实际上,我设置了测试错误。我应该把我的缓存变量放在设置区域,而不是放在测试用例中。完成后,我的速度最快。我还包括了非缓存接受的答案,它排在第二位,你的排在最后。
    【解决方案2】:

    这是因为第一个 div 在调用 $('.off').click 时具有“on”类。所以,jQuery 没有将事件绑定到它。

    您可以将事件绑定为:

    $(".slider-radio-buttons").on('click', '.off', function() {
        $(".on").removeClass('on').toggleClass('off');
        $(this).toggleClass('on').removeClass('off');
    });
    

    见小提琴:http://jsfiddle.net/UyKzf/5/

    【讨论】:

    • +1 a) 首先进入 b) 使用延迟的on 进行事件处理。
    • @TrueBlueAussie - 我认为我的答案(也是第一个,我们同时回答)稍微好一些,因为我使用缓存变量优化了代码。只是我的 2 美分。
    • @Code Maverick:Andre 的帖子早于 19 秒(悬停在 "answered ... ago" 文本上以获取准确时间)。至于优化:“除非重要,否则不要优化”。此功能只需以用户点击速度运行,因此任何速度差异都不是问题:)
    • @TrueBlueAussie - 在重要之前,您永远不知道优化何时重要,因此您应该始终优化您的代码。一般来说,不缓存变量只是一种不好的做法。
    • @Code Maverick:我同意它可以被优化(JQuery 选择器有很多需要回答,时间方面),但至于 when 这很重要,这里的线索在“点击”中。出于更好的理由,我已经对你的答案投了赞成票:)
    【解决方案3】:
    $(".off, .on").click(function() {
        if( $(this).hasClass('off'))
        {
            $(".on").toggleClass('on off');
            $(this).toggleClass('on off');       
        }
    
    });
    

    小提琴:http://jsfiddle.net/UyKzf/7/

    为以后的查看者编辑:

    [有用]这个答案不是很好,因为(见 TrueBlueAussie 评论)

    【讨论】:

    • 太棒了!十分感谢大家。 :)
    • ^^ 你有很多答案,只需要选择接受哪个答案,辛苦了...
    • Andre 作为更好的答案,因为正如 TrueBlueAussie 所说,他使用 'on' 。我也选这个。
    • @Jahnux73:如果一个元素已经处于on 状态,则您的if 语句是不必要的。完全依赖初始状态更容易出现错误(因此不推荐)。显式删除/添加比切换所有元素的状态更好。
    • @TrueBlueAussie 我对你没意见,但这方面没有被提及(但这不是我同意的原因^^)
    【解决方案4】:

    最简单的做法是将它们全部关闭,然后简单地打开被点击的那个。

    See working jsFiddle demo


    HTML

    <div class="slider-radio-buttons">
        <div class="on">Choice 1</div>
        <div class="off">Choice 2</div>
        <div class="off">Choice 3</div>
    </div>
    


    jQuery

    ​​>
    var $buttons = $("div.slider-radio-buttons div");
    
    $buttons.on("click", function () 
    {
        $buttons.removeClass("on").addClass("off");
        $(this).removeClass("off").addClass("on");
    });
    


    CSS

    .off 
    {
        opacity: 0.7;
        background: #FFE3B3;
        -webkit-transition: all 0.3s ease-out;
        -moz-transition: all 0.3s ease-out;
        -ms-transition: all 0.3s ease-out;
        -o-transition: all 0.3s ease-out;
        transition: all 0.3s ease-out;
    }
    .off:hover 
    {
        opacity: 1;
    }
    .on 
    {
        background: #FFA200;
    }
    


    由于已经讨论过哪种答案更快或更有效,我想我会进行性能测试。缓存 vs 兄弟 vs 非缓存。

    See jsPerf test results

    See jsPerf revision test results

    【讨论】:

    • 鉴于我们长时间的讨论(以及我认为总是有更好的方法),我也发布了我自己的优化版本,供您查看。干杯。
    • @TrueBlueAussie - 我已经添加了在 3 个浏览器上测试的修订测试结果,而不仅仅是一个,我的仍然是最快的。
    猜你喜欢
    • 1970-01-01
    • 2020-05-20
    • 1970-01-01
    • 2011-11-10
    • 2012-01-08
    • 1970-01-01
    • 2015-02-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多