news 2026/9/23 22:01:22

Cytoscape.js 集合元素反选:eles.unselect() 用法与选中状态机制深度解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Cytoscape.js 集合元素反选:eles.unselect() 用法与选中状态机制深度解析
  • 数据可视化

【免费下载链接】cytoscape.js

Graph theory (network) library for visualisation and analysis

项目地址:https://gitcode.com/gh_mirrors/cy/cytoscape.js
点击查看免费下载

eles.unselect()是 Cytoscape.js 中用于将集合内所有元素置为“未选中”状态的核心方法,广泛应用于工具栏“取消全选”、交互事件回调中清除选中态、以及多选之后的高亮复位等场景。本文以官方文档 unselect.md 为主体,结合源码实现与测试用例,完整讲解unselect()的用法、底层状态机、事件触发机制,以及它与select()unselectify()autounselectify等选中相关 API 的协作关系,读完后你将能熟练、安全地在图应用中管理与响应元素的选中状态。

API 一览:签名、返回值与别名

unselect()是定义在集合(collection)原型上的方法,作用于调用它的所有元素。其完整行为如下:

项目说明
方法名eles.unselect()(别名eles.deselect()
作用对象调用集合中的每一个元素
返回值原集合本身(支持链式调用)
触发事件unselect(仅对状态确实发生变化的元素触发)
官方示例cy.$('#j').unselect();

官方文档 unselect.md 给出的示例十分简洁:

cy.$('#j').unselect();

其中cy.$('#j')通过 ID 选择器取得元素集合,随后调用unselect()将其从选中状态切换为未选中。由于方法返回集合本身,可以继续链式调用其他集合方法,例如:

// 取消所有节点的选中状态,然后给它们添加高亮 class cy.nodes().unselect().addClass('dimmed');
// 别名 deselect,二者完全等价 cy.$('#j').deselect();

从源码看,别名在 src/collection/switch-functions.mjs 中直接以elesfn.deselect = elesfn.unselect;的形式定义,因此deselectunselect没有任何行为差异。

底层实现:一次理解所有开关型方法

unselect()并不是一个独立手写的函数,而是通过 Cytoscape.js 的“开关函数工厂”(switch function factory)批量生成的。相关实现集中在 src/collection/switch-functions.mjs:

defineSwitchSet( { field: 'selected', ableField: 'selectable', overrideAble: function( ele ){ return ele.cy().autounselectify() ? false : undefined; }, on: 'select', off: 'unselect' } );

这段声明可以拆解为以下要点:

  1. 状态字段field: 'selected'表示该方法读写元素私有状态_private.selected。元素的初始化默认值定义在 src/collection/element.mjs:selected默认falseselectable默认true(未显式指定时)。
  2. 可操作前提ableField: 'selectable'意味着只有selectabletrue的元素才允许被选中/取消选中。对一个unselectify()过的元素调用unselect()不会产生任何效果。
  3. 全局覆盖overrideAble检查核心的autounselectify开关——若该选项开启,则所有元素的选中状态都不可变,unselect()直接返回集合自身。
  4. 事件配对on: 'select'生成select()off: 'unselect'生成unselect(),二者共享同一个工厂函数defineSwitchFunction

工厂函数的核心逻辑(src/collection/switch-functions.mjs)为:遍历集合中每个元素,先判断able前提是否满足,再判断当前值与目标值是否不同(changed),仅在“状态真的发生变化”时才把元素记入changedEles。循环结束后:

let changedColl = this.spawn( changedEles ); changedColl.updateStyle(); // change of state => possible change of style changedColl.emit( params.event );

即对发生变化的元素:重新计算样式(因为选中状态可能影响样式,例如默认样式的:selected规则),并触发unselect事件。如果集合中没有任何元素的选中状态发生改变,则不会触发任何事件——这一点在测试中有明确覆盖(见下文)。

关键行为一:幂等性

对已经处于未选中状态的元素再次调用unselect(),不会触发事件、也不会重新应用样式。测试 test/collection-selection.mjs 验证了这一点:连续两次对同一元素调用unselect(),其selected()始终保持false

关键行为二:事件只在变化时触发

it('fires the `unselect` event', function(){ var n1 = cy.$('#n1').select(); ... n1.on('unselect', function(){ triggered = true; }); n1.unselect(); expect( triggered ).to.be.true; });

对应测试见 test/collection-selection.mjs。这保证了监听unselect事件的业务逻辑不会因冗余调用而重复执行。

状态查询与相关 API 对照

围绕“选中状态”,Cytoscape.js 提供了一组成对的开关型 API,全部由同一个工厂生成:

开关对应开启方法对应关闭方法状态字段
是否被选中select()unselect()/deselect()selected
是否可被选中selectify()unselectify()selectable
  • eles.selected():查询集合第一个元素的选中状态(返回布尔值),与之配套的:selected/:unselected选择器可用于过滤,例如cy.$(':selected')获取当前所有选中元素。相关文档见 select.md、is.md。
  • eles.unselectify():将元素标记为不可选中,此后select()/unselect()对它都不再生效,直到调用selectify()恢复。相关文档见 unselectify.md 与 selectify.md。

从源码(src/collection/switch-functions.mjs)可以看到,这两组开关相互联动:selectable状态本身就受autounselectify全局选项影响。测试 test/collection-selection.mjs 系统验证了这些交互:

n1.unselectify(); n1.select(); expect( n1.selected() ).to.be.false; // unselectify 后 select 无效 n2.select(); n2.unselectify(); n2.unselect(); expect( n2.selected() ).to.be.true; // unselectify 后 unselect 无效 n1.selectify(); // 恢复可选中性后 n1.unselect(); // unselect 重新生效 expect( n1.selected() ).to.be.false;

全局选项:autounselectify

除了逐元素调用unselectify(),还可以在初始化时设置核心选项autounselectify: true,一次性冻结整个图的选中状态:

const cy = cytoscape({ container: document.getElementById('cy'), autounselectify: true, elements: [ /* ... */ ] });

该选项在 src/core/index.mjs 中以默认值false初始化,读取与设置方法cy.autounselectify( bool )定义于 src/core/viewport.mjs。开启后,select()unselect()selectify()unselectify()overrideAble/overrideField钩子都会返回false,从而彻底屏蔽选中状态的变更,适合展示型、只读型图场景。

unselect 事件与交互场景

unselect事件是官方事件体系的一部分(完整事件列表见 events.md)。程序化调用unselect()会触发unselect事件,而用户交互引发的反选会触发带前缀的变体事件,主要包括:

  • tapunselect:点击空白区域或不可选元素时触发。在 src/extensions/renderer/base/load-listeners.mjs 中可以看到,点击空白处时渲染器执行cy.$(isSelected).unselect(['tapunselect'])——这里第二个数组参数是工厂函数支持的“附加事件”扩展用法,即状态变更后除unselect外额外触发tapunselect
  • boxselect/boxunselect:框选交互(拖拽矩形选择)相关,见 src/extensions/renderer/base/load-listeners.mjs 中的cy.$(':selected').unselect(['tapunselect'])等调用。

监听示例:

cy.on('unselect', 'node', function(evt){ console.log('节点被取消选中:', evt.target.id()); }); cy.on('tapunselect', function(){ console.log('点击空白处,所有选中元素被反选'); });

需要特别说明:unselect()的第二个参数可以传入附加事件名数组,但这一用法主要在渲染器内部使用,业务代码中建议只依赖标准的unselect事件,避免与用户交互事件混淆。

常见应用场景

场景一:清除全部选中状态

cy.nodes().unselect(); // 取消所有节点的选中 cy.elements().unselect(); // 取消所有元素(节点 + 边)的选中

场景二:切换选中状态

配合selected()select()实现单选/多选切换逻辑:

const node = cy.$('#a'); if( node.selected() ){ node.unselect(); } else { node.select(); }

场景三:先反选再做其他操作(链式调用)

cy.$(':selected').unselect().removeClass('highlight');

场景四:基于自定义事件实现“取消全部选中”按钮

cy.on('clear-selection', function(){ cy.elements().unselect(); }); // 触发 cy.emit('clear-selection');

测试验证:行为边界一览

除上文已引用的用例外,test/collection-selection.mjs 完整覆盖了unselect()的核心行为契约,可作为实现事实的最终依据:

  • 选中后调用unselect()selected()返回false(L63-L70);
  • 对已未选中的元素重复调用,状态保持false且无副作用(L72-L79);
  • 状态真正变化时触发unselect事件(L81-L95);
  • unselectify()使选中状态不可变,selectify()恢复可变性(L99-L126)。

此外,test/selectors.mjs 还验证了:unselected:unselectable选择器与反选/不可选状态的对应关系,说明unselect()变更的状态会即时反映在选择器查询结果中。

总结与进一步阅读

unselect()虽然只有一行示例,但背后是一个完整、严谨的状态管理机制:开关函数工厂统一生成、selectableautounselectify双层门槛控制、状态变化才触发事件的幂等设计,以及与选择器、样式、事件体系的无缝衔接。理解这一机制,是正确实现复杂交互(多选、框选、工具栏操作)的前提。

可以继续深入阅读的相关文档与源码:

  • 方法文档:select.md、unselectify.md、selectify.md、is.md
  • 事件文档:events.md
  • 选择器文档:selectors.md
  • 核心实现:src/collection/switch-functions.mjs、src/collection/element.mjs
  • 交互触发源码:src/extensions/renderer/base/load-listeners.mjs
  • 行为测试:test/collection-selection.mjs
  • 数据可视化

【免费下载链接】cytoscape.js

Graph theory (network) library for visualisation and analysis

项目地址:https://gitcode.com/gh_mirrors/cy/cytoscape.js
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/23 21:59:08

DCGAN低对比度红外图像增强实战:原理、训练与部署全流程

简介:基于 DCGAN 的低对比度红外图像增强项目资源,面向红外图像处理、计算机视觉以及深度学习应用开发人群,针对红外图像对比度低、目标轮廓模糊等痛点,给出了一套从数据预处理到模型训练、推理的完整实战方案。算法采用生成器与判…

作者头像 李华
网站建设 2026/9/23 21:55:54

SpringBoot宠物药品商城源码:合规处方审核与效期预警实战

简介:本资源是一套完整的Java毕业设计项目——科胜宠物医疗药品商城系统源码,面向计算机专业本科生及Java初学者,解决毕业设计选题、系统开发实践与SpringBoot全栈项目落地等核心需求。压缩包含1300个文件,主体为514个JS前端交互脚…

作者头像 李华
网站建设 2026/9/23 21:55:38

不装Axure,在线免费查看RP文件的3种实用方案

说个很常见的场景:群里突然甩过来一个.rp文件,是产品刚改好的新版原型,让你下午下班前给反馈。你手边没装Axure,又不想为了这一眼去下载一个几百兆的软件,更没心思去折腾破解授权——哪怕只是打开看一眼,也…

作者头像 李华
网站建设 2026/9/23 21:53:38

Excel公式函数实战:从引用方式到查找匹配与错误调试

1. 5.1小节:公式的第一课——等号、运算符和那个让人抓狂的$1.1 运算符优先级:为什么括号比例不是永远最高学Excel公式和函数,第一个认知必须是:所有公式都从等号开始。这不是废话,很多刚入门的朋友在单元格里输入sum(…

作者头像 李华
网站建设 2026/9/23 21:52:27

超融合HCI考试题库怎么刷?从核心考点到实战验证一次讲透

简介:一份面向华为HCI(超融合基础设施)认证备考的题库文档,适合正在准备华为HCI相关认证考试、或希望系统梳理超融合平台核心概念的工程师与运维人员使用。资源为单个docx文件,大小仅49KB,下载后可直接打开…

作者头像 李华