把 HTML 中作为 trigger 的 class name 放到 attribute 里面,会影响效率吗? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a Javascript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
Javascript 权威指南第 5 版
Closure: The Definitive Guide
arbipher
V2EX    Javascript

把 HTML 中作为 trigger 的 class name 放到 attribute 里面,会影响效率吗?

  •  
  •   arbipher 2014-12-08 13:06:12 +08:00 4064 次点击
    这是一个创建于 4034 天前的主题,其中的信息可能已经有所发展或是发生改变。
    比如有个删除按钮:
    <div class='btn btn-danger btn-delete'></div>

    其中btn-delete是给jQuery做选择器用的
    $('.btn-delete').click (...)

    因为class中btn btn-danger是和UI相关的,而btn-delete是和事件处理相关的,
    所以我想把名字改成
    <div class='btn btn-danger trigger-delete'></div>

    此时JS代码为
    $('.trigger-delete').click (...)

    这样从名字就能一目了然看出,那些是和CSS相关,那些是和JS相关。

    我的问题是,如果我把trigger-delete移到attribute里面,改成这样
    <div class='btn btn-danger' data-trigger='delete'></div>

    此时JS代码为
    $('[data-trigger="delete"]').click (...)

    这样class只和CSS有关。

    这种做法可行吗?会有效率或者别的问题?前端小白弱问。
    21 条回复    2014-12-17 14:49:05 +08:00
    boom11235
        1
    boom11235  
       2014-12-08 13:16:05 +08:00
    可行的,只是选择器执行起来效率差点。
    nilennoct
        2
    nilennoct  
       2014-12-08 13:25:14 +08:00
    肯定没有用class快,lz可以考虑用类似J_Delete或T_Delete的类名与css中用的class名区分开
    ZackYang
        3
    ZackYang  
       2014-12-08 13:28:19 +08:00
    带来可维护性和可读性的提高相较于导致性能的损失几乎可以忽略.
    learnshare
        4
    learnshare  
       2014-12-08 13:28:47 +08:00
    最近在思考这个问题:如何用合理的 attr 替代冗长的 class。暂时还没有什么结果出来,有结果再跟你分享一下。
    arbipher
        5
    arbipher  
    OP
       2014-12-08 13:35:01 +08:00
    @boom11235
    @nilennoct
    @ZackYang
    有没有推荐的文章解释选择器执行效率的?


    @learnshare
    tini8
        6
    tini8  
       2014-12-08 13:50:12 +08:00
    这样html代码是变美了,可js代码变丑了:

    $('[data-trigger="delete"]')
    learnshare
        7
    learnshare  
       2014-12-08 14:14:48 +08:00   1
    bsbgong
        8
    bsbgong  
       2014-12-08 14:43:30 +08:00
    跟@ZackYang 的观点一致,这点性能差别可以忽略,代码的可维护性更有价值。
    ZackYang
        9
    ZackYang  
       2014-12-08 15:36:04 +08:00   1
    boom11235
        10
    boom11235  
       2014-12-08 16:30:49 +08:00   1
    @learnshare 这个问题主要是js的选择器性能而不是css吧

    建议:
    css中用class,js的唯一元素挂id,其他的元素选择综合考虑。
    attr和class在现代浏览器中js选择性能差别很小的。
    kmvan
        11
    kmvan  
       2014-12-08 17:10:18 +08:00
    选个class就不用jq吧,直接 selectQuery。
    learnshare data-uid=
        12
    learnshare  
       2014-12-08 17:43:47 +08:00   1
    @boom11235 我认为 JS 选择元素的效率和 CSS 中“一样”,当然不一定是 1:1,但在忽略 JS 和 CSS 执行差异之后,两者执行两个选择器的速度比例应该几乎一样。(浏览器实现的问题,这个不是楼主要关心的重点)


    我同样赞同 @ZackYang 的观点,程序的可读性和可维护性大大提高,一点选择器效率的降低无关紧要。

    我昨天写了这个 demo http://plnkr.co/edit/5BEEsEAdEogibjMyR55b?p=preview ,来尝试找出用 class 和 attr 带来的差异。目前的结果是:自定义的 attr 是非标准的,无法验证,但能够被广泛支持。
    jame
        13
    jame  
       2014-12-08 17:59:40 +08:00 via iPhone   1
    class="btn action" data-trigger="delete"
    $('.action[data-trigger="delete"]')
    这样会更快
    learnshare
        14
    learnshare  
       2014-12-08 18:32:44 +08:00   1
    在 H5 规范里,推荐的是扩展 class 或者 data-* 属性 http://www.w3.org/TR/html5/single-page.html#extensibility

    在 Angular.js 里,使用 ng-* 或者其他任意的属性名来扩展。

    这个 data-* 适合 JS 中存储数据用,而 class 适合为元素扩展样式用。如果想要参考 disabled 这类属性扩展一个 hide(=true/false) 属性,class 和 attr 都可以。

    attr 方式好在简洁易懂,但 data-hide 属性就不如 hide 属性易读。

    我会继续研究这个问题。
    pysama
        15
    pysama  
       2014-12-08 20:05:55 +08:00
    不要在意这些细节,真的~
    fengliu222
        16
    fengliu222  
       2014-12-08 21:01:33 +08:00   2
    @learnshare 这位同学给出的文档,是CSS选择器速度文档,关乎于浏览器渲染页面时的性能,但并非jquery的attribute selector与class selector之间的速度对比。
    http://jsperf.com/jquery-class-vs-attribute-selectors/3
    上面这个地址,歪果仁做了个测试,是关于两种选择器的速度对比的(googleapis这个域名需要翻一下)。
    可以得出,虽然慢了一点,但完全是可以接受的。
    相对于使用data-*带来的可维护性和可读性的收益,那点性能损耗可以忽略。
    spark
        17
    spark  
       2014-12-09 09:22:18 +08:00   1
    楼主可以看看Rails是怎么做的
    spark
        18
    spark  
       2014-12-09 09:36:55 +08:00   1
    arbipher
        19
    arbipher  
    OP
       2014-12-10 01:49:15 +08:00
    感谢大家的回复。

    @ZackYang
    @boom11235
    @fengliu222
    同意你们的观点,“可维护性和可读性的收益”大于“性能损耗”

    @pysama
    确实有点过于细节了。这个问题反复出现,困扰我好久了。。。前几次都忽略,这次终于受不了了

    @tini8
    $('[data-trigger="delete"]')
    这个不丑吧,除去data这个词,trigger和delete用最简单的方法描述了这个函数的类型和作用。

    @kmvan
    selectQuery是DOM API?那选出来的元素,如果再进行其他jQuery操作的话,不是还得转化过去。。。

    @jame
    nice code。只用一个名为action的class name就解决了效率的问题。

    @learnshare
    期待你的研究成果。
    bolasblack
        20
    bolasblack  
       2014-12-17 14:47:42 +08:00   1
    @tini8 @arbipher

    怎么可能会丑……直接扩展 jQuery 的选择器语法不就好了?甚至包装一下 $ 函数,比如如果选择器以 & 开头,就替换为属性选择器:

    $('&delete') -> $('[data-trigger="delete"]')

    这样子难道还丑么?
    bolasblack
        21
    bolasblack  
       2014-12-17 14:49:05 +08:00
    我始终秉持一个观点,在绝大部分开发工作中,可维护性远比效率重要太多了,完全可以牺牲效率还提升可维护性
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3201 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 10:56 PVG 18:56 LAX 02:56 JFK 05:56
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86