拖拽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>
关键修改点解释
- 移除了
tag.hold = hold这行代码:这行是导致事件函数被共享覆盖的元凶,因为所有组件实例都会修改同一个全局tag对象的hold属性,最后只有最后一个实例的函数保留下来。 - 直接在
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
相关产品推荐
相关产品推荐

