// 绑定时依赖的数据
var data = {
isOn: true
}
// 封装DOM操作
function addClassOrRemove (el, clazz, cnd) {
var $el = $(el)
cnd ? $el.addClass(clazz) : $el.remove(clazz)
}
// 将DOM操作与元素绑定,返回操作步骤
function classBinding () {
var tar = document.querySelector('[binding-class]')
var dec = $(tar).attr('binding-class')
var clazz = desc.split(':')[0]
var field = desc.split(':')[1].trim()
return function () {
addClassOrRemove(tar, clazz, data[field])
}
}
// 进行绑定操作,获取绑定后的操作方法
var updateClassAction = classBinding()
// 初始化时更新
updateClassAction()
在 Angular, Vue.js等MVVM框架中,都包含指令(directive)的概念,directive实际上是一种针对DOM操作的抽象封装,并通过框架处理,将DOM操作逻辑与DOM元素进行自动化绑定,用一个简单的声明式语法简化了DOM操作逻辑中的
给元素命名
,查询目标元素
,进行DOM操作
步骤。举个小例子,比如我们有一个header组件,它的HTML片段内容是:
如果我们希望给这里的按钮添加一个高亮的class,用zepto的代码是这样写的:
由以上小例子可以看出,我们在写JS交互逻辑的时候,几乎所有的JS交互逻辑都像以下流程一样:
为此,封装DOM操作并自动化将DOM操作与元素绑定,可以减少1/2的交互逻辑代码(1个步骤替换3步骤),甚至做到根据DOM操作与元素与及数据进行绑定,那就可以用一个绑定声明减少了全部的手动步骤。
根据这一思路,我们先实现DOM操作封装与
组件的HTML中声明了一个click事件,绑定JS模块中的onBtnClick函数,JS模块的代码为:
显然,在完成DOM操作与DOM元素的绑定后,以后的每次更新触发场景中一个步骤就可以完成DOM元素的更新。 我们需要更懒惰一点,把手动触发更新的操作也省略了,如何? 那么我们需要现实监听数据的变更,在不考虑兼容IE9的情况下,我们可以使用ES5的
defineProperty
方法来实现:这就是MVVM的数据绑定的实现,在框架帮助下完成以上一系列的绑定行为,要完成根据状态给按钮添加/移除高亮的class,我们只需要这样一个属性标志:
个人认为,使用属性声明的方式自动化绑定优于具名选择器的方式操作DOM元素。从开发效率角度,我们省去了
给元素命名
/查询目标元素
/进行DOM操作
这3步操作,从维护性角度,我们也省却了知道文档结构
/知道选择器标志
2个步骤。