我正在编写一个 JS webapp 客户端。用户可以编辑文本项目的列表/树(例如,待办事项列表或注释)。我经常用 jQuery 操作 DOM。
用户可以使用键盘上下导航列表(类似于 GMail 中的 J/K 键),并执行其他一些操作。其中许多操作具有镜像“向上”/“向下”功能,例如
$.fn.moveItemUp = function() {
var prev = this.getPreviousItem();
prev && this.insertBefore(prev);
// there's a bit more code in here, but the idea is pretty simple,
// i.e. move the item up if there's a previous item in the list
}
$.fn.moveItemDown = function() {
var next = this.getNextItem();
next && this.insertAfter(next);
// ....
}
现在,这种具有两个几乎相同功能的模式在我的代码中的多个位置重复出现,因为项目列表/树上有许多非常对称的操作。
问题:我如何优雅地重构它以避免代码重复?
到目前为止,我想出的最简单的方法是使用 .apply() ...
$.fn.moveItem = function(direction) {
var up = direction === 'up',
sibling = up ? this.getPreviousItem() : this.getNextItem(),
func = up ? $.fn.insertBefore : $.fn.insertAfter;
// ...
if (! sibling) { return false; }
func.apply(this, [ sibling ]);
// ...
};
当代码的其他元素的结构需要更改 moveUp/moveDown 时,好处是更容易维护。我已经需要多次稍微更改代码,并且我始终需要记住我需要在两个地方进行...
但我对“统一”版本不满意,因为:
- 实现比简单的 moveUp/moveDown 更复杂,因此将来它可能不会那么容易维护。我喜欢简单的代码。所有这些参数,三元运算,每个应该“向上”和“向下”的函数中的 .apply() 技巧......
- 不确定显式引用 jQuery.fn.* 函数是否安全(毕竟它们应该通过将它们应用于 jQuery 对象 $('...').* 来使用)
在使用 DOM 或类似结构时,您如何解决那些“几乎相同的代码”情况?