为什么以下分配删除"宽度和高度"属性?

时间:2016-02-28 04:18:19

标签: javascript html css

我有一个对象数组:

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-xdata-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)
        }
      })
  },

1 个答案:

答案 0 :(得分:2)

这是我疯狂猜测面对一些缺失的部分时发生的事情......

你可能有某种绑定设置,这样当数组发生变化时(由map调用变异),它会重新呈现模板;我在假设。

原始模板(map之前调用)在width属性中包含heightstyle值,但不清楚从。 明确的是它们不包含在您的重新计算中。

因此,我的猜测是map调用会覆盖它们,因为它只用style重写整个 transform属性。< / p>

widthheight值重新添加回style属性的动态呈现值,您就可以了。

编辑:基本上发布的完整代码基本上我说的都是真的,除了增加了竞争onmove事件的味道。 (我相信)

我认为发生的事情是你的第一个 onmove 事件正在触发并设置widthheight以及然后第二个触发事件用style覆盖transform。解决这个问题需要稍微改变逻辑,以便你的事件处理程序不会相互争斗。