mobile-drag-dropを使った、HTML5のDrag & Drop API スマホ向けポリフィル（HTML/CSS+JavaScriptのみ） 

#やりたいこと

- 2021年4月現在でHTML5のDrag & Drop APIがiOSなどで対応していないので、Drag & Drop APIをベースにスマホでもドラッグ＆ドロップをできるようにしたい。

- 参考記事「[Drag & Drop API を使うときにやっておいたほうがいいこと](https://qiita.com/boushi-bird@github/items/ce720122fd0c15abe036)」の補完。

- HTML5のDrag & Drop API自体は動いている前提（PC画面ではドラッグ＆ドロップできるけど、スマホ画面では機能しなくなる人が対象）。

#背景

「[Drag & Drop API を使うときにやっておいたほうがいいこと](https://qiita.com/boushi-bird@github/items/ce720122fd0c15abe036)」を参考に[mobile-drag-drop](https://github.com/timruffles/mobile-drag-drop)を使おうとしたら、以下の点で詰まりました。

①npmとか使ってるけど、もっと簡単に使いたい（でもよくわからん）。
②polyfil関数が読み込めない。
~~③`window.addEventListener('touchmove', function {}, { passive: false });`でエラーになる。~~（③は修正いただけたので削除。参考までにこの状態で残しておきます）

以下、この3点について自分用のメモを兼ねて書いていきます。

#詰まった3点の解決策

###①npmとか使ってるけど、もっと簡単に使いたい（でもよくわからん）。

これは、ローカルにダウンロードして、[mobile-drag-drop](https://github.com/timruffles/mobile-drag-drop)のREADMEで「global」のところに書いているのをHTMLファイルのhead部分に入れるだけでOKでした。

私の場合、「options are optional〜」と書いてある方のオプションは不要だったので、HTMLファイルは以下のコードでOKでした。

```html:index.html
<!DOCTYPE html>
<html>
  <head>
    …
    <script src="＜パスを適宜書く＞/mobile-drag-drop/release/index.min.js"></script>
    <script src="＜パスを適宜書く＞/mobile-drag-drop/release/scroll-behaviour.min.js"></script>
  </head>
  …
</html>
```

※微妙に注意ですが、mobile-drag-dropをGitHubから落としてきて何も考えずに解凍すると「mobile-drag-drop **-master** 」になってるかも。
※「〜.min.js」ではなく「〜.js」を使うと、コンソールにログが出るようになっていました。
※ちなみに、今回は使いませんでしたが、CDNもあったので参考までに[リンク（jsDelivr）](https://www.jsdelivr.com/package/npm/mobile-drag-drop)を載せておきます。

###②polyfil関数が読み込めない。

これが一番ハマったところですが、結論として、「[Drag & Drop API を使うときにやっておいたほうがいいこと](https://qiita.com/boushi-bird@github/items/ce720122fd0c15abe036)」の今回使ったところでは、以下2点の修正でエラーにならなくなりました。

- `polyfill`→`MobileDragDrop.polyfill`

- `scrollBehaviourDragImageTranslateOverride`→`MobileDragDrop.scrollBehaviourDragImageTranslateOverride`

バージョンアップ時に仕様が変わったのかも……？（そこまでは調べてない）

###~~③`window.addEventListener('touchmove', function {}, { passive: false });`でエラーになる。~~

~~これは
`function {}`→`function() {}`
の修正だけで治りました。~~

~~※これは「[Drag & Drop API を使うときにやっておいたほうがいいこと](https://qiita.com/boushi-bird@github/items/ce720122fd0c15abe036)」のコードでコメントにあった[https://github.com/timruffles/mobile-drag-drop/issues/77](https://github.com/timruffles/mobile-drag-drop/issues/77)を見に行ったら「()」が付いていました。~~

#動く最終的な形

HTML5のDrag & Drop API自体はPC画面では動いている場合（PC画面で動かすのは[ここ](https://blog.ver001.com/javascript-dragdrop-sort/)を参考にしました）、以下を足せばとりあえずスマホでも動くようになったよ！！というコード例です。

これ以上のことは、参考にさせていただいた「[Drag & Drop API を使うときにやっておいたほうがいいこと](https://qiita.com/boushi-bird@github/items/ce720122fd0c15abe036)」の方を見に行ってくださいｗ

以下、コード例。

```html:index.html
<!DOCTYPE html>
<html>
  <head>
    …
    <!-- Polyfill for HTML 5 drag'n'drop: mobile-drag-dropの読み込み -->
    <script src="＜パスを適宜書く＞/mobile-drag-drop/release/index.min.js"></script>
    <script src="＜パスを適宜書く＞/mobile-drag-drop/release/scroll-behaviour.min.js"></script>
    …
    <!-- このHTMLファイル用JavaScriptファイルの読み込み -->
    <script src="＜パスを適宜書く＞/main.js"></script>
    …
  </head>
  …
</html>
```

```javascript:main.js
// 修正箇所以外はそのまま引用させていただいています
// 最小限だと、以下をメインの.jsファイルに書き足すだけでOKです
// 初めにスマホの判定をしているので、書き足すなら冒頭とかが良いかも

// 以下、「Drag & Drop API を使うときにやっておいたほうがいいこと」の一部改変版

// iOS/Androidのときだけ、usePolyfill=trueになる
const usePolyfill = MobileDragDrop.polyfill({
  dragImageTranslateOverride: MobileDragDrop.scrollBehaviourDragImageTranslateOverride,
});

if (usePolyfill) {
  // https://github.com/timruffles/mobile-drag-drop#polyfill-requires-dragenter-listener
  // このpolyfill使用の場合 dragenter イベント時に Event.preventDefault() を呼ぶ必要がある
  document.addEventListener('dragenter', function(event) {
    event.preventDefault();
  });
  // https://github.com/timruffles/mobile-drag-drop/issues/77
  window.addEventListener('touchmove', function() {}, { passive: false });
}
```