fabricjs給元素添加事件偵聽導致可能的內存泄漏問題

場景

由於需要給每一種元素設置一個獨立的工具欄,所以就需要給每一個元素設置一個獨立的事件去修改對應的工具欄的值

比如一個元素的角度顯示問題。
我們可以給元素添加一個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)

也保證了事件唯一。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章