场景
由于需要给每一种元素设置一个独立的工具栏,所以就需要给每一个元素设置一个独立的事件去修改对应的工具栏的值
比如一个元素的角度显示问题。
我们可以给元素添加一个rotate
事件,去动态修改工具栏的angle
的值。
代码:
this.gettersTarget.on('rotating', arg => {
// 设置角度的angle值
this.angleValue = parseInt(arg.target.angle)
})
但是在测试的时候,发现触发的速度越来越快。
由于工具栏是根据元素而动态变化的,从而导致在设计的时候,用户选择一个元素的时候都需要根据元素去加载对应的组件,并且由于作用域的问题,我们不能去提前绑定,只能在组件加载的时候去绑定,才能通过this
去访问工具栏的值。
提前绑定事件不可行
我试过提前绑定事件,但是由于需求是需要重新加载,即使是提前绑定好事件,但是重新加载场景后,this
无法正确访问到对应的作用域,也就无法修改对应的值了。这样,原本 绑定事件就失效了。
源码找答案
我们都知道,fabric事件肯定是一个数组管理的,不然也无法解释为什么每次点击后,事件触发的越来越快。所以我们只需要找到fabricjs上的事件管理的数组,在上面去进行判断,让每一个元素只能绑定一个事件,这样就可以避免重复绑定相同的事件而导致的内存泄漏的问题。
在继承的fabric.object上找到on
方法
发现事件都绑定到对象的__eventListeners
上了。
我们输出看看:
可以看出来,我们每一次点击而导致的工具栏加载,都会触发重复添加事件。
我们在事件添加判断该事件是否大于0就可以了,当然可以根据需求去进行修改。
// // 绑定旋转按钮; gettersTarget为当前选择元素的object对象
let {rotating} = this.gettersTarget.__eventListeners
if (rotating.length < 1) {
this.gettersTarget.on('rotating', arg => {
console.log('1')
this.angleValue = parseInt(arg.target.angle)
})
}
发现达成目的了,但是出现了一个新的问题。
重新加载事件没用
虽然达到了绑定事件的内存问题,但是由于需求是需要动态加载属性的,如果用户刷新页面,通过fabric的objectTocanvas方法加载回来的canvas,发现工具栏同样无法触发,所以我们需要修改逻辑,需要保证每次点击元素,都需要更新元素对象上的事件是最新的。
这样重新加载都可以修改组件上的input,因为事件绑定是实时的。
let rotating = null
if (this.gettersTarget.__eventListeners) {
rotating = this.gettersTarget.__eventListeners.rotating
// 清楚事件
rotating.pop()
}
console.log('1')
this.gettersTarget.on('rotating', arg => {
this.angleValue = parseInt(arg.target.angle)
})
console.log(this.gettersTarget.__eventListeners)
也保证了事件唯一。