[mind-elixir]Mind-Elixir 的交互增強:單擊、雙擊與鼠標 Hover 功能實現
功能簡述
- 通過防抖,實現單擊雙擊區分
- 通過mousemove事件,實現hover效果
實現思路
(一)單擊與雙擊事件
- 功能描述
- 單擊節點時,可以觸發單擊事件,用于執行一些簡單操作,如顯示節點詳情、切換樣式等。
- 雙擊節點時,可以觸發雙擊事件,用于執行更復雜的操作,如編輯節點內容、展開/折疊子節點等。
- 通過防抖處理,能夠準確區分單擊和雙擊事件,避免誤判。
- 實現思路
- 使用
clickTimer
和 clickCount
來記錄點擊事件的時間和次數。 - 當節點被選中時,通過
handleNodeSelect
方法判斷是單擊還是雙擊。 - 如果是同一個節點在短時間內多次點擊,則視為雙擊;否則視為單擊。
- 代碼實現
handleNodeSelect(nodeData) {if (this.lastClickedNode && this.lastClickedNode.id === nodeData.id) {this.clickCount++} else {this.clickCount = 1this.lastClickedNode = nodeData}if (this.clickTimer) {clearTimeout(this.clickTimer)}this.clickTimer = setTimeout(() => {if (this.clickCount === 1) {console.log('觸發點擊', nodeData)} else if (this.clickCount >= 2) {console.log('觸發雙擊', nodeData)}this.clickCount = 0this.lastClickedNode = null}, 200)
}
(二)鼠標 Hover 事件
- 功能描述
- 當鼠標懸停在某個節點上時,可以獲取該節點的 ID,用于高亮顯示、提示信息等操作。
- 通過監聽
mousemove
事件,實時獲取鼠標位置和對應的節點信息。
- 實現思路
- 在
handleMouseMove
方法中,通過事件目標(e.target
)獲取節點的 ID。 - 判斷當前鼠標所在位置是否包含特定的節點元素(如
me-tpc
),從而確定是否觸發 Hover 事件。
- 代碼實現
handleMouseMove(e) {if (e?.target?.tagName === 'ME-TPC') {const nodeId = e.target.getAttribute('data-nodeid')if (nodeId !== this.hoverId) {console.log('鼠標移入', nodeId)this.hoverId = nodeId}} else {if (this.hoverId) {console.log('鼠標移出', this.hoverId)this.hoverId = ''}}}
具體代碼實現
<template><div class="box"><div id="map" @mousemove="handleMouseMove"></div><div style="margin-top: 20px"><button @click="test1">測試1</button></div></div>
</template><script>
import MindElixir from 'mind-elixir'
import example from 'mind-elixir/example'const mock = {id: 'root',topic: '中心主題',children: [{id: 'child1',topic: '子主題1',children: []},{id: 'child2',topic: '子主題2',children: []}]
}export default {name: 'MindElixir',data() {return {ME: null,clickTimer: null,clickCount: 0,lastClickedNode: null,hoverId: ''}},mounted() {const generateMainBranch = ({ pT, pL, pW, pH, cT, cL, cW, cH, direction }) => {console.log('111', pT, pL, pW, pH)console.log('222', cT, cL, cW, cH)console.log('direction', direction)const x1 = pWconst y1 = pT + pH / 2const c1 = pW + (cL - pW) / 2const c2 = cT + cH / 2return `M ${x1} ${y1} H ${c1} V ${c2} H ${cL}`}console.log('example', example)const theme = MindElixir.THEMEtheme.cssVar['--root-bgcolor'] = '#2499f2'theme.cssVar['--root-radius'] = '5px'theme.cssVar['--main-radius'] = '5px'theme.palette = ['#27f25a']this.ME = new MindElixir({el: '#map',locale: 'zh_CN',draggable: true, editable: true, contextMenu: true, toolBar: true, nodeMenu: true, keypress: true, generateMainBranch})this.ME.bus.addListener('operation', operation => {console.log('operation', operation)})this.ME.init({nodeData: mock,theme})this.ME.bus.addListener('selectNode', this.handleNodeSelect)},methods: {test1() {const mock2 = {id: 'root',topic: '中心主題222',style: {color: 'yellow'},children: [{id: 'child3',topic: '子主題3',children: []},{id: 'child4',topic: '子主題4',children: []}]}this.ME.refresh({nodeData: mock2})},handleNodeSelect(nodeData) {if (this.lastClickedNode && this.lastClickedNode.id === nodeData.id) {this.clickCount++} else {this.clickCount = 1this.lastClickedNode = nodeData}if (this.clickTimer) {clearTimeout(this.clickTimer)}this.clickTimer = setTimeout(() => {if (this.clickCount === 1) {console.log('觸發點擊', nodeData)} else if (this.clickCount >= 2) {console.log('觸發雙擊', nodeData)}this.clickCount = 0this.lastClickedNode = null}, 200) },handleMouseMove(e) {if (e?.target?.tagName === 'ME-TPC') {const nodeId = e.target.getAttribute('data-nodeid')if (nodeId !== this.hoverId) {console.log('鼠標移入', nodeId)this.hoverId = nodeId}} else {if (this.hoverId) {console.log('鼠標移出', this.hoverId)this.hoverId = ''}}}}
}
</script><style lang="less" scoped>
.box {text-align: center;
}
#map {width: 100%;height: 800px;overflow: auto;
}
</style>