SortableJS / Vue.Draggable

Vue drag-and-drop component based on Sortable.js
https://sortablejs.github.io/Vue.Draggable/
MIT License
20.15k stars 2.9k forks source link

Symbol.iterator traceback on Internet Explorer when using Draggable #995

Open arrancardnell opened 3 years ago

arrancardnell commented 3 years ago

Version & browser

Internet Explorer 11+ VueDraggable 2.24.3

Step by step scenario

Minimal example from docs produces error on IE

<template>
  <Draggable v-model="myArray" group="people">
    <div v-for="element in myArray" :key="element.id">
      {{ element.name }}
    </div>
  </Draggable>
</template>

<script>
import Draggable from "vuedraggable";

export default {
  name: "TEST",
  components: {
    Draggable,
  },
  data() {
    return {
      myArray: [
        { id: 1, name: "Element 1" },
        { id: 2, name: "Element 2" },
      ],
    };
  },
};
</script>

The above code results in the following when running on IE:

draggable-github-bug

arrancardnell commented 3 years ago

So I did some digging into this. The error seems to come from this piece of code:

function computeIndexes(slots, children, isTransition, footerOffset) {
  if (!slots) {
    return [];
  }

  const elmFromNodes = slots.map(elt => elt.elm);
  const footerIndex = children.length - footerOffset;
  const rawIndexes = [...children].map((elt, idx) =>
    idx >= footerIndex ? elmFromNodes.length : elmFromNodes.indexOf(elt)
  );
  return isTransition ? rawIndexes.filter(ind => ind !== -1) : rawIndexes;
}

In particular, the issue is caused by [...children], because children is an HTMLCollection, which are not iterable as per DOM4 spec (even though they can be iterated over). This is ignored by FF and Chrome, but trips up IE.

Since the code above appears to be just casting children to an array, the error can be fixed by replacing [...children] with Array.from(children).

For anyone looking for an interim fix, adding the following line of code to your main.js file will also solve the issue:

HTMLCollection.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];