几年前,我对HTML属性里写事件处理代码这件事深恶痛绝。那时候这确实是个糟糕透顶的做法。

模块化的出现让onclick变得更难用了。你想调用模块里的代码?几乎不可能,除非你愿意污染全局命名空间。

打开网易新闻 查看精彩图片

但现在我的态度开始软化。转折点在于自定义元素(custom elements)——代码可以安安稳稳待在模块里,同时通过DOM属性被触发。自定义元素成了两者之间的桥梁:

打开网易新闻 查看精彩图片

Click Me!

实际逻辑,也就是doThings方法,仍然独立于DOM的运作,住在单独的模块里。但按钮点击就能触发它,不需要额外的JavaScript来牵线搭桥。DOM本身就是连接元素的纽带,这本就是它的天职。

可惜,Web标准离一个更优雅的方案只差一步之遥:

Click Me!

打开网易新闻 查看精彩图片

这个方案本可以更好:省掉closest()的样板代码,把方法调用换成事件驱动。但它有个硬伤——只能用ID,完全不管DOM的层级关系。

如果可以许愿,我会让commandfor接受CSS选择器,默认当作closest()的参数,除非以#开头。可惜现实不是这样。

所以在当下的世界里,onclick是个相当不错的替代方案,只是稍微啰嗦一点。

补充一点:对于更复杂的场景,我还挺喜欢另一种做法——Click Me!,然后在文档根节点挂一个点击监听器,拦截带x-event属性的按钮点击,派发自定义事件。这样既简化了HTML,又让逻辑与DOM结构保持解耦。