You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JointJS中悬停单元格标记选择器时触发动作?

在JointJS中实现标记元素的悬停触发动作

核心思路

利用JointJS支持的pointerenter和pointerleave指针事件(对应鼠标悬停/离开行为),结合标记元素的唯一标识(如类名)识别目标按钮,进而触发透明度调整逻辑。

具体实现步骤

  1. 给标记按钮添加唯一标识
    在自定义单元格的markup和attrs中,为每个SVG按钮添加唯一的class属性,方便后续识别:

    const MyCustomCell = joint.dia.Element.define('custom.Cell', {
      attrs: {
        body: { width: 220, height: 120, fill: '#ffffff', stroke: '#333333' },
        // 四个按钮分别设置唯一class
        btn1: { x: 15, y: 15, width: 25, height: 25, fill: '#e74c3c', class: 'hover-btn-1' },
        btn2: { x: 50, y: 15, width: 25, height: 25, fill: '#2ecc71', class: 'hover-btn-2' },
        btn3: { x: 15, y: 50, width: 25, height: 25, fill: '#3498db', class: 'hover-btn-3' },
        btn4: { x: 50, y: 50, width: 25, height: 25, fill: '#f1c40f', class: 'hover-btn-4' }
      }
    }, {
      markup: [
        { tagName: 'rect', selector: 'body' },
        { tagName: 'rect', selector: 'btn1' },
        { tagName: 'rect', selector: 'btn2' },
        { tagName: 'rect', selector: 'btn3' },
        { tagName: 'rect', selector: 'btn4' }
      ]
    });
    
  2. 绑定悬停事件并识别目标按钮
    给自定义单元格绑定pointerenter(悬停进入)和pointerleave(悬停离开)事件,通过事件目标的class属性判断当前悬停的按钮:

    // 悬停进入时调整其他元素透明度
    MyCustomCell.on('pointerenter', function(evt) {
      const targetClass = evt.target.getAttribute('class');
      // 过滤非按钮元素的事件
      if (!targetClass || !targetClass.startsWith('hover-btn-')) return;
    
      // 根据不同按钮设置对应透明度
      let targetOpacity = 0.5;
      switch(targetClass) {
        case 'hover-btn-1':
          targetOpacity = 0.3;
          break;
        case 'hover-btn-2':
          targetOpacity = 0.4;
          break;
        case 'hover-btn-3':
          targetOpacity = 0.6;
          break;
        case 'hover-btn-4':
          targetOpacity = 0.7;
          break;
      }
    
      // 筛选当前单元格外的所有元素,修改透明度
      const currentCellId = this.id;
      graph.getElements().forEach(cell => {
        if (cell.id !== currentCellId) {
          cell.attr('body/opacity', targetOpacity);
        }
      });
    });
    
    // 悬停离开时恢复透明度
    MyCustomCell.on('pointerleave', function(evt) {
      const targetClass = evt.target.getAttribute('class');
      if (!targetClass || !targetClass.startsWith('hover-btn-')) return;
    
      // 恢复所有其他元素的默认透明度
      const currentCellId = this.id;
      graph.getElements().forEach(cell => {
        if (cell.id !== currentCellId) {
          cell.attr('body/opacity', 1);
        }
      });
    });
    
  3. 替代方案:全局画布事件监听
    如果需要全局监听所有元素的按钮悬停,也可以直接在画布(paper)上绑定事件:

    paper.on('element:pointerenter', function(view, evt) {
      const targetClass = evt.target.getAttribute('class');
      if (!targetClass || !targetClass.startsWith('hover-btn-')) return;
    
      // 同上述透明度调整逻辑
      const currentCellId = view.model.id;
      // ...
    });
    
    paper.on('element:pointerleave', function(view, evt) {
      const targetClass = evt.target.getAttribute('class');
      if (!targetClass || !targetClass.startsWith('hover-btn-')) return;
    
      // 同上述恢复透明度逻辑
      const currentCellId = view.model.id;
      // ...
    });
    

关键说明

  • JointJS的pointerenter/pointerleave事件天然支持鼠标悬停场景,同时兼容触摸设备;
  • 通过evt.target可以直接获取触发事件的SVG元素,利用预先设置的class就能精准识别目标按钮;
  • 若元素结构复杂,也可以用view.findTargetBySelector(selector)方法匹配标记中的selector,替代class识别。

内容的提问来源于stack exchange,提问作者ata1704

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 00:41:13