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

2014-12-08 13:06:12 +08:00
 arbipher
比如有个删除按钮:
<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有关。

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


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

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

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


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

我昨天写了这个 demo http://plnkr.co/edit/5BEEsEAdEogibjMyR55b?p=preview ,来尝试找出用 class 和 attr 带来的差异。目前的结果是:自定义的 attr 是非标准的,无法验证,但能够被广泛支持。
jame
2014-12-08 17:59:40 +08:00
class="btn action" data-trigger="delete"
$('.action[data-trigger="delete"]')
这样会更快
learnshare
2014-12-08 18:32:44 +08:00
在 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
2014-12-08 20:05:55 +08:00
不要在意这些细节,真的~
fengliu222
2014-12-08 21:01:33 +08:00
@learnshare 这位同学给出的文档,是CSS选择器速度文档,关乎于浏览器渲染页面时的性能,但并非jquery的attribute selector与class selector之间的速度对比。
http://jsperf.com/jquery-class-vs-attribute-selectors/3
上面这个地址,歪果仁做了个测试,是关于两种选择器的速度对比的(googleapis这个域名需要翻一下)。
可以得出,虽然慢了一点,但完全是可以接受的。
相对于使用data-*带来的可维护性和可读性的收益,那点性能损耗可以忽略。
spark
2014-12-09 09:22:18 +08:00
楼主可以看看Rails是怎么做的
spark
2014-12-09 09:36:55 +08:00
arbipher
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
2014-12-17 14:47:42 +08:00
@tini8 @arbipher

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

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

这样子难道还丑么?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/152325

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX