[mind-elixir]Mind-Elixir 的交互增强:单击、双击与鼠标 Hover 功能实现

功能简述

  1. 通过防抖,实现单击双击区分
  2. 通过mousemove事件,实现hover效果

实现思路

(一)单击与双击事件
  1. 功能描述
    • 单击节点时,可以触发单击事件,用于执行一些简单操作,如显示节点详情、切换样式等。
    • 双击节点时,可以触发双击事件,用于执行更复杂的操作,如编辑节点内容、展开/折叠子节点等。
    • 通过防抖处理,能够准确区分单击和双击事件,避免误判。
  2. 实现思路
    • 使用 clickTimerclickCount 来记录点击事件的时间和次数。
    • 当节点被选中时,通过 handleNodeSelect 方法判断是单击还是双击。
    • 如果是同一个节点在短时间内多次点击,则视为双击;否则视为单击。
  3. 代码实现
    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) // 200ms内的多次点击判断为双击
    }
    
(二)鼠标 Hover 事件
  1. 功能描述
    • 当鼠标悬停在某个节点上时,可以获取该节点的 ID,用于高亮显示、提示信息等操作。
    • 通过监听 mousemove 事件,实时获取鼠标位置和对应的节点信息。
  2. 实现思路
    • handleMouseMove 方法中,通过事件目标(e.target)获取节点的 ID。
    • 判断当前鼠标所在位置是否包含特定的节点元素(如 me-tpc),从而确定是否触发 Hover 事件。
  3. 代码实现
    // 鼠标移动事件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,// 鼠标移入idhoverId: ''}},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, // 启用快捷键// before: {},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) // 200ms内的多次点击判断为双击},// 鼠标移动事件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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/917057.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/917057.shtml
英文地址,请注明出处:http://en.pswp.cn/news/917057.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c++-迭代器类别仿函数常用算法函数

C常用算法函数 1. 前置知识 1.1 迭代器的类别 C中&#xff0c;迭代器是 STL 容器库的核心组件之一&#xff0c;具有举足轻重的作用&#xff0c;它提供了一种 统一的方式来访问和遍历容器&#xff0c;而无需关心底层数据结构的具体实现。迭代器类似指针&#xff0c;但比指针更通…

Python深度学习框架TensorFlow与Keras的实践探索

基础概念与安装配置 TensorFlow核心架构解析 TensorFlow是由Google Brain团队开发的开源深度学习框架&#xff0c;其核心架构包含数据流图&#xff08;Data Flow Graph&#xff09;和张量计算系统。数据流图通过节点表示运算操作&#xff08;如卷积、激活函数&#xff09;&…

c# net6.0+ 安装中文智能提示

https://github.com/stratosblue/IntelliSenseLocalizer 1、安装tool dotnet tool install -g islocalizer 2、 安装IntelliSense 文件&#xff0c;安装其他net版本修改下版本号 安装中文net6.0采集包 islocalizer install auto -m net6.0 -l zh-cn 安装中英文双语net6.0采集包…

【建模与仿真】二阶邻居节点信息驱动的节点重要性排序算法

导读&#xff1a; 在复杂网络中&#xff0c;挖掘重要节点对精准推荐、交通管控、谣言控制和疾病遏制等应用至关重要。为此&#xff0c;本文提出一种局部信息驱动的节点重要性排序算法Leaky Noisy Integrate-and-Fire (LNIF)。该算法通过获取节点的二阶邻居信息计算节点重要性&…

指令微调Qwen3实现文本分类任务

参考文档&#xff1a; SwanLab入门深度学习&#xff1a;Qwen3大模型指令微调 - 肖祥 - 博客园 vLLM&#xff1a;让大语言模型推理更高效的新一代引擎 —— 原理详解一_vllm 原理-CSDN博客 概述 为了实现对100个标签的多标签文本分类任务&#xff0c;前期调用gpt-4o进行prom…

【机器学习-3】 | 决策树与鸢尾花分类实践篇

0 序言 本文将深入探讨决策树算法&#xff0c;先回顾下前边的知识&#xff0c;从其基本概念、构建过程讲起&#xff0c;带你理解信息熵、信息增益等核心要点。 接着在引入新知识点&#xff0c;介绍Scikit - learn 库中决策树的实现与应用&#xff0c;再通过一个具体项目的方式来…

【数字投影】折幕影院都是沉浸式吗?

折幕影院作为一种现代化的展示形式&#xff0c;其核心特点在于通过多块屏幕拼接和投影融合技术&#xff0c;打造更具包围感的视觉体验。折幕影院设计通常采用多折幕结构&#xff0c;如三折幕、五折幕等&#xff0c;利用多台投影机的协同工作&#xff0c;呈现无缝衔接的超大画面…

数据结构——图(三、图的 广度/深度 优先搜索)

一、广度优先搜索(BFS)①找到与一个顶点相邻的所有顶点 ②标记哪些顶点被访问过 ③需要一个辅助队列#define MaxVertexNum 100 bool visited[MaxVertexNum]; //访问标记数组 void BFSTraverse(Graph G){ //对图进行广度优先遍历&#xff0c;处理非连通图的函数 for(int i0;i…

