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

拖拽Riot.js SVG组件异常:点击蓝色矩形触发绿色组件事件

解决Riot.js中SVG拖拽元素事件绑定混乱的问题

你遇到的问题核心在于组件实例的事件处理函数被意外共享覆盖了。你把tag.hold = hold直接赋值给全局的tag对象,导致最后渲染的绿色矩形组件覆盖了之前蓝色矩形的hold引用,所以不管点哪个矩形,都会触发最后那个实例的事件。

修复方案

我们需要确保每个r-rect组件实例拥有独立的事件处理函数,而不是共享同一个引用。修改你的r-rect.tag代码如下:

<r-rect>
  <rect ref="rect" onmousedown={hold} />
  <script>
    const tag = this;
    tag.x = Number.parseInt(opts.x);
    tag.y = Number.parseInt(opts.y);
    tag._name = opts.name;

    tag.on("mount", function(e) {
      tag.refs.rect.setAttribute("x", opts.x);
      tag.refs.rect.setAttribute("y", opts.y);
      tag.refs.rect.setAttribute("width", opts.width);
      tag.refs.rect.setAttribute("height", opts.height);
      opts.rx && tag.refs.rect.setAttribute("rx", opts.rx);
      opts.ry && tag.refs.rect.setAttribute("ry", opts.ry);
    });

    // 每个组件实例会创建自己的hold函数,不会被其他实例覆盖
    function hold(e){
      console.log(tag._name);
    }
  </script>
</r-rect>

关键修改点解释

  1. 移除了tag.hold = hold这行代码:这行是导致事件函数被共享覆盖的元凶,因为所有组件实例都会修改同一个全局tag对象的hold属性,最后只有最后一个实例的函数保留下来。
  2. 直接在onmousedown={hold}中引用组件内部定义的hold函数:Riot.js会为每个组件实例创建独立的作用域,这样每个矩形的mousedown事件都会绑定到自己实例的hold函数上,点击蓝色矩形就会输出"blue",点击绿色矩形输出"green"。

你的SVG部分代码无需修改,保持原样即可:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <g name="green" data-is="r-rect" x="30" y="230" width="256" height="64" rx="5" ry="5" draggable="true" fill="green"></g>
  <g name="blue" data-is="r-rect" x="10" y="110" width="256" height="64" rx="5" ry="5" draggable="true" fill="blue"></g>
</svg>

这样修改后,每个矩形的mousedown事件就会正确触发对应实例的处理函数了,你可以继续在此基础上完善拖拽的逻辑(比如监听mousemove和mouseup来实现拖拽位移)。

内容的提问来源于stack exchange,提问作者Amit Kumar Gupta

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:56:44