我有一个对象数组:
elements: [
{
id: '1',
dataX: 0,
dataY: 0
},
{
id: '2',
dataX: 189,
dataY: 189
}
]
它们在模板中使用如下:
// This is inside a repeat loop:
<a class="btn"
id="{{ id }}"
data-x="{{ dataX }}"
data-y="{{ dataY }}"
style="transform: translate({{ dataX }}px, {{ dataY}}px);">
</a>
最终输出:
<a class="btn" id="2" data-x="189" data-y="189" style="transform: translate(189px, 189px); width: 144px; height: 36px;"></a>
我的代码更改了data-x
和data-y
以及transform
属性的值,因此可以拖动锚标记。
在该函数结束时,我有几行更改数组elements
本身:
const target = event.target
const x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx
const y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy
// the code that makes the anchor tags move
// the code that modifies the array itself
this.elements.map(item => {
if (item.id === target.id) {
item.dataX = x
item.dataY = y
}
})
有效。但是,宽度和高度属性被消除:
<a class="btn" id="2" data-x="189" data-y="189" style="transform: translate(189px, 189px);"></a>
这是为什么以及如何预防?
注意:this.elements
是一个反应元素。这意味着如果数据发生更改,则元素将在模板中重新呈现。
编辑(完整的JavaScript代码。我使用Interact.js):
ready () {
interact('#plane > *')
.draggable({
snap: {
targets: [
interact.createSnapGrid({ x: this.baseUnit, y: this.baseUnit })
],
range: Infinity,
relativePoints: [ { x: 0, y: 0 } ]
},
restrict: {
restriction: 'parent',
elementRect: { top: 0, left: 0, bottom: 1, right: 1 }
},
onmove: (event) => {
const target = event.target
const x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx
const y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy
// translate the element
target.style.webkitTransform =
target.style.transform =
'translate(' + x + 'px, ' + y + 'px)'
// update the positon attributes
target.setAttribute('data-x', x)
target.setAttribute('data-y', y)
this.elements.map(item => {
if (item.id === target.id) {
console.log(item)
item.dataX = x
item.dataY = y
}
})
}
})
.resizable({
snap: {
targets: [
interact.createSnapGrid({ x: this.baseUnit, y: this.baseUnit })
],
range: Infinity,
relativePoints: [ { x: 0, y: 0 } ]
},
edges: { left: true, right: true, bottom: true, top: true },
onmove: (event) => {
const target = event.target
let x = (parseFloat(target.getAttribute('data-x')) || 0)
let y = (parseFloat(target.getAttribute('data-y')) || 0)
// update the element's style
target.style.width = event.rect.width + 'px'
target.style.height = event.rect.height + 'px'
// translate when resizing from top or left edges
x += event.deltaRect.left
y += event.deltaRect.top
target.setAttribute('data-width', event.rect.width)
target.setAttribute('data-height', event.rect.height)
target.textContent = Math.round(event.rect.width) + '×' + Math.round(event.rect.height)
}
})
},
答案 0 :(得分:2)
这是我疯狂猜测面对一些缺失的部分时发生的事情......
你可能有某种绑定设置,这样当数组发生变化时(由map
调用变异),它会重新呈现模板;我在假设。
原始模板(map
之前调用)在width
属性中包含height
和style
值,但不清楚从。 明确的是它们不包含在您的重新计算中。
因此,我的猜测是map
调用会覆盖它们,因为它只用style
重写整个 transform
属性。< / p>
将width
和height
值重新添加回style
属性的动态呈现值,您就可以了。
编辑:基本上发布的完整代码基本上我说的都是真的,除了增加了竞争onmove事件的味道。 (我相信)
我认为发生的事情是你的第一个 onmove 事件正在触发并设置width
和height
以及然后第二个触发事件用style
覆盖transform
。解决这个问题需要稍微改变逻辑,以便你的事件处理程序不会相互争斗。