ux@me Theme 2.0 Released

一. ux@me 简介

ux@me 最开始是我给自己 blog 设计的一套 wordpress 主题, 构建于 wp 3.0.4. 第一版发布于 2011 年 01 月, 但那充其量只是一个”可以使用”的版本, 存在诸多 bug(比如, 在评论时, 如果用户没有输入网址, 也会将系统默认字符串发送到后台, 造成很多虚假链接). 除此之外, 还有很多重要的功能没在 1.0 版本中实现.

但是后来我又懒了下来, 本打算在过年之后升级的新版本, 也一直搞到今天才正式推出. 这里也要多多感谢前端大神, JS 小牛人小如, 如果没有他不断的鞭策和耐心指导, 新版本也不会这么顺利上线.

2.0 里, 新增了一系列我当初构想这个主题时想到的交互功能(具体功能列表见下面的 feature list), 并修改了若干 bug. 所以还算是一个蛮大的升级, 我就直接把版本加到了 2.0(听起来也很响亮啊!), 希望之前有下载过老版本的朋友, 尽可能升级到这个版本.

下载地址: 猛击这里下载

二. ux@me 2.0 Feature list

  1. 新增回复通知功能. 如果在 php.ini 中打开了 mail()功能, 则可以通过邮件通知回复者有了新评论.
  2. 新增左右键翻页功能. 效果和豆瓣的浏览照片功能相似, 当到达最后一页或最前一页时, 会给出相应提示.
  3. 新增进入后台管理页面的快捷键. 因为 wp 3.1 之前都只能通过链接进入后台, 我比较偷懒, 做了一个小功能, 在页面上除输入框之外的任意地方输入”admin”, 就可以进入 wp 后台登录界面.
  4. 重构了 JS 架构, 改进之前的 kbdMgr 对象, 新增了表单验证和 tip 功能.
  5. 优化评论功能, 修正 1.0 版本中的若干 bug.
  6. 增加 avatar 中图片名称的定义说明(预计在下一个小版本改进中将这块做为单独的模块, 无需再直接修改源码)

三. 升级过程中遇到的问题

表单的默认行为

平时对 form 的默认行为研究不多, 这次在改动评论时, 遇到很多问题, 才把 form 的默认行为研究了一下.
首先, form 的默认行为优先级会大于 jquery 提供的 submit() 方法, 如下代码所示:

<form action="http://uxat.me" onsubmit="return false">
    <input type="text" name="test" />
</form>
<script>
    $('form').submit(function() {return true})
</script>

此时如果按下回车不会触发提交事件, 因为 form 的原生事件阻止了提件.

另外, 在今天的项目中, 一个同事也遇见一个关乎 form 表单优先级的问题. 当点击一个 type=”submit” 的 button 时, 也会触发表单的 submit 事件. 此时如果用 JS 来做判断是否提交就需要注意了, 有可能你的 JS 不会起作用:

<script>
    if(aaa < bbb) {return false} else {return true}
</script>

这里我故意用两个未定义的变量 aaa, bbb 来做大小判断. 按理说 JS 会提示错误. 但实际上, 如果点击 submit button 触发 submit 事件, 浏览器会立即提交表单, 甚至都不会报 JS 出错. 这样就会让查找错误变得很困难.

其次, 应该防止多次事件绑定. jQuery 为多个事件提供了一个"命名空间", 但不应滥用它. 我刚开始做键盘事件管理时, 就犯了这个错误, 导致事件处理程序被多次运行. 例如以下代码中:

<a href="#">click me!</a>
<p>here is a prap</p>
<script>
    $('a').click(function() {// 第一次绑定
        $('p').click(function() {alert(1)})
    })
</script>

在 a 的 click 回调函数中再次为一个元素绑定了事件. 这样当多次点击 a 时, 就会为该元素多次绑定事件, 最后导致触发 p 元素的 click 事件时, 会运行多次回调函数.

对象的构建

对于我这种以前没有写过程序, 没有 OO 思维的人来说, 不停的做项目是一个很好的弥补方式. 这次升级过程中, 对于怎么样合理的构建对象, 有了一些新的理解.

首先, 做为对象核心的功能, 应该尽最大可能考虑颗粒化和通用性. 颗粒化即将功能分解成不同的小单元, 然后集中精力解决每个功能单元. 在分割功能单元的时候, 要想清楚单元之间的逻辑和调用关系. 实际上, 颗粒化的目的在于最大限度降低耦合度, 以此使功能做到最大程度的通用性.

这样一来, 在使用的时候就能够做到增减自如了. 比如, 在 2.0 版本中增加的出错抖动功能, 就是做为整个表单验证功能的一个附加功能单元, 在实例化验证功能时可以方便选择是否带上抖动功能. 同时, 该功能也可以很方便的被其它元素调用.

其次, 核心对象一定要简洁, 只提供基本的初始化配置功能即可, 需要扩展出来的功能尽量不要放在核心中去做. 这是另一个层面上的解耦了. 当然, 也只有精简到位, 才能保证功能的通用性. 例如在 2.0 版中的表单验证功能里, 我的核心只提供了 onSuccess, onFaild 等几个状态, 而这些状态对应的判断函数实现就不是核心功能该关心的事了.

再次, 将核心功能(低耦合)和 DOM 操作(高藕合)分离开. 由于我 JS 水平的原因, 现在还做不到对所有功能都解耦. 另外, 在实际的前端项目中, 有些功能实现也确实不需要太在意耦合性. 因此, 我建立了一个 dom.js 来存放这些高耦合的代码. 通过 dom.js 和 core.js, 总算使我的 JS 有一些入门感觉了.

PS, 说到这里, 又不得不提到 JS 框架的一个重要功能 --- 模块依赖管理. 根据吼吼的建议, 学院网站已经开始尝试使用 require.js 来做为 bado 框架的模块依赖解决方案. require.js 是一个略为偏重的模块处理框架, 实际上模块管理只是它的功能之一. 它通过自定义的 define 功能来定义模块, 再用 require 功能来引用, 处理模块. 下面我想抽时间好好研究这一块, 模块处理对性能来说是个关键问题, 可以和豆瓣的 do 框架一起对比着学习, 哈哈.

require.js 的官方地址是: http://requirejs.org/

最后, 在写构造函数时, 要用好 this 属性. 但在 JS 中要用好 this 也不是一件简单的事, 这块后面我会专门写篇日起来记录我对 this 的理解.

好吧, 码字到此为止. 最后发生了一系列事情, 生活, 工作都比较混乱, 导致 blog 很久没更新了. 希望能够尽快处理好, 嘿嘿.

2011-04-17 20:01160