getBoundingClientRect is not a function on vueJs

Viewed 7972

I would like to find the top and bottom edge of a div when i move my cursor over it. The div is generated dynamically. However, it produced error message

getBoundingClientRect is not a function

<template>
    <div>
        <div v-for="(i, index) in divs" :key="index">
            <div :ref="'ref_' + index" @mouseover="divDragOver($event, index)">
                This is div {{ index }}
            </div>
        </div>        
    </div>
</template>

<script>

export default{
  methods: {
    divDragOver(e, i){
      var divTop = this.$refs["ref_" + i].getBoundingClientRect().top;
      console.log(divTop);
    }
  }
}
</script>

3 Answers

You can use event.target as another user suggested which is, I think, the cleanest way

<template>
  <div>
    <div v-for="(i, index) in divs" :key="index">
      <div ref="myDiv" @mouseover="divDragOver">This is div {{ index }}</div>
    </div>
  </div>
</template>

<script>
export default {
  data: function() {
    return { divs: [1, 2, 3, 4] };
  },
  methods: {
    divDragOver(event) {
      console.log(event.target); // this will be your mouseover div
    }
  }
};
</script>

For your issue though, based on Vue.js documentation:

When ref is used together with v-for, the ref you get will be an array containing the child components mirroring the data source.

So you don't have to use the index on your ref creation, while you will end up with divs.length arrays which their first element will be your reference.

If you had to use refs:

<template>
  <div>
    <div v-for="(i, index) in divs" :key="index">
      <div ref="myDiv" @mouseover="divDragOver($event, index)">This is div {{ index }}</div>
    </div>
  </div>
</template>

<script>
export default {
  data: function() {
    return { divs: [1, 2, 3, 4] };
  },
  methods: {
    divDragOver(e, i) {
      console.log(this.$refs.myDiv); // this will be an array with all your refs, use i to access
    }
  }
};
</script>

So you were getting an error because your element's ref was on this.$refs["ref_" + i][0]

Try something like that:

<template>
  <div>
    <div v-for="index in divs" :key="index">
      <div :ref="'ref_' + index" @mouseover="divDragOver($event, index)">
        This is div {{ index }}
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    divs: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
  }),
  methods: {
    divDragOver(e, i) {
      let [div] = this.$refs['ref_' + i];
      let top = div.getBoundingClientRect().top;
      console.log(top);
    },
  },
};
</script>

Your code doesn't work, because the this.refs return an Array.

You can handle this problem by accessing the target element in the event:

<script>
export default{
  methods: {
    divDragOver(e){
      var divTop = e.target.getBoundingClientRect();
      console.log(divTop);
    }
  }
}
</script>
Related