在開發思惟導圖控件blink-mind-react的時候,有一個需求是:當點擊展開和摺疊某個節點的時候,須要展開和摺疊的icon的位置(相對於視口的位置)不要發生變化。react
這個思惟導圖組件是放在DragScroll組件裏面的,由於思惟導圖須要能夠拖動到視口的任何區域進行查看。在開發思惟導圖組件的時候,用的佈局方式是Flex 佈局。當點擊展開或者摺疊按鈕時,整個控件的size會發生變化,而我想要的效果是點擊按鈕的位置在視覺效果上不能有移動,否則的話,若是點擊了按鈕以後,發現按鈕移動到了另一個位置(由於整個佈局被重排了),用戶體驗會不好。git
爲了解決上述問題,想到一個方案是能夠在點擊按鈕以後,調用一個函數讓DragScroll控件裏面的viewBox的scroll值調整到合適的位置,就能夠讓點擊按鈕在視覺上看上去位置沒有發生改變。github
基於上面的方案,在DragScroll組件裏面封裝了兩個函數:bash
setViewBoxScroll是使用絕對座標進行scroll值調整函數
setViewBoxScrollDelta是使用相對座標進行scroll值調整佈局
setViewBoxScroll = (left: number, top: number) => {
if (this.viewBox) {
this.viewBox.scrollLeft = left;
this.viewBox.scrollTop = top;
}
};
setViewBoxScrollDelta = (deltaLeft: number, deltaTop: number) => {
if (this.viewBox) {
this.viewBox.scrollLeft += deltaLeft;
this.viewBox.scrollTop += deltaTop;
}
};
複製代碼
經過render函數中的調用傳遞給子組件ui
{this.props.children(
this.setViewBoxScroll,
this.setViewBoxScrollDelta
)}
複製代碼
這樣子組件就能夠經過props 拿到這兩個函數,在須要的時候調用這兩個函數中的任意一個進行本身所須要的scroll值調整。this
比方說在思惟導圖的節點組件NodeWidget中,使用了setViewBoxScrollDelta函數來調整DragScroll組件的scroll 值,保證節點在展開或摺疊過程當中,視覺上位置不變。spa
componentDidUpdate(
prevProps: Readonly<MindNodeWidgetProps>,
prevState: Readonly<MindNodeWidgetState>,
snapshot?: any
): void {
if (this.needRelocation) {
let newRect = this.collapseIcon.getBoundingClientRect();
this.props.setViewBoxScrollDelta(
newRect.left - this.oldCollapseIconRect.left,
newRect.top - this.oldCollapseIconRect.top
);
this.needRelocation = false;
}
this.layoutSubLinks();
}
複製代碼