直击WAIC | 百度袁佛玉:加速具身智能技术及产品研发,助力场景应用多样化落地

7月26日&#xff0c;2025世界人工智能大会暨人工智能全球治理高级别会议&#xff08;WAIC&#xff09;在上海开幕。同期&#xff0c;由国家地方共建人形机器人创新中心&#xff08;以下简称“国地中心”&#xff09;与中国电子学会联合承办&#xff0c;百度智能云、中国联通上海…

2025年人形机器人动捕技术研讨会将在本周四召开

2025年7月31日爱迪斯通所主办的【2025人形机器动作捕捉技术研讨会】是携手北京天树探界公司线下活动结合线上直播的形式&#xff0c;会议将聚焦在“动作捕捉软硬件协同&#xff0c;加速人形机器人训练”&#xff0c;将深度讲解多项核心技术&#xff0c;包含全球知名的惯性动捕大…

Apple基础(Xcode①-项目结构解析)

要运行设备之前先选择好设备Product---->Destination---->选择设备首次运行手机提示如出现 “未受信任的企业级开发者” → 手机打开 设置 ▸ 通用 ▸ VPN与设备管理 → 信任你的 Apple ID 即可ContentView 是 SwiftUI 项目里 最顶层、最主界面 的那个“页面”&#xff0…

微服务 02

一、网关路由网关就是网络的关口。数据在网络间传输&#xff0c;从一个网络传输到另一网络时就需要经过网关来做数据的路由和转发以及数据安全的校验。路由是网关的核心功能之一&#xff0c;决定如何将客户端请求映射到后端服务。1、快速入门创建新模块&#xff0c;引入网关依赖…

04动手学深度学习笔记(上)

04数据操作 import torch(1)张量表示一个数据组成的数组&#xff0c;这个数组可能有多个维度。 xtorch.arange(12) xtensor([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])(2)通过shape来访问张量的形状和张量中元素的总数 x.shapetorch.Size([12])(3)number of elements表…

MCU中的RTC(Real-Time Clock,实时时钟)是什么?

MCU中的RTC(Real-Time Clock,实时时钟)是什么? 在MCU(微控制器单元)中,RTC(Real-Time Clock,实时时钟) 是一个独立计时模块,用于在系统断电或低功耗状态下持续记录时间和日期。以下是关于RTC的详细说明: 1. RTC的核心功能 精准计时:提供年、月、日、时、分、秒、…

Linux 进程调度管理

进程调度器可粗略分为两类&#xff1a;实时调度器(kernel)&#xff0c;系统中重要的进程由实时调度器调度&#xff0c;获得CPU能力强。非实时调度器(user)&#xff0c;系统中大部分进程由非实时调度器调度&#xff0c;获得CPU能力弱。实时调度器实时调度器支持的调度策略&#…

基于 C 语言视角:流程图中分支与循环结构的深度解析

前言&#xff08;约 1500 字&#xff09;在 C 语言程序设计中&#xff0c;控制结构是构建逻辑的核心骨架&#xff0c;而流程图作为可视化工具&#xff0c;是将抽象代码逻辑转化为直观图形的桥梁。对于入门 C 语言的工程师而言&#xff0c;掌握流程图与分支、循环结构的对应关系…

threejs创建自定义多段柱

最近在研究自定义建模&#xff0c;有一个多断柱模型比较有意思&#xff0c;分享下&#xff0c;就是利用几组点串&#xff0c;比如上中下&#xff0c;然后每组点又不一样多&#xff0c;点续还不一样&#xff0c;(比如第一个环的第一个点在左边&#xff0c;第二个环在右边)&#…

Language Models are Few-Shot Learners: 开箱即用的GPT-3(四)

Result续 Winograd-Style Tasks Winograd-Style Tasks 是自然语言处理中的一类经典任务。它源于 Winograd Schema Challenge(WSC),主要涉及确定代词指的是哪个单词,旨在评估模型的常识推理和自然语言理解能力。 这个任务中的具体通常包含高度歧义的代词,但从语义角度看…

BGP高级特性之认证

一、概述BGP使用TCP作为传输协议&#xff0c;只要TCP数据包的源地址、目的地址、源端口、目的端 口和TCP序号是正确的&#xff0c;BGP就会认为这个数据包有效&#xff0c;但数据包的大部分参数对于攻击 者来说是不难获得的。为了保证BGP免受攻击&#xff0c;可以在BGP邻居之间使…

商旅平台怎么选?如何规避商旅流程中的违规风险?

在中大型企业的商旅管理中&#xff0c;一个典型的管理“黑洞”——流程漏洞与超标正持续吞噬企业成本与管理效能&#xff1a;差标混乱、审批脱节让超规订单频频闯关&#xff0c;不仅让企业商旅成本超支&#xff0c;还可能引发税务稽查风险。隐性的合规风险&#xff0c;比如虚假…