🤖

画像をドラッグ&ドロップした際に、ダウンロードさせない方法

2024/10/14に公開

アップロードした画像が横一列に並んでいて、それをドラッグ&ドロップで並び替えるUIを実装する機会がありました。
ライブラリを使わずに実装したのですが、ハマった箇所があったのでメモ書きがてら書き残しておきます。

※業務で実装した際ははReactで実装していますが、解決策がhtml並びにcssの問題なので、
今回の記事ではReactを使わずに実装をしています。

完成形

こちら(playcode.io)でコード並びにUIが見れます。
※ハマった箇所が画像をアップロードするところではなく、
ドラッグ&ドロップの挙動を作る箇所でしたので、
画像がドラッグ&ドロップで移動できるだけのUIになっています。

以下のような感じで、ドラッグ&ドロップで順番を入れ替えられるようなUIができます。
よろしければいじってみてください。
※休日に肩の力を抜いて書いているので、筆者の趣味全開の画像選択になっていますがご容赦ください。

ハマったポイント

以前、画像以外の要素で同じようなUIを作ったことがあったので、
てっきり画像でも同じようにできると思って実装しました。

しかし、画面外でドロップした場合に、以下のようなことが起きました。

  • デスクトップなどでドロップすると画像がダウンロードされる
  • ブラウザの他のウィンドウなどでドロップすると、ブラウザに画像が表示される

解決策

以下の2つで解決できます。

  • imgタグにcssで、pointer-events: none;を付与
  • imgタグをdivタグで囲み、divタグにdraggable="true"を付与

1つずつ解説します。

imgタグにcssで、pointer-events: none;を付与する理由

一言で言うと、画像(img)そのものをドラッグ&ドロップさせないためです。

ブラウザでデフォルトでドラッグ可能なのは、テキストの選択範囲、画像、リンクのみです。
デフォルトでドラッグ可能な要素は全て、デスクトップでドロップするとダウンロードできたりとか、
ブラウザで別タブを表示させて表示するといった挙動がサポートされています。

imgタグをdivタグで囲み、divタグにdraggable="true"を付与する理由

画像(img)そのものをドラッグ&ドロップさせないようにしたので、
ドラッグができるようにするためにdivタグで囲みます。

デフォルトでドラッグ&ドロップが可能な、テキストの選択範囲、画像、リンクとは異なり、
デスクトップでドロップするとダウンロードできたりとか、
ブラウザで別タブを表示させて表示するといった挙動がdivタグにはサポートされていません。

したがって、ドラッグ&ドロップはできるが、
ダウンロードやタブが立ち上がるといった挙動はしないという状態が実現できます。

最後に

クイズの答えは以下です。

Discussion